An Ecto.Type storing an Elixir Date.Range.t/0 in a PostgreSQL
daterange column.
A range such as Date.range(~D[2024-01-01], ~D[2024-12-31]) stores
and loads as itself, so a span of dates is a first-class value in a
schema. daterange is a built-in PostgreSQL type, so no migration
beyond the column is needed, and the column can be queried with the
range operators (@>, &&) — including an exclusion constraint that
forbids overlapping spans — and indexed with a GiST index.
Schema
# in a migration
add :period, :daterange
# in a schema
field :period, Localize.Ecto.Type.DateRangeSemantics
Date.Range is inclusive of both ends, so
Date.range(~D[2024-01-01], ~D[2024-12-31]) covers the whole year;
it is stored as the PostgreSQL range [2024-01-01, 2024-12-31] and
read back inclusive regardless of the bound form PostgreSQL
canonicalizes to (it stores daterange as [lower, upper)).
Only ascending day-step ranges are storable — a range carrying a step
other than one day, or a descending one, has no daterange
equivalent and is rejected on cast and dump.
Summary
Functions
Callback implementation for Ecto.Type.embed_as/1.
Callback implementation for Ecto.Type.equal?/2.
Functions
Callback implementation for Ecto.Type.embed_as/1.
Callback implementation for Ecto.Type.equal?/2.