从Python中的UUID v1中提取时间

28

我有一些在我的程序中随机生成的UUID,但是我想要提取生成的UUID的时间戳以进行测试。我注意到使用 fields 访问器可以获取时间戳的各个部分,但我不知道如何将它们组合起来。

4个回答

39

查看 /usr/lib/python2.6/uuid.py 文件,你会看到:

def uuid1(node=None, clock_seq=None):
    ...
    nanoseconds = int(time.time() * 1e9)
    # 0x01b21dd213814000 is the number of 100-ns intervals between the
    # UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
    timestamp = int(nanoseconds/100) + 0x01b21dd213814000L

如果解出time.time()的方程组,你将得到:

time.time()-like quantity = ((timestamp - 0x01b21dd213814000L)*100/1e9)

所以使用:

In [3]: import uuid

In [4]: u = uuid.uuid1()

In [58]: datetime.datetime.fromtimestamp((u.time - 0x01b21dd213814000L)*100/1e9)
Out[58]: datetime.datetime(2010, 9, 25, 17, 43, 6, 298623)

这个函数返回由uuid.uuid1生成的UUID相关联的日期时间。


看起来你解决了我的问题。与此同时,我不得不返回并创建自己的构造函数,因为它只生成当前时间戳,而我需要随机过去的时间戳。谢谢你的快速回答 :-) - cdecker
1
有趣的是,UUID时代是指儒略历...(捂脸) - ezdazuzena
3
@ezdazuzena,实际上,格里高利历(请参见RFC 4122,第4.1.4节关于基督教历法的改革)。当然,这完全是任意的,但UNIX纪元也是如此。我向你挑战,选择一个更好的日期起点,并解释为什么你的决定不仅是任意的,并且展示有必要改变现有标准(以及其众多的依赖和间接依赖项)以遵循你的标准。 - zxq9

19

您可以使用一个简单的公式,该公式直接遵循定义

时间戳是一个 60 位值。对于 UUID 第 1 版,它以协调世界时(UTC)表示,作为自公历改革的日期——1582 年 10 月 15 日 00:00:00.00 起的 100 纳秒间隔计数。

>>> from uuid import uuid1
>>> from datetime import datetime, timedelta
>>> datetime(1582, 10, 15) + timedelta(microseconds=uuid1().time//10)
datetime.datetime(2015, 11, 13, 6, 59, 12, 109560)

12
使用TimeUUID库,这样您就知道您没有做错数学了。
示例。
import uuid
import time_uuid

my_uuid = uuid.UUID('{12345678-1234-5678-1234-567812345678}')
ts = time_uuid.TimeUUID(bytes=my_uuid.bytes).get_timestamp()

我尝试不断调用 print(time_uuid.TimeUUID(bytes=uuid.uuid1().bytes).get_datetime()),但我发现时间只在每2秒钟改变一次。它似乎无法精确计算。 - Ruben Alves
但是我发现每次调用uuid1().time时,它的值都不同,这正是我所期望的。考虑到我只想知道哪一个是先创建的,通过比较它们的uuid1().time就可以解决我的问题。 - Ruben Alves
3
我不建议为一行代码的问题增加依赖。 - Ninjakannon

3
自从我安装了Cassandra并且在使用它,我就能够使用`cassandra.util`中的`datetime_from_uuid1`函数。
>>> import uuid
>>> from cassandra.util import datetime_from_uuid1
>>> foo = uuid.uuid1()
>>> dt_foo = datetime_from_uuid1(foo)
>>> dt_foo
datetime.datetime(2016, 07, 26, 8, 2, 12, 104560)

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