Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UUID1 from UTC Timestamp in Python?

Tags:

python

The problem goes like this:

My application is deployed on a remote server with different timezone and I want to generate a uuid1 against UTC timestamp. I can't find a way to generate uuid1 from any given timestamp. The reason I want to do this is that I don't want to get into the hassle of calculating my local time where my local time does not observe Daylight saving time and the remote server does and a result the presentation logic becomes cumbersome.

The limitation is that the Timestamp needs to be stored as uuid1. Any idea or workaround for this will be higly appreciated.

like image 838
SoulReaver Avatar asked Feb 24 '23 05:02

SoulReaver


1 Answers

the UUID class will do the bit-juggling if you give it the right fragments - http://docs.python.org/library/uuid.html

to get the right components you can copy the the uuid1 code from python2.7:

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)

all you need to do is copy+paste that and modify the timestamp part to use a fixed value (you can ignore the last_timestamp part if you know that your times are distinct - that is just to avoid duplicates when the clock resolution is insufficient).

like image 118
andrew cooke Avatar answered Mar 11 '23 19:03

andrew cooke