C# DateTime.AddYears在闰年上的行为
当在DateTime上使用AddYears方法时,有人能解释.NET中闰年计算背后的数学或简单推理吗C# DateTime.AddYears在闰年上的行为,c#,.net,datetime,C#,.net,Datetime,当在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("2
- 如果你把2012年2月29日加上一年,你会得到2013年2月28日,而不是2013年3月1日(一年后的前一天)
- 如果将2012年1月31日加上一年,则为2013年1月31日(一年后的同一日期)
// 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月份。在这两种情况下,您添加的是“较大单位”(月或年),而“较小单位”(日)将被截断以适应年/月组合
(顺便说一句,这也是我的行为方式。)
正如Tim在评论中提到的,也是这样:
AddYears方法将闰年考虑在内,计算得出的年份。结果DateTime对象的月份和时间部分与此实例保持相同
所以这个月必须保持在二月;很明显,年份将根据增加的年份而变化,因此必须调整日期以保持有效。根据您的理由,2012年3月1日将成为2012年3月2日,因为您增加了一年。如果你把之前所有闰年的变化都加在一起,你会发现你的计算在很大程度上是飘忽不定的。唯一明智的回应是在非闰年返回2月28日。有趣的是,尽管如此 e、 g.此功能有时用于:
private static int Age(DateTime birthDate, DateTime asAtDate)
{
// Calculate age in years
int age = asAtDate.Year - birthDate.Year;
if (asAtDate < birthDate.AddYears(age)) age--;
if (age < 0) age = 0;
return age;
}
非常清楚:“AddYears方法计算结果年份时考虑了闰年。结果DateTime对象的月份和时间部分与此实例保持相同。”谢谢。这对我来说很有意义,但我意识到我一直认为日期和日历是重叠的数组,其中29.02的“索引”将与下一个非闰年的01.03的索引相同。一个非常简单(也是错误的)的想法。一年总是12个月,但12个月可以是365天或366天,每个月可以是28到31天不等的天数。一天始终是24小时,因此添加天、小时等的方法将是精确的,没有任何变化,因为一天的长度不会随每个自定义的天数而变化。正如预期的那样,如果您将365天添加到2000年1月1日,您将得到2000年12月31日,因为该年有366天。AddYears和AddMonths是不同的,因为一年的含义或长度随年份而变化,就像一个月的长度随月份而变化一样。这意味着,对于3月15日这样的日期,在该值上加上“一个月”在技术上是不明确的,因为它涉及到3月和4月的天数。因为它是模糊的,为了避免“漂移”,必须保持日不变,增加月数,每12个月增加一年。这样做可能会导致“出界”的数字,因此必须更改日期。只有在最后一步中才能改变日期。有趣的是,在“1月31日”调用AddMonths(2)得到的值与在中间值“2月28日”->“3月28日”连续两次调用AddMonth(1)得到的值“3月31日”不同换句话说,对于29到31之间的天数,AddMonths方法(或运算符,如果您愿意)缺少addition的关联属性,因为您可以根据对additions的分组方式获得不同的日期。i、 e.DateTime(“1月31日”)。AddMonth(1)。AddMonths(1)给出的结果与DateTime(“1月31日”)。AddMonths(2)不同,闰年的结果也不同。因此,它没有完全意义,但它有效地将每次通话的日期漂移降至最低,而其他可能的方法则更没有意义(例如,使用计算所涉及的所有月份的平均天数)。@Triynko:我甚至不会说它“没有完全意义”-只是日历没有提供与自然数相同的计算基础。
=DATEDIF(DATE(2016,2,28),DATE(2017,2,28),"Y")
gives result of 1
=DATEDIF(DATE(2016,2,29),DATE(2017,2,28),"Y")
gives result of 0
=DATEDIF(DATE(2016,2,29),DATE(2017,3,1),"Y")
gives result of 1
=DATEDIF(DATE(2016,3,1),DATE(2017,3,1),"Y")
gives result of 1