【问题标题】:Why would Python's datetime.utcnow() always return the same value for microseconds?为什么 Python 的 datetime.utcnow() 总是在微秒内返回相同的值?
【发布时间】:2016-02-18 05:04:34
【问题描述】:

我正在使用 Python 的 datetime.datetime.utcnow() 方法,我注意到微秒值始终相同。

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

请注意微秒值始终为 286。为什么会这样?我能做些什么来解决这个问题?

更多信息:time.time() 也总是有 286us。毫秒值很好。我认为这实际上是根本原因,因为我相信 datetime.datetime.utcnow() 调用 time.time()。


这是一个简短的脚本,表明这不仅仅是运气:

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()))

结果:

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

谢谢,


系统信息:

  • Win32 上的 Python 3.4.3(v3.4.3:9b73f1c3e601,2015 年 2 月 24 日,22:44:40)[MSC v.1600 64 位 (AMD64)]
  • Windows 7 Professional,Service Pack 1. 64 位。
  • 英特尔酷睿 i5-2400 @ 3.10GHz

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

最终编辑:

所以,我第二天早上回来(电脑整晚都开着),我再次启动了 python 解释器,现在一切都很好!

什么鬼,伙计?

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

我仍然对为什么会/可能首先发生这种情况感兴趣,所以如果有人有任何额外的信息,那就太好了。可悲的是我不知道我是否能够复制它......

【问题讨论】:

  • 好时机?我无法复制它。
  • 每次给我打电话时看起来都不一样。 datetime.datetime(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])。年、月、日、时相同。我猜你的系统时钟没有输出那个精度……我们说的是纳秒,而不是微秒。
  • 您计算机上的系统时钟很可能没有必要的精度来处理这些微秒数。我不确定为什么最后 3 位数字不是 000。
  • 不,随机等待总是会产生相同的 286us 值。再加上它连续发生 30 次的几率非常小。我只是碰巧在原始帖子中展示了其中的 3 个。
  • 你的处理器是什么?

标签: python datetime python-3.x python-3.4 python-datetime


【解决方案1】:

免责声明:这不是答案。


我看到完全不同的微秒,所以我做了这个实验:

ms = 0
for _ in range(10000):
    ms_ = datetime.datetime.utcnow().microsecond % 10000
    if ms != ms_:
        diff = (ms_ - ms) % 1000
        ms = ms_
        print ms, diff

它显示了微秒的变化(我只是显示了一个数字,所以增加是可见的):

8007 7    # garbage
8984 977
9960 976
937 977
1914 977
2890 976
3867 977
4843 976
5820 977
6796 976
7773 977
8750 977
9726 976
703 977
1679 976
2656 977
3632 976
4609 977
5585 976

如您所见,在我的 Windows 机器上,增量非常一致。它只是不是 1000,就像在 OP 的机器上一样,所以这就是为什么我(我们?)观察到不同的微秒。增量可能与某些系统时钟同步,我猜,在 OP 的机器上每毫秒都会重新触发一次?

很想听听其他人的意见。欢迎发表评论。

注意:这是一台 T4500,运行频率为 2.30GHz。

【讨论】:

  • 现在我正在考虑时钟速度...你的呢?
  • @KarolyHorvath 你问我们是否可以复制你所看到的,现在,我不能。运行您的代码时,我总是得到 diff=0:1286 0, 2286 0, 3286 0, 4286 0, etc...
  • 我的机器上有很多 diff = 7 和 8
  • @dthor:你显然可以,而且你确实......增量是一样的,对你来说是 1000。
  • @KarolyHorvath 哈哈,是的,你是对的。我没想到。
【解决方案2】:

有一个古老的笑话,关于自然历史博物馆的两个人想知道恐龙化石的年龄。一名守卫无意中听到他们说:“哦,它已经有 5 亿 7 年的历史了”。一个人说:“这是一个惊人的数字,它是如何确定的?”守卫说:“嗯,在我接受培训时,有人告诉我它有五亿年的历史,那是七年前的事了。”

这是两次以不同精度水平相加的结果。假设我在 12:03:06 开始时钟,而时钟只有分钟分辨率。如果我将时钟上的时间添加到开始时间,我会得到一系列时间,例如 12:03:06、12:04:06、12:05:06 等等。

Windows 正在将时间从具有毫秒分辨率和任意开始时间的单调时钟添加到该时钟以微秒分辨率读取零的时间。

一种常见的技术就是简单地将时间四舍五入到您所依赖的分辨率,这当然不能高于时钟的保证分辨率。我相信这个时钟的保证分辨率是 10 毫秒。

【讨论】:

  • 所有 Windows 版本都这样吗?那你怎么解释我的结果呢?
  • 我怀疑出于某种原因,他的 TSC 无法使用。也许他的 CPU 没有恒定的 TSC 频率。我不确定。 (i5-2400 的文档说确实如此。可能是 BIOS 损坏?可能是奇怪的电源管理设置?HPET 已禁用?HPET 未在 BIOS 中设置为 64 位模式?)
  • 这是一个完全不同的芯片。你有一致的增量吗?
  • @DavidSchwartz 我明白你在第 2 段中所说的话,但我的问题是:我是如何总是在 286us 上开始我的 1ms 时钟的?使用您的示例,我希望下次我开始时钟时是 12:08:27、12:09:27、12:10:27 等。
  • @dthor 系统启动时的时钟。
猜你喜欢
  • 2013-09-20
  • 1970-01-01
  • 2014-05-18
  • 2018-09-24
  • 1970-01-01
  • 2020-12-27
  • 2020-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多