timeunit - timespan c#




TimeSpan FromMilliseconds strange implementation? (4)

Accepting a double is a logical design. You can have fractions of milliseconds.

What's happening internally is an implementation design. Even if all current implementations (of the CLI) round it first that doesn't have to be the case in the future.

I recently encountered some wird behaviour in the .net timespan implementation.

        TimeSpan test = TimeSpan.FromMilliseconds(0.5);
        double ms = test.TotalMilliseconds; // Returns 0

The FromMilliseconds takes a double as parameter. However, it seems the value is rounded internally.

If I instantiate a new timespan with 5000 ticks (.5 ms), the value of TotalMilliseconds is correct.

Looking at the TimeSpan implementation in reflector reveals that the input is in fact casted to a long.

Why did Microsoft design the FromMilliseconds method to take a double a parameter instead of a long (since a double value is useless given this implementation)?


Or, you could do:

double x = 0.4;

TimeSpan t = TimeSpan.FromTicks((long)(TimeSpan.TicksPerMillisecond * x)); // where x can be a double
double ms = t.TotalMilliseconds; //return 0.4

--sarcasm

TimeSpan converts the double of milliseconds to ticks so "OBVIOUSLY" you can have a TimeSpan with less than a 1ms granularity.

-/sarcasm

-- this isn't obvious at all... why this isn't done inside the .FromMilliseconds method is beyond me.


The problem with your code is actually the first line, where you call FromMilliseconds. As noted previously, the remarks in the documentation state the following:

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.

In reality, this statement is neither correct nor logically sound. In reverse order:

  • Ticks are defined as "one hundred nanoseconds". By this definition, the documentation should have been written as:

    Therefore, value will only be considered accurate to the nearest millisecond tick, or one ten-millionth of a second.

  • Due to a bug or oversight, the value parameter is not converted directly to ticks prior to initializing the new TimeSpan instance. This can be seen in the reference source for TimeSpan, where the millis value is rounded prior to its conversion to ticks, rather than after. If maximum precision were to be preserved, this line of code should have read as follows (and the adjustment by 0.5 milliseconds 3 lines earlier would be removed):

    return new TimeSpan((long)(millis * TicksPerMillisecond));
    

Summary:

The documentation for the various TimeSpan.From*, with the exception of FromTicks, should be updated to state that the argument is rounded to the nearest millisecond (without including the reference to ticks).


This is by design, obviously. The documentation says as much:

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.





timespan