script/base36-uuid.py: interpret timestamp with Gregorian calendar
UUID v1 uses an epoch derived frmo Gregorian calendar. but base36-uuid.py interprets the timestamp with the UNIX epoch time. that's why it prints a UUID like ```console $ ./scripts/base36-uuid.py -d 3gbi_0mhs_4sjf42oac6rxqdsnyx date = 2411-02-16 16:05:52 decimicro_seconds = 0x7ad550 lsb = 0xafe141a195fe0d59 ``` even this UUID is generated on nov 30, 2023. so in this change, we shift the time with the timestamp of UNIX epoch derived from the Gregorian calendar's day 0. so, after this change, we have: ```console $ ./scripts/base36-uuid.py -d 3gbi_0mhs_4sjf42oac6rxqdsnyx date = 2023-11-30 16:05:52 decimicro_seconds = 0x7ad550 lsb = 0xafe141a195fe0d59 ``` see https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.4 Signed-off-by: Kefu Chai <kefu.chai@scylladb.com> Closes scylladb/scylladb#16235
This commit is contained in:
@@ -132,9 +132,16 @@ class TimeUuid:
|
||||
def lsb(self) -> int:
|
||||
return int.from_bytes(self.uuid.bytes[8:], byteorder='big')
|
||||
|
||||
# the duration between 00:00 15 Oct 1582 and UNIX epoch
|
||||
# see also utils/UUID_gen.hh
|
||||
UNIX_EPOCH_SINCE_GREGORIAN_DAY0 = 122192928000000000
|
||||
|
||||
@property
|
||||
def timestamp(self) -> (datetime.datetime, int):
|
||||
seconds, decimicro_seconds = divmod(self.uuid.time, DECIMICRO_RATIO)
|
||||
# UUID v1 uses a timestamp epoch derived from Gregorian calendar, so we
|
||||
# need to translate the timetamp to the UNIX time
|
||||
unix_time = self.uuid.time - self.UNIX_EPOCH_SINCE_GREGORIAN_DAY0
|
||||
seconds, decimicro_seconds = divmod(unix_time, DECIMICRO_RATIO)
|
||||
return datetime.datetime.fromtimestamp(seconds), decimicro_seconds
|
||||
|
||||
def print_field(self, field: str, print_in_hex: bool) -> None:
|
||||
@@ -178,6 +185,10 @@ def test_dencode_base36() -> None:
|
||||
assert timeuuid.lsb == expected_lsb
|
||||
assert timeuuid.encode_with_base36() == encoded_uuid
|
||||
|
||||
timestamp, decimicro_seconds = timeuuid.timestamp
|
||||
assert timestamp == datetime.datetime(2022, 5, 23, 18, 37, 52)
|
||||
assert decimicro_seconds == 7040000
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
|
||||
Reference in New Issue
Block a user