Uuidv7Chrono
Convert between dates/datetimes and UUIDv7 for time-based Ecto database queries.
UUIDv7 encodes a Unix timestamp in its most significant bits, making primary keys naturally time-ordered. This library lets you generate UUIDv7 boundary values from a Date or DateTime, so you can efficiently filter records by time using simple primary key comparisons — no extra inserted_at index needed.
Installation
Add uuidv7_chrono to your list of dependencies in mix.exs:
def deps do
[
{:uuidv7_chrono, "~> 0.1.0"}
]
endUsage
Filter Ecto queries by time
yesterday = Date.utc_today() |> Date.add(-1)
# Records created after yesterday
from(u in User, where: u.id > ^Uuidv7Chrono.to_uuid(yesterday))
# Records created before a specific timestamp
cutoff = ~U[2026-01-01 00:00:00Z]
from(o in Order, where: o.id < ^Uuidv7Chrono.to_uuid(cutoff))Extract timestamps from UUIDv7
Uuidv7Chrono.to_datetime("019d2566-fe40-7000-8000-000000000000")
#=> ~U[2026-03-25 14:30:00.000Z]
Uuidv7Chrono.to_date("019d2566-fe40-7000-8000-000000000000")
#=> ~D[2026-03-25]
Both to_datetime/1 and to_date/1 accept string UUIDs ("019d2566-fe40-...") and raw 16-byte binary UUIDs.
Database partitioning
If your table is range-partitioned on a UUIDv7 primary key, these boundary values enable partition pruning — the database skips partitions that can't contain matching rows:
# Query only hits the Q1 2026 partition
from(o in Order,
where: o.id >= ^Uuidv7Chrono.to_uuid(~D[2026-01-01])
and o.id < ^Uuidv7Chrono.to_uuid(~D[2026-04-01])
)Postgres-compatible aliases
If you prefer names that mirror the pg_uuidv7 Postgres extension:
Uuidv7Chrono.uuid_generate_v7(~U[2026-03-25 14:30:00Z])
Uuidv7Chrono.uuid_v7_to_timestamptz("019d2566-fe40-7000-8000-000000000000")API
| Function | Description |
|---|---|
to_uuid(Date.t() | DateTime.t()) | Date/DateTime to UUIDv7 string |
to_datetime(String.t() | binary()) | UUIDv7 to DateTime |
to_date(String.t() | binary()) | UUIDv7 to Date |
uuid_generate_v7/1 |
Alias for to_uuid/1 (pg_uuidv7 compat) |
uuid_v7_to_timestamptz/1 |
Alias for to_datetime/1 (pg_uuidv7 compat) |
How it works
to_uuid/1 encodes the timestamp as the first 48 bits of a UUIDv7 and fills the remaining bits with zeros. This produces the lowest possible UUIDv7 for that point in time, making it ideal as a boundary value in range queries.
Zero dependencies. Pure Elixir.
License
Apache-2.0