在 nodatime 上添加两个句点

Adding two periods on nodatime

其中 listObjAge 是一个包含多个句点的列表;

Period objTotalPeriod = listObjAge[0].period;
for (int i = 1; i < listObjAge.Count; i++) {
   objTotalPeriod += listObjAge[i].period;
}

简而言之:
我得到了什么:

listObjAge[0].period + listObjAge[1].period = ????.
2 yr 1 mnth 28 days  + 0 yr 8 mnth 30 days  = 2 yr 9 mnth 58 days 
// this result is not wrong but is there any way to correctly add days for the above code.

我期待什么:

2 yr 1 mnth 28 days  + 0 yr 8 mnth 30 days  = 2 yr 10 mnth 28 days 

如您所见,我想添加两个时期的结果。有什么方法可以使用 nodatime 来实现吗?

已解决:
我知道它在理论上是不正确的。但这对我有用。

int intDays = 0;
for (int i = 0; i < listObjAge.Count; i++) {
     intDays += listObjAge[i].period.Days; // adding all the days for every period
}

strYear = (intDays / 365).ToString();
strMonth = ((intDays % 365) / 30).ToString();
strDays = ((intDays % 365) % 30).ToString();

您应该查看描述算术的 Noda Time 用户指南 http://nodatime.org/2.0.x/userguide/arithmetic - 在 "Adding a Period" 部分下查看更多信息。


最容易想到这可能与示例混淆的地方。假设我们将 "one month minus three days" 添加到 2011 年 1 月 30 日:

Period period = Period.FromMonths(1) - Period.FromDays(3);
LocalDate date = new LocalDate(2011, 1, 30);
date = date + period;

如果您将这个谜题交给真人,他们可能会等到最后一刻检查有效性,然后得出 "February 27th" 的答案。 Noda Time 会在2月25日给出答案,因为上面的代码有效计算为:

Period period = Period.FromMonths(1) - Period.FromDays(3);
LocalDate date = new LocalDate(2011, 1, 30);
date = date + Period.FromMonths(1); // February 28th (truncated)
date = date - Period.FromDays(3); // February 25th

The benefit of this approach is simplicity and predictability: when you know the rules, it's very easy to work out what Noda Time will do. The downside is that if you don't know the rules, it looks like it's broken.


用你的代码

根据文档,您得到的结果是基于 "rules" 的 预期行为 。简单地说,您对两个两个周期的加法运算将计算为:

Years (2 + 0) = 2
Months(1 + 8) = 9
Days (28 + 30) = 58

Your comment:
this result is not wrong but is there any way to correctly add days for the above code.

"correct"是什么意思?你是说 28 + 30 = 58 不正确吗?


备选方案

int days = 28 + 30; // carry over your days and +1 month or whatever logic you had in mind
int months = 1 + 8;
Period p1 = new PeriodBuilder { Days = days, Months = months }.Build();

使用这个

public static Period add(Period b, Period c)
{

   int years = b.year + c.year;
   int months = b.month + c.month;
   int days= b.days + c.days;
   return new PeriodBuilder { Days = days, Months = months , Years  = years}.Build();
}

听起来您正在寻找使月份和日期(和星期?)正常化的方法。现有的 Normalize 方法处理从 "days downwards" 开始的所有内容(例如小时),因此您可以使用它开始:

public static Period NormalizeIncludingMonths(this Period period, int daysPerMonth)
{
    period = period.Normalize();
    int extraMonths = days / daysPerMonth;
    int months = period.Months + extraMonths;
    int extraYears = months / 12;
    // Simplest way of changing just a few parts...
    var builder = period.ToBuilder();
    builder.Years += extraYears;
    builder.Months = months % 12;
    builder.Days = days % daysPerMonth;
    return builder.Build();
}

所以在你的情况下,听起来你可能想要:

objTotalPeriod = objTotalPeriod.NormalizeIncludingMonths(31);

请注意,使用它的算术可能会产生 "odd" 个结果,就像日历算术的本质一样。