Python中的UTC时间戳的UUID1?

时间:2011-08-22 21:30:05

标签: python

问题是这样的:

我的应用程序部署在具有不同时区的远程服务器上,我想生成针对UTC时间戳的uuid1。我找不到从任何给定时间戳生成uuid1的方法。我想这样做的原因是我不想进入计算我的本地时间的麻烦,我的本地时间没有观察夏令时和远程服务器的作用,结果表示逻辑变得很麻烦。

限制是时间戳需要存储为uuid1。任何想法或解决方法都将受到高度赞赏。

4 个答案:

答案 0 :(得分:3)

如果你给它正确的片段,那么UUID类会做点杂耍 - http://docs.python.org/library/uuid.html

要获得正确的组件,您可以从python2.7复制uuid1代码:

def uuid1(node=None, clock_seq=None):
        """Generate a UUID from a host ID, sequence number, and the current time.
        If 'node' is not given, getnode() is used to obtain the hardware
        address.  If 'clock_seq' is given, it is used as the sequence number;
        otherwise a random 14-bit sequence number is chosen."""
    # When the system provides a version-1 UUID generator, use it (but don't
    # use UuidCreate here because its UUIDs don't conform to RFC 4122).
    if _uuid_generate_time and node is clock_seq is None:
        _buffer = ctypes.create_string_buffer(16)
        _uuid_generate_time(_buffer)
        return UUID(bytes=_buffer.raw)
    global _last_timestamp
    import time
    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
    if _last_timestamp is not None and timestamp <= _last_timestamp:
        timestamp = _last_timestamp + 1
    _last_timestamp = timestamp
    if clock_seq is None:
        import random
        clock_seq = random.randrange(1<<14L) # instead of stable storage
    time_low = timestamp & 0xffffffffL
    time_mid = (timestamp >> 32L) & 0xffffL
    time_hi_version = (timestamp >> 48L) & 0x0fffL
    clock_seq_low = clock_seq & 0xffL
    clock_seq_hi_variant = (clock_seq >> 8L) & 0x3fL
    if node is None:
        node = getnode()
    return UUID(fields=(time_low, time_mid, time_hi_version,
                        clock_seq_hi_variant, clock_seq_low, node), version=1)

您需要做的就是复制+粘贴并修改时间戳部分以使用固定值(如果您知道时间不同,则可以忽略last_timestamp部分 - 这只是为了避免在时钟分辨率为时重复不足)。

答案 1 :(得分:1)

这是从UUID v1中提取Unix时间戳的功能:

def uuid1_unix_timestamp(uuid_):
    '''
    Extract timestamp from UUID1.

    Params
    ------
    uuid_ : uuid.UUID
        UUID v1 instance.

    Returns
    -------
    float
        Unix timestamp.
    '''
    import datetime as dt

    # UUID v1 timestamp is measured from [00:00:00, 1 October 1582][1].
    #
    # [1]: https://quora.com/Why-UUID-v1-timestamp-measured-from-00-00-00-00-15-October-
    return (uuid_.time * 1e-7 - (dt.datetime.utcfromtimestamp(0) -
                                 dt.datetime(1582, 10, 15)).total_seconds())

用法:

>>> import datetime as dt
>>> # Extract timestamp from a new Python UUID v1 instance.
>>> uuid1_unix_timestamp(uuid.uuid1())
1533834175.8219986
>>> # Convert timestamp from Python UUID v1 to Python datetime.
>>> timestamp = uuid1_unix_timestamp(uuid.uuid1())
>>> dt.datetime.utcfromtimestamp(timestamp)
datetime.datetime(2018, 8, 9, 17, 3, 10, 122999)
>>> # Extract timestamp from a UUID v1 string.
>>> uuid_ = uuid.UUID('4101d7a1-9bf6-11e8-b86d-9cb6d0e37eb4')
>>> uuid1_unix_timestamp(uuid_)
1533834258.9699993

答案 2 :(得分:1)

Python的Cassandra驱动程序现在具有用于此目的的功能:

cassandra.util.uuid_from_time()

https://datastax.github.io/python-driver/api/cassandra/util.html#cassandra.util.uuid_from_time

答案 3 :(得分:0)

这是一个示例代码,它将根据给定的整数时间戳生成UUID1

请注意,虽然时间戳部分将保持静态,但uuid的一部分仍是随机的。 如果您希望uuid保持不变,则可以传递clock_seq

import uuid

try:
    import unittest.mock as mock
except ImportError:
    import mock


def fixed_uuid1(timestamp, *args, **kwargs):
    """Returns a UUID1 from a fixed timestamp"""
    with mock.patch('uuid._uuid_generate_time', None), \
            mock.patch('uuid._last_timestamp', None), \
            mock.patch('time.time', return_value=timestamp):
        return uuid.uuid1(*args, **kwargs)


print(fixed_uuid1(0))
print(fixed_uuid1(0, clock_seq=0))
print(fixed_uuid1(1565627822.303553))