I have a Windows FILETIME :
A 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC))
and I need it rounded UP to the nearest even second, as described here.
The code I have so far:
var originalDt = DateTime.FromFileTimeUtc(input);
// round it UP to the nearest Second
var newDt = originalDt.AddMilliseconds(1000 - originalDt.Millisecond);
// then if our new Second isn't even
if (newDt.Second % 2 != 0)
{
// add one second to it, then it'll be even
newDt = newDt.AddSeconds(1);
}
return newDt.ToFileTimeUtc();
doesn't quite work... it turns 130790247821478763 into 130790247820008763, I'm after 130790247800000000.
Maths isn't my strongest subject... can I just zero those last four digits safely? Or should I forget the above code and just zero the last eight digits completely? Or... another way?
Rather than struggling with the DateTime
object, you could perhaps more easily just do the raw mathematics:
If input
is the number of 100 nanoseconds, then:
/10
for the number of microseconds;
/10,000
for the number of milliseconds;
/10,000,000
for the number of seconds;
/20,000,000
for the number of 'two-seconds';
So:
input = input / 20000000 * 20000000;
The division will round the number DOWN to the last even second, then the multiply will get it back into the right size again.
But you said you wanted it rounded UP:
input = (input / 20000000 + 1) * 20000000;
That adds one 'two-second' to the small number before factoring it up again.
Pedantically, if input
was at exactly the two-second mark, then this would add two seconds to it. To fix that:
if (input % 20000000!=0) {
input = (input / 20000000 + 1) * 20000000;
} // if
That checks whether there's any fractional 'two-second' before deciding to bump it up. I'll leave it up to you as to whether you add this extra check...
@Matthew Watson points out that the usual programmers trick for the above problem is to pre-add not quite enough to roll input
over to the next 'two-second', then go ahead and do the divide-then-multiply. If input
was over the minimum, that'll roll it over:
const long twoSeconds = 20000000;
...
input = (input + twoSeconds - 1) / twoSeconds * twoSeconds;