You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Thanks for making this library and writing it in rust!
Currently this library expects uuid7(timestamp) to get an integer milliseconds value, which doesn't match the seconds.msµs precision that the python datetime standard library uses for unix timestamps and datetime objects.
support the UUIDv7-recommeded default of using 1ms precision for timestamp
support the python-ecosystem default of using 1µs precision for timestamp
document that UUIDv8 is recommended for all other precisions (e.g. 50ns,100nsetc.) (OR add a uuid7(timestamp=..., resolution: int=1_000_000) (nanoseconds) parameter?)
Can we add native datetime obj and seconds.msµs ts support to uuid7(timestamp)?
I propose uuid_utils.uuid7(timestamp=...) be extended to accept int | float | datetime as ms or seconds.msµs in order to align with python ecosystem expectations. This can be accomplished without breaking any existing behavior or adding any new non-determinism, because milliseconds-based timestamps are easily distinguished based on length. If a native python datetime or timestamp float with µs precision is passed, I think it is safe and expected to fill the optional uuid7 fields up to the same ~1µs resolution that the user provides.
While the 2022 draft only had millisecond precision, the most recent RFC draft as of 2024 has support for variable precision (1ms ~ 50ns) transparently in a single namespace by opportunistically using the leftmost bits of the randomness segment.
The default precision can stay at the millisecond level as recommended by UUIDv7, but for applications that work in the python ecosystem and/or need finer control, accepting datetime | float could provide an escape hatch to access more precision.
Right now, calls in quick succession result in identical timestamps between separate uuid7s. It's unfortunate because the uuid7 has space for more precision in theory, it would be nice to be able to encode timstamps up to the same resolution that the standard library can. Apps could get slightly more monotonic (and can also get rid of redundant created_at fields).
print(uuid7().timestamp, uuid7().timestamp) # 1735718399999, 1735718399999# could be this:print(uuid7().timestamp, uuid7().timestamp) # 1735718399.999123, 1735718399.999124
In order to not break backwards compatibility, all this could be accomplished by overloading the signature of uuid7:
- def uuid7(timestamp: int | None = None):+ def uuid7(timestamp: int | float | datetime | None = None):+ timestamp = timestamp or datetime.now()+ if isinstance(timestamp, (int, float)):+ try:+ # first try parsing ts as int/float seconds (the python stdlib default format)+ timestamp = datetime.fromtimestamp(timestamp, UTC)+ # will throw "ValueError: year 56964 is out of range" if ts is milliseconds+ except ValueError:+ # preserve existing uuid_utils.uuid7 default behavior (timestamp is milliseconds as int)+ timestamp = datetime.fromtimestamp(timestamp/1000, UTC)+
...
Can a UUID().date property be added to return the full microsecond-precision datetime?
>>>datetime.fromtimestamp(uuid7().timestamp, UTC) # off by /1000, not what python expectsValueError: year56963isoutofrange
# ideally UUID.timestamp should return a python-standard seconds.msµs float like so:>>>datetime.fromtimestamp(uuid7(1735718399999).timestamp) # aka 1735718399.999000datetime.datetime(2024, 12, 31, 23, 59, 59, 999000) # (the default, ms precision)>>>datetime.fromtimestamp(uuid7(1735718399.999123).timestamp)
datetime.datetime(2024, 12, 31, 23, 59, 59, 999123) # (µs precision when ts is passed)# but in order to not break backwards compatibility, adding a new .date property is more realistic:>>>uuid7(1735718399.999123).datedatetime.datetime(2024, 12, 31, 23, 59, 59, 999123)
>>>uuid7(1735718399.999123).date.timestamp() # allows getting python timestamp easily too1735718399.999123
+ from datetime import UTC, datetime
class UUID:
...
+ @property+ def date(self) -> datetime:+ return datetime.fromtimestamp(self.timestamp/1000, UTC)
Timestamp precision should survive round-trip Encode/Decode
# example usage:>>>ts_with_µs=1735718399.999123# sec.msµs float, same format as python stdlib datetime.timestamp()>>>dt_with_µs=datetime.fromtimestamp(ts, UTC) # == datetime(2024, 12, 31, 23, 59, 59, 999123)>>>uuid7_with_µs=uuid7(timestamp=dt_with_µs) # pass datetime with ms and/or µs>>>assertuuid7_with_µs==uuid7(timestamp=ts_with_µs) # pass ts as int or float with µs>>>after_dt=datetime.fromtimestamp(uuid7_with_µs.timestamp, UTC) # == datetime.datetime(2024, 12, 31, 23, 59, 59, 999123) >>>after_ts=_with_microseconds.timestamp() # ms.µs should be identical to original1735445361.908123# ms & µs should survive encode/decode with full precision>>>assertts_with_µs==after_ts==dt_with_µs.timestamp() ==after_dt.timestamp() ==uuid7_with_µs.timestamp
The 128 bits in the UUID would be allocated as follows:
48 bits for milliseconds since epoch
4 bits for version
12 bits for µs
2 bits for variant + 2 bits of rand
12 bits for ns / rand
48 bits of randomness
The text was updated successfully, but these errors were encountered:
pirate
changed the title
Questions about UUID().timestamp and uuid7(timestmap)
Questions about UUID().timestamp and uuid7(timestmap)Dec 29, 2024
pirate
changed the title
Questions about UUID().timestamp and uuid7(timestmap)
Allow passing datetime to uuid7(timestamp) and add UUID.date: datetime getter
Dec 29, 2024
Thanks for making this library and writing it in rust!
Currently this library expects
uuid7(timestamp)
to get an integer milliseconds value, which doesn't match theseconds.msµs
precision that the pythondatetime
standard library uses for unix timestamps anddatetime
objects.uuid7(timestamp=..., resolution: int=1_000_000)
(nanoseconds) parameter?)Can we add native
datetime
obj andseconds.msµs
ts support touuid7(timestamp)
?I propose
https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-7uuid_utils.uuid7(timestamp=...)
be extended to acceptint | float | datetime
asms
orseconds.msµs
in order to align with python ecosystem expectations. This can be accomplished without breaking any existing behavior or adding any new non-determinism, because milliseconds-based timestamps are easily distinguished based on length. If a native pythondatetime
or timestampfloat
with µs precision is passed, I think it is safe and expected to fill the optional uuid7 fields up to the same ~1µs resolution that the user provides.While the 2022 draft only had millisecond precision, the most recent RFC draft as of 2024 has support for variable precision (1ms ~ 50ns) transparently in a single namespace by opportunistically using the leftmost bits of the randomness segment.
https://www.rfc-editor.org/rfc/rfc9562#monotonicity_counters
The default precision can stay at the millisecond level as recommended by UUIDv7, but for applications that work in the python ecosystem and/or need finer control, accepting
datetime | float
could provide an escape hatch to access more precision.Right now, calls in quick succession result in identical timestamps between separate uuid7s. It's unfortunate because the uuid7 has space for more precision in theory, it would be nice to be able to encode timstamps up to the same resolution that the standard library can. Apps could get slightly more monotonic (and can also get rid of redundant
created_at
fields).In order to not break backwards compatibility, all this could be accomplished by overloading the signature of
uuid7
:Can a
UUID().date
property be added to return the full microsecond-precisiondatetime
?Timestamp precision should survive round-trip Encode/Decode
The 128 bits in the UUID would be allocated as follows:
The text was updated successfully, but these errors were encountered: