TimeSpan.FromMilliseconds rounding!

Today’s fairly brutal gotcha: TimeSpan.FromMilliseconds accepts a double but internally rounds the value to a long before converting to ticks (multiplying by 10000).

For example, using C# interactive in VS2017:

> TimeSpan.FromMilliseconds(1.5)
[00:00:00.0020000]

> TimeSpan.FromMilliseconds(1234.5678)
[00:00:01.2350000]

Using .FromTicks works as expected:


> TimeSpan.FromTicks(15000)
[00:00:00.0015000]

To be fair this is the documented behavior:

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.

But really, it isn’t expected since the input is a double!

This all came to light because a camera system I’m involved with started overexposing –  the integration time was programmed as 2ms instead of the desired 1.5ms. Hmmph!

So a little alternative:

> TimeSpan TimeSpanFromMillisecondsEx(double ms) =>
    TimeSpan.FromTicks((long)(ms * 10000.0))

> TimeSpanFromMillisecondsEx(1.5)
[00:00:00.0015000]

 

Note: the FromMilliseconds method delegates to an internal Interval method, passing the milliseconds value and 1 as the scale:


private static TimeSpan Interval(double value, int scale)
{
    if (double.IsNaN(value))
    {
        throw new ArgumentException(Environment.GetResourceString("Arg_CannotBeNaN"));
    }
    double num = value * scale;
    double num2 = num + ((value >= 0.0) ? 0.5 : -0.5);
    if ((num2 > 922337203685477) || (num2 = 0.0) ? 0.5 : -0.5);
    if ((num2 > 922337203685477) || (num2 < -922337203685477))
    {
        throw new OverflowException(Environment.GetResourceString("Overflow_TimeSpanTooLong"));
    }
    return new TimeSpan(((long) num2) * 0x2710L);
}

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s