The next 2 lines adds the same amount to the same date, and the results date part is the same, but somehow the there’s difference in the time part!
(new DateTime(2000,1,3,18,0,0)).AddDays(4535);
(new DateTime(2000,1,3,18,0,0)).AddMonths(149);
you’ll get a difference of 15 secs, and with both are at least roundable to days, I don’t know why this happend, but it happens only with AddDays, but not AddMonths (even with thousands of months added)
Edit 1
So I’ve tried to make a sample project, but no luck. If I run my main project, and put the sample lines into the watches, than I get 2 separate values, if I make a fresh start, the problem is not there. The project is 3.5, c#, vs2010, win7hp x64 (proj: x86). I’m trying to reproduce it also in a fresh small project, I’ll be writing back if I have it.
These are my results in the main project (copeid from watches!):
(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
Edit 2
I’ve managed to narrow it down even more. We have a self-made component, panel base, we draw on it with directx. If I make that visible=false, than visible=true, than the error comes, before the visible=true (or show()), the calculation is correct. What in the world can be there, that the result gets something else of a formula where no variable is used. Culture is not affected in the component..
This is a result of DirectX silently changing the floating-point calculation mode of the CPU to always use single precision. This is sometimes done for performance: using single precision can be quite a bit faster than using double precision. See the description of the
FpuPreserveflag in the MSDN documentation for the DirectXCreateFlagsenumeration.The reason others aren’t able to reproduce this is because they are not doing those DirectX calls.
The argument to
AddDaysis adouble. This value is multiplied by a scale factor to get the time in milliseconds. It is this calculation that produces the error.Consider:
The expression for
milliseconds2contains a cast tofloat, which mimics the effect of DirectX forcing single-precision calculations. This will print15360, exactly the difference you find.By contrast,
AddMonthstakes an integer, and does not use any floating-point arithmetic. So the result is exact.