I'm playing around with Python's datetime.datetime.utcnow() method and I'm noticing that the microsecond value is always the same.
>>> import datetime
>>> datetime.datetime.utcnow()
datetime.datetime(2015, 11, 16, 23, 20, 46, 42286)
>>> datetime.datetime.utcnow()
datetime.datetime(2015, 11, 16, 23, 20, 55, 505286)
>>> datetime.datetime.utcnow()
datetime.datetime(2015, 11, 16, 23, 21, 1, 552286)
Notice how the microsecond value is always 286. Why would that be? And what can I do to fix that?
A little more info: time.time()
also always has 286us. The millisecond values are fine. I think that this is actually the root cause, since I believe that datetime.datetime.utcnow() calls time.time().
Here's a short script that shows that it's not just luck:
import datetime, random, time
for wait_time in [random.random() for _ in range(10)]:
time.sleep(wait_time)
print("Waited {}, result {}".format(wait_time, datetime.datetime.utcnow()))
Result:
Waited 0.6074311218736113, result 2015-11-16 23:35:24.603286
Waited 0.960317012489652, result 2015-11-16 23:35:25.563286
Waited 0.13555474339177553, result 2015-11-16 23:35:25.698286
Waited 0.6179213307667111, result 2015-11-16 23:35:26.315286
Waited 0.2872301475401443, result 2015-11-16 23:35:26.602286
Waited 0.42578113509089066, result 2015-11-16 23:35:27.027286
Waited 0.647233264729425, result 2015-11-16 23:35:27.674286
Waited 0.38930513172405146, result 2015-11-16 23:35:28.063286
Waited 0.6500370260649043, result 2015-11-16 23:35:28.713286
Waited 0.9807308512288959, result 2015-11-16 23:35:29.693286
Thanks,
Name Adjustable Implementation Monotonic Resolution (seconds)
============ ========== ========================= ========= ====================
clock False QueryPerformanceCounter() True 3.3106597e-07
monotomic False GetTickCount64() True 0.015600099999
perf_counter False QueryPerformanceCounter() True 3.3106597e-07
process_time False GetProcessTime() True 1e-7
time True GetSystemTimeAsFileTime() False 0.015600099999
So, I come back to this the next morning (computer stayed on all night) and I started up the python interpreter again and everything is fine now!
What the heck, man?
>>> datetime.datetime.utcnow()
datetime.datetime(2015, 11, 17, 17, 19, 17, 626982)
>>> datetime.datetime.utcnow()
datetime.datetime(2015, 11, 17, 17, 19, 18, 234043)
>>> datetime.datetime.utcnow()
datetime.datetime(2015, 11, 17, 17, 19, 19, 106130)
>>> datetime.datetime.utcnow()
datetime.datetime(2015, 11, 17, 17, 20, 7, 707990)
I'm still interested in why this would/could have happened in the first place, so if anyone has any additional information that would be great. Sadly I don't know if I'll be able to replicate it...
There's an old joke about two people at a natural history museum wondering how old a dinosaur fossil is. A guard overhears them and says, "Oh, it's five-hundred million and seven years old". One of the people says, "that's an astonshing number, how was it determined?" The guard says, "Well, I was told it was five-hundred million years old during my orientation, and that was seven years ago."
This is the result of adding together two times with differing levels of precision. Say I start a clock at 12:03:06 and that clock only has minute resolution. If I add the time on my clock to the start time, I'll get a series of times like 12:03:06, 12:04:06, 12:05:06, and so on.
Windows is adding the time from a monotonic clock with millisecond resolution and an arbitrary start time to the time at which that clock read zero with microsecond resolution.
A common technique is simply to round the time to the resolution you are relying on, which of course must not be higher than the clock's guaranteed resolution. I believe the guaranteed resolution for this clock is 10 milliseconds.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With