问题是这样的:
我的应用程序部署在具有不同时区的远程服务器上,我想生成针对UTC时间戳的uuid1。我找不到从任何给定时间戳生成uuid1的方法。我想这样做的原因是我不想进入计算我的本地时间的麻烦,我的本地时间没有观察夏令时和远程服务器的作用,结果表示逻辑变得很麻烦。
限制是时间戳需要存储为uuid1。任何想法或解决方法都将受到高度赞赏。
答案 0 :(得分:3)
要获得正确的组件,您可以从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))