import uuid import random from datetime import datetime, UTC def encode_time_fields(dt: datetime) -> int: year = dt.year month = dt.month hour = dt.hour minute = dt.minute millisecond = dt.microsecond // 1000 # Bounds check if not (1970 <= year <= 4095): raise ValueError("Year out of range") # Encode into 40 bits encoded = ( ((year - 1970) << 28) | (month << 24) | (hour << 19) | (minute << 13) | (millisecond) ) return encoded # 40 bits def generate_uuidv8_custom_time(dt: datetime = None) -> uuid.UUID: if dt is None: dt = datetime.now(UTC) timestamp_bits = encode_time_fields(dt) # Fill the remaining 88 bits with randomness rand_high = random.getrandbits(88) # Combine timestamp and random into a 128-bit integer full_bits = (timestamp_bits << 88) | rand_high # Insert UUIDv8 version and variant bits full_bits &= ~(0xF << 76) full_bits |= (0x8 << 76) # version 8 full_bits &= ~(0xC000 << 48) full_bits |= (0x8000 << 48) # variant 1 (10xxxxxx...) # Convert to UUID object bytes_ = full_bits.to_bytes(16, byteorder="big") return uuid.UUID(bytes=bytes_) def decode_time_from_uuidv8(u: uuid.UUID): int_val = int.from_bytes(u.bytes, byteorder="big") timestamp_bits = int_val >> 88 year = ((timestamp_bits >> 28) & 0xFFF) + 1970 month = (timestamp_bits >> 24) & 0xF hour = (timestamp_bits >> 19) & 0x1F minute = (timestamp_bits >> 13) & 0x3F millisecond = timestamp_bits & 0x1FFF return f"{year:04}-{month:02} {hour:02}:{minute:02}.{millisecond:03}" uuid = generate_uuidv8_custom_time() # '03749580-0664-8ad3-ac86-c2532981ef85' decode_time_from_uuidv8(uuid) # '2025-04 18:44.6'