Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# DateTime.AddYears在闰年上的行为_C#_.net_Datetime - Fatal编程技术网

C# DateTime.AddYears在闰年上的行为

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

当在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月份。在这两种情况下,您添加的是“较大单位”(月或年),而“较小单位”(日)将被截断以适应年/月组合

(顺便说一句,这也是我的行为方式。)

正如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