.NET 2.0: Fraction support broken for DateTime?

S

sumip

I just made a pretty strange observation with .NET 2.0 -
DateTime.AddMilliseconds(double) and AddSeconds(double) seem to be
broken:

DateTime now = new DateTime();
DateTime t2 = now.AddMilliseconds(1.5);
Console.Out.WriteLine(t2.TimeOfDay);

The code above rounds the fraction to full milliseconds and results in
this output:
00:00:00.0020000


However, if I use AddTicks, the result is as expected:

DateTime now = new DateTime();
DateTime t2 = now.AddTicks(15000);
Console.Out.WriteLine(t2.TimeOfDay);

Output: 00:00:00.0015000


IMHO, AddMillisecond should work completely different. From the
documentation of AddMilliseconds:

<quote>
The fractional part of value is the fractional part of a millisecond.
For example, 4.5 is equivalent to 4 milliseconds, and 5000 ticks, where
one millisecond = 10000 ticks.
</quote>

However, I just can't imagine that there is such a severe bug in the
framework. Any ideas?

Cheers,
Philipp
 
L

Larry Lard

I just made a pretty strange observation with .NET 2.0 -
DateTime.AddMilliseconds(double) and AddSeconds(double) seem to be
broken:

DateTime now = new DateTime();
DateTime t2 = now.AddMilliseconds(1.5);
Console.Out.WriteLine(t2.TimeOfDay);

The code above rounds the fraction to full milliseconds and results in
this output:
00:00:00.0020000


However, if I use AddTicks, the result is as expected:

DateTime now = new DateTime();
DateTime t2 = now.AddTicks(15000);
Console.Out.WriteLine(t2.TimeOfDay);

Output: 00:00:00.0015000


IMHO, AddMillisecond should work completely different. From the
documentation of AddMilliseconds:

<quote>
The fractional part of value is the fractional part of a millisecond.
For example, 4.5 is equivalent to 4 milliseconds, and 5000 ticks, where
one millisecond = 10000 ticks.
</quote>

However, I just can't imagine that there is such a severe bug in the
framework. Any ideas?
From looking at Reflector I would be inclined to agree this is a bug.
AddMilliseconds, AddSeconds, AddMinutes and AddHours all privately call
Add, which takes a number and a 'scale' parameter. For AddMilliseconds,
scale is 1:

public DateTime AddMilliseconds(double value)
{
return this.Add(value, 1);
}


This is what Add looks like:

private DateTime Add(double value, int scale)
{
long num1 = (long) ((value * scale) + ((value >= 0) ? 0.5 :
-0.5));
// bounds checking snipped

return this.AddTicks(num1 * 0x2710);
}
From which it seems clear that the fractional part of the argument to
AddMilliseconds is simply thrown away.
 
S

sumip

Larry,

Thanks for the fast reply! I just checked it with .NET 1.1 and the
behaviour is the same. I'm really surprised that this hasn't been
reported and fixed for 2.0 yet. I guess this indicates that .NET still
plays a minor role when it comes to real-time applications...

Cheers,
Philipp
 
J

Jon Skeet [C# MVP]

Thanks for the fast reply! I just checked it with .NET 1.1 and the
behaviour is the same. I'm really surprised that this hasn't been
reported and fixed for 2.0 yet. I guess this indicates that .NET still
plays a minor role when it comes to real-time applications...

That's certainly true, as .NET isn't an appropriate platform for
real-time applications for various reasons. (Heck, most if not all
versions of Windows aren't appropriate for running real-time
applications.) Of course, it's possible that we're thinking of
different definitions of "real-time applications".

Jon
 
S

sumip

It's indeed not "real real-time" what I'm talking about. While we do
some stuff in "real time", we don't work with intervals below 100ms -
which is horribly slow for the hardware guys ;-)

However, we're controlling external hardware that provides realtime
functionality via a .NET application, and just retrieve the data for
analysis. This makes a nice couple.

Cheers,
Philipp
 
Top