java 一个月的第一天,使用给定的DateTime对象获取一个月的第一天和最后一天

这是对@Sergey和@Steffen的答案的长篇评论 . 在过去我自己编写了类似的代码后,我决定检查最重要的是什么,同时记住清晰度也很重要 .

结果

以下是1000万次迭代的示例测试运行结果:

2257 ms for FirstDayOfMonth_AddMethod()

2406 ms for FirstDayOfMonth_NewMethod()

6342 ms for LastDayOfMonth_AddMethod()

4037 ms for LastDayOfMonth_AddMethodWithDaysInMonth()

4160 ms for LastDayOfMonth_NewMethod()

4212 ms for LastDayOfMonth_NewMethodWithReuseOfExtMethod()

2491 ms for LastDayOfMonth_SpecialCase()

代码

我使用LINQPad 4(在C#程序模式下)在打开编译器优化的情况下运行测试 . 为了清晰和方便,以下是经过测试的代码作为扩展方法的因素:

public static class DateTimeDayOfMonthExtensions

{

public static DateTime FirstDayOfMonth_AddMethod(this DateTime value)

{

return value.Date.AddDays(1 - value.Day);

}

public static DateTime FirstDayOfMonth_NewMethod(this DateTime value)

{

return new DateTime(value.Year, value.Month, 1);

}

public static DateTime LastDayOfMonth_AddMethod(this DateTime value)

{

return value.FirstDayOfMonth_AddMethod().AddMonths(1).AddDays(-1);

}

public static DateTime LastDayOfMonth_AddMethodWithDaysInMonth(this DateTime value)

{

return value.Date.AddDays(DateTime.DaysInMonth(value.Year, value.Month) - value.Day);

}

public static DateTime LastDayOfMonth_SpecialCase(this DateTime value)

{

return value.AddDays(DateTime.DaysInMonth(value.Year, value.Month) - 1);

}

public static int DaysInMonth(this DateTime value)

{

return DateTime.DaysInMonth(value.Year, value.Month);

}

public static DateTime LastDayOfMonth_NewMethod(this DateTime value)

{

return new DateTime(value.Year, value.Month, DateTime.DaysInMonth(value.Year, value.Month));

}

public static DateTime LastDayOfMonth_NewMethodWithReuseOfExtMethod(this DateTime value)

{

return new DateTime(value.Year, value.Month, value.DaysInMonth());

}

}

void Main()

{

Random rnd = new Random();

DateTime[] sampleData = new DateTime[10000000];

for(int i = 0; i < sampleData.Length; i++) {

sampleData[i] = new DateTime(1970, 1, 1).AddDays(rnd.Next(0, 365 * 50));

}

GC.Collect();

System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();

for(int i = 0; i < sampleData.Length; i++) {

DateTime test = sampleData[i].FirstDayOfMonth_AddMethod();

}

string.Format("{0} ms for FirstDayOfMonth_AddMethod()", sw.ElapsedMilliseconds).Dump();

GC.Collect();

sw.Restart();

for(int i = 0; i < sampleData.Length; i++) {

DateTime test = sampleData[i].FirstDayOfMonth_NewMethod();

}

string.Format("{0} ms for FirstDayOfMonth_NewMethod()", sw.ElapsedMilliseconds).Dump();

GC.Collect();

sw.Restart();

for(int i = 0; i < sampleData.Length; i++) {

DateTime test = sampleData[i].LastDayOfMonth_AddMethod();

}

string.Format("{0} ms for LastDayOfMonth_AddMethod()", sw.ElapsedMilliseconds).Dump();

GC.Collect();

sw.Restart();

for(int i = 0; i < sampleData.Length; i++) {

DateTime test = sampleData[i].LastDayOfMonth_AddMethodWithDaysInMonth();

}

string.Format("{0} ms for LastDayOfMonth_AddMethodWithDaysInMonth()", sw.ElapsedMilliseconds).Dump();

GC.Collect();

sw.Restart();

for(int i = 0; i < sampleData.Length; i++) {

DateTime test = sampleData[i].LastDayOfMonth_NewMethod();

}

string.Format("{0} ms for LastDayOfMonth_NewMethod()", sw.ElapsedMilliseconds).Dump();

GC.Collect();

sw.Restart();

for(int i = 0; i < sampleData.Length; i++) {

DateTime test = sampleData[i].LastDayOfMonth_NewMethodWithReuseOfExtMethod();

}

string.Format("{0} ms for LastDayOfMonth_NewMethodWithReuseOfExtMethod()", sw.ElapsedMilliseconds).Dump();

for(int i = 0; i < sampleData.Length; i++) {

sampleData[i] = sampleData[i].FirstDayOfMonth_AddMethod();

}

GC.Collect();

sw.Restart();

for(int i = 0; i < sampleData.Length; i++) {

DateTime test = sampleData[i].LastDayOfMonth_SpecialCase();

}

string.Format("{0} ms for LastDayOfMonth_SpecialCase()", sw.ElapsedMilliseconds).Dump();

}

分析

我对其中一些结果感到惊讶 .

虽然其中没有多少 FirstDayOfMonth_AddMethod 在大多数测试中都略快于 FirstDayOfMonth_NewMethod . 但是,我认为后者有一个更清晰的意图,所以我更喜欢这个 .

LastDayOfMonth_AddMethod 对 LastDayOfMonth_AddMethodWithDaysInMonth , LastDayOfMonth_NewMethod 和 LastDayOfMonth_NewMethodWithReuseOfExtMethod 明显失败 . 在最快的三个之间没有任何内容,因此它取决于您的个人偏好 . 我选择了 LastDayOfMonth_NewMethodWithReuseOfExtMethod 的清晰度,并重用了另一种有用的扩展方法 . 恕我直言,其意图更清晰,我愿意接受小的性能成本 .

LastDayOfMonth_SpecialCase 假设您在特殊情况下提供了本月的第一个月,您可能已经计算了该日期,并使用带有 DateTime.DaysInMonth 的add方法来获取结果 . 这比其他版本更快,正如您所期望的那样,但除非您迫切需要速度,否则我不认为在您的武器库中有这种特殊情况 .

结论

这是一个扩展方法类,我的选择和@Steffen的一般协议我相信:

public static class DateTimeDayOfMonthExtensions

{

public static DateTime FirstDayOfMonth(this DateTime value)

{

return new DateTime(value.Year, value.Month, 1);

}

public static int DaysInMonth(this DateTime value)

{

return DateTime.DaysInMonth(value.Year, value.Month);

}

public static DateTime LastDayOfMonth(this DateTime value)

{

return new DateTime(value.Year, value.Month, value.DaysInMonth());

}

}

如果你有这个目的,谢谢你的时间!很有趣:¬) . 如果您对这些算法有任何其他建议,请发表评论 .

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值