Python解决datetime.now()的问题

5
from datetime import datetime
import time
for i in range(1000):
    curr_time  = datetime.now()
    print(curr_time)
    time.sleep(0.0001)

我正在测试datetime.now()的分辨率。由于它应该以微秒为单位输出,我期望每次打印输出都会不同。然而,我总是得到类似这样的输出结果。
...
2015-07-10 22:38:47.212073
2015-07-10 22:38:47.212073
2015-07-10 22:38:47.212073
2015-07-10 22:38:47.212073
2015-07-10 22:38:47.212073
2015-07-10 22:38:47.212073
2015-07-10 22:38:47.212073
2015-07-10 22:38:47.212073
2015-07-10 22:38:47.212073
2015-07-10 22:38:47.212073
2015-07-10 22:38:47.212073
2015-07-10 22:38:47.212073
2015-07-10 22:38:47.212073
2015-07-10 22:38:47.213074
2015-07-10 22:38:47.213074
2015-07-10 22:38:47.213074
2015-07-10 22:38:47.213074
2015-07-10 22:38:47.213074
2015-07-10 22:38:47.213074
2015-07-10 22:38:47.213074
2015-07-10 22:38:47.213074
2015-07-10 22:38:47.213074
2015-07-10 22:38:47.213074
2015-07-10 22:38:47.213074
...

为什么会发生这种情况?有没有办法获得准确的微秒级时间戳?实际上我不需要微秒,但能获取0.1毫秒的分辨率会很好。
=== 更新 ====
我将其与使用time.perf_counter()和添加到起始datetime的方式进行了比较from datetime import datetime, timedeltaimport time
datetime0 = datetime.now()
t0 = time.perf_counter()
for i in range(1000):
    print('datetime.now(): ', datetime.now())
    print('time.perf_counter(): ', datetime0 + timedelta(0, time.perf_counter()-t0))
    print('\n')

    time.sleep(0.000001)

我不确定它真正有多“准确”,但分辨率至少更高。然而,这似乎并不重要,因为我的电脑甚至无法以如此高的速度打印。对于我的目的来说,我只是需要不同的时间戳来区分不同的条目,所以这对我来说已经足够好了。

...
datetime.now():  2015-07-10 23:24:18.010377
time.perf_counter():  2015-07-10 23:24:18.010352


datetime.now():  2015-07-10 23:24:18.010377
time.perf_counter():  2015-07-10 23:24:18.010545


datetime.now():  2015-07-10 23:24:18.010377
time.perf_counter():  2015-07-10 23:24:18.010745


datetime.now():  2015-07-10 23:24:18.011377
time.perf_counter():  2015-07-10 23:24:18.010961


datetime.now():  2015-07-10 23:24:18.011377
time.perf_counter():  2015-07-10 23:24:18.011155


datetime.now():  2015-07-10 23:24:18.011377
time.perf_counter():  2015-07-10 23:24:18.011369


datetime.now():  2015-07-10 23:24:18.011377
time.perf_counter():  2015-07-10 23:24:18.011596


datetime.now():  2015-07-10 23:24:18.012379
time.perf_counter():  2015-07-10 23:24:18.011829


datetime.now():  2015-07-10 23:24:18.012379
time.perf_counter():  2015-07-10 23:24:18.012026


datetime.now():  2015-07-10 23:24:18.012379
time.perf_counter():  2015-07-10 23:24:18.012232


datetime.now():  2015-07-10 23:24:18.012379
time.perf_counter():  2015-07-10 23:24:18.012424


datetime.now():  2015-07-10 23:24:18.012379
time.perf_counter():  2015-07-10 23:24:18.012619


datetime.now():  2015-07-10 23:24:18.013380
time.perf_counter():  2015-07-10 23:24:18.012844


datetime.now():  2015-07-10 23:24:18.013380
time.perf_counter():  2015-07-10 23:24:18.013044


datetime.now():  2015-07-10 23:24:18.013380
time.perf_counter():  2015-07-10 23:24:18.013242


datetime.now():  2015-07-10 23:24:18.013380
time.perf_counter():  2015-07-10 23:24:18.013437


datetime.now():  2015-07-10 23:24:18.013380
time.perf_counter():  2015-07-10 23:24:18.013638


datetime.now():  2015-07-10 23:24:18.014379
time.perf_counter():  2015-07-10 23:24:18.013903


datetime.now():  2015-07-10 23:24:18.014379
time.perf_counter():  2015-07-10 23:24:18.014125


datetime.now():  2015-07-10 23:24:18.014379
time.perf_counter():  2015-07-10 23:24:18.014328


datetime.now():  2015-07-10 23:24:18.014379
time.perf_counter():  2015-07-10 23:24:18.014526


datetime.now():  2015-07-10 23:24:18.014379
time.perf_counter():  2015-07-10 23:24:18.014721


datetime.now():  2015-07-10 23:24:18.015381
time.perf_counter():  2015-07-10 23:24:18.014919

...

3
我确定这取决于操作系统的时钟,而操作系统的时钟通常不是非常精确的。 - Mark Ransom
你的时间戳的最大分辨率将取决于你的时间源的最大分辨率。 - Burhan Khalid
我明白了。我正在使用Windows 8。它似乎具有1毫秒的分辨率。我猜操作系统没有超过这个分辨率的方法? - tuzzer
如果您在循环中运行调用GetSystemTimeAsFileTime()datetime.utcnow()utcnow_microseconds()(删除time.sleep())会发生什么? - jfs
1个回答

2
这可能是您的系统对time.sleep的限制,而不是datetime.now()...或者两者都有。请问您正在运行哪个操作系统、哪个版本以及哪个Python分发版?您的系统可能没有提供time.sleep文档中提到的“亚秒精度”。
sleep(...)
    sleep(seconds)

    Delay execution for a given number of seconds.  The argument may be
    a floating point number for subsecond precision.

在Linux 3.x上,使用CPython 2.7,我得到了非常接近您预期的0.0001时间步长的结果。
2015-07-10 19:58:24.353711
2015-07-10 19:58:24.353879
2015-07-10 19:58:24.354052
2015-07-10 19:58:24.354227
2015-07-10 19:58:24.354401
2015-07-10 19:58:24.354577
2015-07-10 19:58:24.354757
2015-07-10 19:58:24.354938

1
我使用Windows 8和Python 34。我认为问题出在datetime.now()上。我尝试了time.clock(),它似乎在每个循环中显示不同的时间。可能需要将从time.clock()获取的值转换为datetime。 - tuzzer
很好了解。如果还没有的话,我建议提交错误报告 - Dan Lenski
3
@tuzzer说:datetime.now()函数具有微秒级别的精度未来可能支持纳秒),可以查看.resolution属性。这并不代表准确性,在Windows上可能大约为10毫秒到55毫秒左右(ms==毫秒)(.utcnow()在现代CPython和Windows上使用GetSystemTimeAsFileTime())。请参见精度与准确性不同 - jfs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接