.NET AddDays问题

时间:2012-03-14 12:55:09

标签: c# .net datetime

接下来的两行在相同的日期添加相同的金额,结果日期部分是相同的,但不知何故,时间部分有差异!

(new DateTime(2000,1,3,18,0,0)).AddDays(4535);   
(new DateTime(2000,1,3,18,0,0)).AddMonths(149);

你会得到15秒的差异,并且两者至少可以倒圆几天,我不知道为什么会发生这种情况,但它只发生在AddDays,而不是AddMonths(即使添加了数千个月)


修改1

所以我试图制作一个示例项目,但没有运气。如果我运行我的主项目,并将样品线放入手表,而不是我得到2个单独的值,如果我重新开始,问题就不存在了。该项目是3.5,c#,vs2010,win7hp x64(proj:x86)。我正在尝试在一个新的小项目中重现它,如果我有它,我会写回来。

这些是我在主要项目中的结果(来自手表的copeid!):

(new DateTime(2000, 1, 3, 18, 0, 0)).AddDays(4535).Ticks    
 634743432153600000 long

(new DateTime(2000, 1, 3, 18, 0, 0)).AddMonths(149).Ticks   
 634743432000000000 long

修改2

我已经设法将其缩小范围了。我们有一个自制组件,面板底座,我们使用directx绘制它。如果我在visible = true(或show())之前使那个visible = false,而不是visible = true,那么计算是正确的。世界上可以有什么,结果得到了一个没有使用变量的公式。文化不受组成部分的影响..

2 个答案:

答案 0 :(得分:4)

这里他们给出了相同的结果:

var d1 = (new DateTime(2000, 1, 3, 18, 0, 0)).AddDays(4535).Ticks;
var d2 = (new DateTime(2000, 1, 3, 18, 0, 0)).AddMonths(149).Ticks;

d1 == d2 == 634743432000000000

(Tick是DateTime时间的内部“量子”。它很短。它是one ten-millionth of a second

我要补充一点,即使是Mono(.NET的独立实现)也会得到相同的结果http://ideone.com/krySY(Ideone使用单声道)

考虑到你写的最近的事情,这很容易:内存损坏。内存损坏可以做很随机的事情。这可能是其中之一: - )

答案 1 :(得分:3)

这是DirectX静默更改CPU的浮点计算模式以始终使用单精度的结果。这有时是为了提高性能:使用单精度可以比使用双精度快一点。有关DirectX CreateFlags枚举的信息,请参阅MSDN文档中FpuPreserve标志的说明。

其他人无法重现这一点的原因是因为他们没有进行那些DirectX调用。

AddDays的参数是double。此值乘以比例因子以获得以毫秒为单位的时间。正是这种计算产生了错误。

考虑:

double value = 4535;
int scale = 86400000;
long milliseconds = (long) ((value * scale) + ((value >= 0.0) ? 0.5 : -0.5));
long milliseconds2 = (long)((float)(value * scale) + ((value >= 0.0) ? 0.5 : -0.5));
Console.WriteLine(milliseconds2 - milliseconds);

milliseconds2的表达式包含对float的强制转换,它模仿DirectX强制进行单精度计算的效果。这将打印15360,确切地说是您找到的差异。

相比之下,AddMonths采用整数,并且不使用任何浮点运算。所以结果是准确的。