使用NodaTime计算包含日期范围的天数

6

例如,如果我有以下代码:

var nodaStart = new LocalDate(2012, 5, 1);
var nodaEnd = new LocalDate(2012,5,2);
var daysBetween = Period.Between(nodaStart, nodaEnd,PeriodUnits.Day);

然后,daysBetween.Days == 1

然而,我计算的范围需要将其视为2天。也就是说,它需要包括开始和结束日期。

实际方法可以使用起始日期和结束日期(不超过一年),并需要计算天数。如果超过31天,则返回余数作为整周数量。

我的逻辑运行正常,但由于计数是排他性的,所以我少了一天。

我想我可以在创建nodaStart之前做startDate.addDays(-1),但我想知道是否有更优雅/更漂亮的方式让noda返回Period。

谢谢


更新: 我已经阅读了Period类的源代码+操作符被重载,因此我可以添加。

daysBetween += Period.FromDays(1);

2
如果您这样做,应该使用endDate.AddDays(1)。2012/05/02是2012/05/02 00:00——即第二天的早上。您想要的是第二天晚上,因此应在结束日期加一天,而不是从开始日期减去一天。 - Roger Lipscombe
2个回答

6

(抱歉回复晚了 - 我之前没看到这个。)

以下是可行方案:

  • 在计算之前在结尾处添加一天(我认为这是最逻辑的做法,因为你实际上想要下一天的开始)
  • 在计算之前从开始处减去一天
  • 将得出的结束日期增加1天

以上方案都可以。我不认为Noda Time会改变来使这更简单。 Between是一种“大概在单位周围”的减法操作符 - 你很少会发现有减法操作符使得2 - 1等于2。


3
+1 表示同意“你不会找到很多减法运算符使得 2 - 1 等于 2。” :) - Paul D'Ambra

0
对于“模糊”的人类大脑,如果一段时间标识了一个单独的日子、星期、月份等(与整个倍数相比),我们可以考虑将这段时间的开始和结束日期视为包含在内,因此您可以编写以下代码:
var start = new NodaTime.LocalDateTime(s.Year, s.Month, s.Day, s.Hour, s.Minute);
var end = new NodaTime.LocalDateTime(e.Year, e.Month, e.Day, e.Hour, e.Minute);

NodaTime.Period periodInclusive = NodaTime.Period.Between(start, end.PlusDays(1), NodaTime.PeriodUnits.AllDateUnits);
NodaTime.Period period =  NodaTime.Period.Between(start, end, NodaTime.PeriodUnits.AllDateUnits);
bool isInclusivePeriod = periodInclusive.Days + periodInclusive.Weeks + periodInclusive.Months + periodInclusive.Years < 
                         period.Days + period.Weeks + period.Months + period.Years;

period = isInclusivePeriod ? periodInclusive : period;
// do stuff with period here....

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接