tugberk
tugberk

Reputation: 58444

TimeSpan comparison with millisecond precision

I'm hitting something here which is very odd but I'm not sure whether it's me knowing the TimeSpan APIs wrong. The following prints out false and I'm not sure why:

var foo = TimeSpan.FromMilliseconds(123.34d);
var bar = TimeSpan.FromMilliseconds(123.33d);
Console.WriteLine(foo > bar);

The following prints true:

var foo = TimeSpan.FromMilliseconds(123.34d);
var bar = TimeSpan.FromMilliseconds(123.33d);
Console.WriteLine(foo == bar);

Doesn't TimeSpan.FromMilliseconds take millisecond precision into account while doing the comparison?

Upvotes: 4

Views: 2903

Answers (4)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726489

TimeSpan simply rounds the number of milliseconds that you pass it, so both 123.33 and 123.34 end up representing a timespan of 123 milliseconds. 123.5 would be rounded up to 123 milliseconds.

If you need better precision, do the math with the ticks yourself:

var foo = TimeSpan.FromTicks((long)(123.34*TimeSpan.TicksPerMillisecond));
var bar = TimeSpan.FromTicks((long)(123.33*TimeSpan.TicksPerMillisecond));
Console.WriteLine(foo > bar);

Now your program produces True (demo).

Upvotes: 5

HDL_CinC_Dragon
HDL_CinC_Dragon

Reputation: 193

Its an issue with precision:

var fooba = TimeSpan.FromMilliseconds(123.36d);
var foob = TimeSpan.FromMilliseconds(123.35d);
var foo = TimeSpan.FromMilliseconds(123.34d);
var bar = TimeSpan.FromMilliseconds(123.33d);
Console.WriteLine(fooba + " > " + foob + "?: " + (fooba > foob));
Console.WriteLine(foob + " > " + foo + "?: " + (foob > foo));
Console.WriteLine(foo + " > " + bar + "?: " + (foo > bar));
Console.WriteLine(fooba + " == " + foob + "?: " + (fooba == foob));
Console.WriteLine(foob + " == " + foo + "?: " + (foob == foo));
Console.WriteLine(foo + " == " + bar + "?: " + (foo == bar));

00:00:00.1230000 > 00:00:00.1230000?: False
00:00:00.1230000 > 00:00:00.1230000?: False
00:00:00.1230000 > 00:00:00.1230000?: False
00:00:00.1230000 == 00:00:00.1230000?: True
00:00:00.1230000 == 00:00:00.1230000?: True
00:00:00.1230000 == 00:00:00.1230000?: True

Upvotes: 0

marc wellman
marc wellman

Reputation: 5886

According to the API documentation http://msdn.microsoft.com/en-us/library/system.timespan.frommilliseconds(v=vs.110).aspx the method TimeSpan.FromMilliSeconds(double d) takes any double value but only respects values up to one digit after the comma since the double is converted into ticks before it is used within the TimeSpan struct.

The value parameter is converted to ticks, and that number of ticks is used to initialize the new TimeSpan. Therefore, value will only be considered accurate to the nearest millisecond. Note that, because of the loss of precision of the Double data type, this conversion can generate an OverflowException for values that are near to but still in the range of either MinValue or MaxValue.

This is also emphasized by the examples on that site:

GenTimeSpanFromMillisec( 1 );
GenTimeSpanFromMillisec( 1.5 );
GenTimeSpanFromMillisec( 12345.6 );
GenTimeSpanFromMillisec( 123456789.8 );
GenTimeSpanFromMillisec( 1234567898765.4 );
GenTimeSpanFromMillisec( 1000 );
GenTimeSpanFromMillisec( 60000 );
GenTimeSpanFromMillisec( 3600000 );
GenTimeSpanFromMillisec( 86400000 );
GenTimeSpanFromMillisec( 1801220200 );

Upvotes: 1

lboshuizen
lboshuizen

Reputation: 2786

Timespan accepts a floating point as a parameter for milliseconds but ignores the decimals.

Makes sense, as timespan has no notion of sub-milliseconds; it's the smallest unit.

Upvotes: 1

Related Questions