闰年上DateTime.AddYears的行为

在DateTime上使用AddYears方法时,有人可以解释.NET中闰年计算背后的数学或简单推理吗?

  • 如果您参加2012年2月29日并增加一年,您将获得2013年2月28日,而不是2013年3月1日(一年后的前一天)。
  • 如果您在2012年1月31日之前添加一年,则会在2013年1月31日(一年后的同一日期)到达。

我想大多数人会认为“一年从29.02.leapX是01.03.leapX + 1”。

例:

// Testing with 29th Feb var now1 = DateTime.Parse("2012-02-29 15:00:00"); var results1 = new DateTime[] { now1.AddYears(1), now1.AddYears(2), now1.AddYears(3), now1.AddYears(4) }; foreach(var dt in results1) { Console.WriteLine(dt.ToString("s")); } // Output: // 2013-02-28T15:00:00 // 2014-02-28T15:00:00 // 2015-02-28T15:00:00 // 2016-02-29T15:00:00 // Testing with 31st Jan var now2 = DateTime.Parse("2012-01-31 13:00:00"); var results2 = new DateTime[] { now2.AddYears(1), now2.AddYears(2), now2.AddYears(3), now2.AddYears(4) }; foreach(var dt in results2) { Console.WriteLine(dt.ToString("s")); } // Output: // 2013-01-31T13:00:00 // 2014-01-31T13:00:00 // 2015-01-31T13:00:00 // 2016-01-31T13:00:00 

我想大多数人会认为“一年从29.02.leapX是01.03.leapX + 1”。

我不会。 我通常会期望截断。 它基本上类似于1月30日增加一个月 – 我希望在2月份的最后一天。 在这两种情况下,您都会添加“更大的单位”(月份或年份),而“较小的单位”(日期)将被截断以适应年/月组合。

(这就是Joda Time和Noda Time的行为方式,顺便说一下。)

正如蒂姆在评论中提到的那样,它的记录方式也是如此:

AddYears方法在考虑闰年的情况下计算结果年份。 生成的DateTime对象的月份和时间部分与此实例保持一致。

所以这个必须留在二月; 这一年将根据添加的年数而变化,显然 – 因此必须调整以保持有效。

根据您的理由,2012年3月1日将在2012年3月2日增加一年。 如果您在之前的所有闰年中添加此class次,那么您将发现大量漂移的计算。 唯一明智的反应是在非闰年回归28-Feb。