C#DateTime AddDays意外偏移量

C#DateTime AddDays意外偏移量,c#,datetime,C#,Datetime,我有一个非常简单的DateTime对象,它被设置为日期01-01-0001。我被提供了一个要添加到此日期时间的值,以天为单位。不过,我看到我的结果中出现了意想不到的抵消,即两天。让我们假设我打印了AddDays()调用的结果,如下所示: DateTime myDateTime = DateTime.Parse("01-01-0001 00:00:00"); Console.WriteLine(myDateTime.AddDays(735768.0)); 根据上述数值(735768.0),我预计

我有一个非常简单的DateTime对象,它被设置为日期01-01-0001。我被提供了一个要添加到此日期时间的值,以天为单位。不过,我看到我的结果中出现了意想不到的抵消,即两天。让我们假设我打印了AddDays()调用的结果,如下所示:

DateTime myDateTime = DateTime.Parse("01-01-0001 00:00:00");
Console.WriteLine(myDateTime.AddDays(735768.0));
根据上述数值(735768.0),我预计输出为“6/18/2015 12:00:00 AM”。然而,我得到的却是“6/20/2015 12:00:00 AM”。当我访问以下网站并计算01-01-0001-->06/18/2015之间的持续时间(以天为单位)时,我得到的值为735768天,如预期的那样:

我是做错了什么,还是有什么事情在我不知道的情况下发生了

如果您想知道,735768代表我正在处理的数据的第一时间值。数据预计将于2015年6月18日00:00:00开始


编辑:我应该注意,我只是提供了一个冲突源的例子,一个特定的网站。其他网站,包括我从政府气象局获取数据的网站,都给了我2015年6月18日的数据。这并不意味着C#是错的。我更好奇的是,这种抵消是从哪里来的,以及为什么。

来自网站“从开始日期到结束日期是735768天,但不包括结束日期”。这让我想到,你实际上需要增加735767天,因为网站计算开始日期。但这只能解释额外的一天。也许有一天网站错了?他们确实有一个警告。

如果是闰年,那就要多出两天,如果是这样的话,那就要休息503天。在我看来,有两种选择,一种是A。你在网上使用的计算器有点不准确,另一种是C#使用的数学在这个尺度上是不准确的。如果你自己计算,你会发现735768/365是一个完全无理的数字。因此,我的想法是,在引擎盖下进行的数学中的不精确性不能在那么多天内保持准确。这种情况经常发生在小数点上,我假设C#可能正在截断小数点(向下舍入),因此您可以休息两天。不管怎样,我猜。

.NET给了你一个“正确”的答案——注意“正确”是假设一个纯粹的公历,正如安德鲁·惠特克在下面的评论和上面的答案中指出的那样。安德鲁的回答更正确

闰年可以定义为可以被4整除,但不能被100整除,除非它可以被400整除。因此,自1/1/0001遵循这些规则以来,共有488个闰日

考虑到这些闰日,从1/1/0001到2014年底,共有735598天。这让我们找到了2015年第170天,即2015年6月20日(31+28+31+30+31+20)

此外,在.NET中,这并不像一些人所建议的那样是一个舍入问题。由于
DateTime.AddDays
将长的数据类型作为64位有符号整数使用,因此不会发生溢出或舍入

Ticks/day = 864BB (or 8.64 x 10^11)
Tick / (2,015 years) ~ 1.75 x 10^15
Max long = 9,223,372,036,854,775,807 (or 9.22 x 10^18)

Timeanddate.com正在考虑日历从朱利安改为格里高利,这解释了这种差异

如果您查看time和date.com上的差异,您实际上可以看到这种变化:

  • 儒略历法上闰年的计算公式是“每年可被4整除”。这意味着,当日历发生变化时,timeanddate.com在第一年和1752年之间的计算中有更多的闰年。这使得.NET的计算在1753年之前落后了11天
  • ,英国和美国东海岸使用。这一变化的结果是1752年只有355天。NET的计算没有考虑此计算,因此此时,.NET的计算提前了两天

根据,
DateTime
基本上只使用公历。这就是为什么.NET的计算中没有反映出上述微妙之处。

如果你运行下面的代码,你会发现每年2月只有28天 100,200 ...... 1900年

如果你通过链接,你会发现100200年2月有29天

最好不要将.net date day与Timeanddate.com进行比较

代码:


你考虑过闰年吗?为什么不存储日期时间呢?也许是闰年吧?试试这个,看看你得到了什么:
TimeSpan diff=newdatetime(2015,6,15)-myDateTime
并查看
diff.TotalDays
值。您希望该日期的值是什么?是因为其他网站这么说,还是因为你计算的?如果是网站错了,而不是
AddDays
功能怎么办?您是否通过多个来源进行了确认?@VicenteZambrano从DateTime MSDN文档中“AddDays方法在执行日期算术时考虑了闰年和一个月的天数。”@Steve我认为您确实复制了,您得到的日期与OP相同,OP表示该日期不正确。答案是“正确”如果您假定闰年计算仅使用公历规则进行。这可能被认为是不正确的,因为在所讨论的日期范围内使用了多个日历系统。鉴于.NET DateTimes在内部表示为自给定纪元起的100ns间隔数,这似乎相当不可信。(而且,年大约是365.2425天。)“我猜”,我没说发生了什么。很明显,你在这个网站上说的任何话都会让你的代表被带走。这是一个很好的激励人们提供意见的方法。一般来说,答案不适合猜测;对此,我们有意见。答案应该是相对权威的。从经验或仔细研究中得到的一点答案,或一些好问题,或大量有用的编辑,都会很快让你达到50岁。我很同情你,但到达那里所花的时间比你想象的要少。
static void Main(string[] args)
        {          
            for (int i = 001; i <= 2015; i++)
            {
                if (i % 4 == 0)
                {                    
                    if (DateTime.DaysInMonth(i, 2) != 29)
                    {
                        Console.WriteLine("Days {0} in a month feb Year {1}..", DateTime.DaysInMonth(i, 2), i);
                    }
                }
            }
            Console.ReadLine();
        }
Days 28 in a month feb Year 100..
Days 28 in a month feb Year 200..
Days 28 in a month feb Year 300..
Days 28 in a month feb Year 500..
Days 28 in a month feb Year 600..
Days 28 in a month feb Year 700..
Days 28 in a month feb Year 900..
Days 28 in a month feb Year 1000..
Days 28 in a month feb Year 1100..
Days 28 in a month feb Year 1300..
Days 28 in a month feb Year 1400..
Days 28 in a month feb Year 1500..
Days 28 in a month feb Year 1700..
Days 28 in a month feb Year 1800..
Days 28 in a month feb Year 1900..