Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would Python's datetime.utcnow() always return the same value for microseconds?

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,


System Info:

  • Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:44:40) [MSC v.1600 64 bit (AMD64)] on win32
  • Windows 7 Professional, Service Pack 1. 64 bit.
  • Intel Core i5-2400 @ 3.10GHz

Results from time.get_clock_info()

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

Final Edit:

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...

like image 240
dthor Avatar asked Sep 26 '22 04:09

dthor


1 Answers

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.

like image 112
David Schwartz Avatar answered Sep 30 '22 06:09

David Schwartz