【问题标题】:Count the number of inclusive dates covered by a date period计算日期期间包含的包含日期的数量
【发布时间】:2012-12-20 10:57:49
【问题描述】:

我正在计算两个DateTimes 之间覆盖(包括)日期的数量。

这不是.TotalDays,因为少于 24 小时的时段仍可能通过重叠两个不同的日期返回“2”。同样,相隔几分钟的两个日期仍应返回“1”。

例如:

2012-2-1 14:00 to 2012-2-2 23:00 -> 2 (1st and 2nd Feb)
2012-2-1 14:00 to 2012-2-2 10:00 -> 2 (1st and 2nd Feb)
2012-2-1 23:00 to 2012-2-2 00:00 -> 2 (1st and 2nd Feb)
2012-2-1 23:00 to 2012-2-3 00:00 -> 3 (1st, 2nd, 3rd Feb)
2012-2-1 14:00 to 2012-2-1 15:00 -> 1 (1st Feb)
2012-2-1 14:00 to 2012-2-1 14:00 -> 1 (1st Feb)
2012-1-1 00:00 to 2012-12-31 23:59 -> 366 (All of 2012)

我可以通过下面的代码获得这个功能:

DateTime dt1 = new DateTime(2000,1,2,12,00,00);
DateTime dt2 = new DateTime(2000,1,3,03,00,00);

int count = 0;
for (DateTime date = dt1; date.Date <= dt2.Date; date = date.AddDays(1))
    count++;

return count;

有没有更好的办法?

【问题讨论】:

  • d1.Date.Subtract(d2.Date).TotalDays + 1 怎么样
  • 不确定它是如何复制的。同一天的两个日期仍应返回 1. 跨越两天的少于 24 小时的时间段应返回两天。
  • NodaTime 非常适合这种事情,参考:[如何使用 NodaTime 计算包含天数][1] [1]:stackoverflow.com/questions/10336863/…
  • 这不是重复,因为它与指定的重复有不同的答案......

标签: c# date datetime


【解决方案1】:

也许只是

TimeSpan duration = dt2.Date - dt1.Date;
int days = duration.Days + 1;

Demo

【讨论】:

  • 是的,它做到了,+1。不幸的是,戴维奥击败了你,因为你被接受了。
  • @MattMitchell:但我还是会使用TimeSpan.Days 而不是TotalDays,因为您不想计算天数的小数部分(double),而只计算天数部分(int) .
  • @MattMitchell:我看到 Davio 也改变了它,所以无论如何我的论点毫无意义;)
  • 是的。如果这是一个突破点,我会改变接受的答案,但它在功能上并不重要。感谢您的帮助。
【解决方案2】:

为什么不只是:

int count = dt1.Date.Subtract(dt2.Date).Duration().Days + 1;

使用 .Date 将日期标准化为午夜 (0:00),将 1 加到 Days 以获取不同日期的数量,而不仅仅是中间的天数。

使用Duration 可确保您始终得到肯定的答复。

【讨论】:

  • 就可以了。可以的时候会接受。我没有注意到它在所有测试中总是以 1 为单位,这是个好地方。
  • 您可以使用减号而不是.Subtract 来简化一点(根据@Tim Schmelter 的回答)
  • @MattMitchell 是的,这是一个偏好问题,当我像这样链接时,我喜欢使用 Subtract。
  • 顺便说一句,你的Duration() 应该是一个方法调用而不是一个属性。它实际上处理了我的原始样本没有处理的错误日期。
【解决方案3】:
DateTime d1=DateTime.MinValue;
DateTime d2=DateTime.MaxValue;
TimeSpan span=d2-d1;
int counter = span.Days + 1;

【讨论】:

  • 表示你也想计算月份
【解决方案4】:

Math.Ceiling((d2 - d1.Date).TotalDays)

尝试了您提到的所有案例。结果是预期的!希望对您有所帮助。

【讨论】:

  • 尽力而为,但它无法处理 2000/1/1 23:00 到 2000/1/2 00:00 (它返回 1 并且应该是 2,因为那里有 2 个日期)。请参阅@Davio 接受的答案以获得有效的解决方案。
  • @MattMitchell 这表明数学上“取Ceiling”与“取Floor 并添加1”不同。后者会给出正确的行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多