【发布时间】:2010-07-20 01:57:27
【问题描述】:
示例:给定以下两个日期,finish 总是大于或等于 start
开始 = 2001 年 1 月 1 日
完成 = 2002 年 3 月 15 日
所以从 2001 年 1 月 1 日到 2002 年 2 月结束
月 = 12 + 2 = 14
2002 年 3 月
15/30 = 0.5
所以总计相差 14.5 个月。
手工计算很容易,但我如何优雅地编码呢?目前我有很多 if else 和 while 循环的组合来实现我想要的,但我相信那里有更简单的解决方案。
更新:输出需要精确(不是近似值),例如: 如果从 2001 年 1 月 1 日开始,到 2001 年 4 月 16 日结束,则输出应为 1 + 1 + 1= 3(一月、二月和三月)和 16 / 31 = 0.516 个月,因此总数为 3.516。
另一个例子是,如果我从 2001 年 7 月 5 日开始并在 2002 年 7 月 10 日结束,那么输出应该是到 2002 年 6 月结束的 11 个月,并且 (31-5)/31 = 0.839 和 10/31 = 0.323 个月,所以总数是 11 + 0.839 + 0.323 = 12.162。
我扩展了 Josh Stodola 的代码和 Hightechrider 的代码:
public static decimal GetMonthsInRange(this IDateRange thisDateRange)
{
var start = thisDateRange.Start;
var finish = thisDateRange.Finish;
var monthsApart = Math.Abs(12*(start.Year - finish.Year) + start.Month - finish.Month) - 1;
decimal daysInStartMonth = DateTime.DaysInMonth(start.Year, start.Month);
decimal daysInFinishMonth = DateTime.DaysInMonth(finish.Year, finish.Month);
var daysApartInStartMonth = (daysInStartMonth - start.Day + 1)/daysInStartMonth;
var daysApartInFinishMonth = finish.Day/daysInFinishMonth;
return monthsApart + daysApartInStartMonth + daysApartInFinishMonth;
}
【问题讨论】:
-
感谢那些提供近似解决方案的人,但我需要一种优雅的方法来按日历月/年/日计算月差。这就是为什么我当前的解决方案包含 if else for each 和 while 循环。
-
您的计算似乎假设结束时间包括当天的全部时间 - 这是您真正想要的吗? 3 月 15 日,
DateTime值的时间为午夜,这意味着在可能的 31 天中,3 月仅过去了 14 天。 -
@Hightechrider,开始日总是 00:00:00:1 毫秒,结束日总是 23:59:59:999。因此,如果开始和结束在同一天,则计为 1 天。