Why is DateTime.AddDays rounded to the nearest millisecond?

I separate the two doubles in .NET and use the result object to generate the end date from the start date by calling (dtStart is predefined):

var dValue = 1500.0/8400.0; var dtEnd = dtStart.AddDays(dValue); 

After checking dtEnd, I found that the result was accurate only to the nearest millisecond. Looking at it, I found that .AddMilliseconds, etc. Around the numbers and TimeSpan.FromDays does a similar thing. I was wondering if there was a reason why this rounding was done, as it seems that the only way to get the correct value here is to use .AddTicks?

For reference. Call Destinations (where MillisPerDay = 86400000)

 public DateTime AddDays(double value) { return Add(value, MillisPerDay); } 

which causes

 private DateTime Add(double value, int scale) { long millis = (long)(value * scale + (value >= 0? 0.5: -0.5)); if (millis <= -MaxMillis || millis >= MaxMillis) throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_AddValue")); return AddTicks(millis * TicksPerMillisecond); } 
+6
source share
1 answer

Edit: After thinking about this, I understand that the first version of my answer was incorrect.

Here are the comments in the Microsoft source code:

 // Returns the DateTime resulting from adding a fractional number of // xxxxs to this DateTime. The result is computed by rounding the // fractional number of xxxxs given by value to the nearest // millisecond, and adding that interval to this DateTime. The // value argument is permitted to be negative. 

These comments appear in five different AddXxxx (double value) methods, where Xxxx = Days, Hours, Milliseconds, Minutes, and Seconds.

Note that this is only for methods that take a floating point value. (And one may wonder whether it is worth using floating point values ​​in calculations by date, but this is a topic for another day.)

Now that the OP correctly points out, these five methods all call this method:

 // Returns the DateTime resulting from adding a fractional number of // time units to this DateTime. private DateTime Add(double value, int scale) { long millis = (long)(value * scale + (value >= 0? 0.5: -0.5)); if (millis <= -MaxMillis || millis >= MaxMillis) throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_AddValue")); return AddTicks(millis * TicksPerMillisecond); } 

So what is being done is that the value added to the DateTime is rounded to the nearest millisecond number before adding. But not the result - just adding (or subtracting) the value.

This is actually documented, for example http://msdn.microsoft.com/en-us/library/system.datetime.adddays%28v=vs.110%29.aspx "The value parameter is rounded to the nearest millisecond."

Why I do not know. Perhaps the programmers thought that if you use floating point values, you should know that your values ​​are usually not entirely accurate. Or maybe they want to some extent model millisecond Java-style times.

+2
source

Source: https://habr.com/ru/post/978421/


All Articles