An Ecto type for a span of time: a start and an end instant, the start
included and the end left out ([from, to)), as for a booking from
14:00 to 16:00.
The :storage option says how the span is stored, so that the same
field works with any database:
:postgres(the default) - a PostgreSQLtstzrangecolumn. It needs:postgrex.:string- a text column with an ISO 8601 interval in UTC,"2027-03-15T13:00:00Z/2027-03-15T15:00:00Z": SQLite, MySQL, and embedded schemas.:map- a map column (JSON in SQLite and MySQL) with%{"from" => "2027-03-15T13:00:00Z", "to" => "2027-03-15T15:00:00Z"}.
# PostgreSQL
add :booking, :tstzrange
field :booking, Koyomi.DateTimeRange
# SQLite (ecto_sqlite3), MySQL
add :booking, :string
field :booking, Koyomi.DateTimeRange, storage: :stringA query for the spans that hold an instant needs PostgreSQL; with
another database, two :utc_datetime columns can be queried as
instants.
The value is a %Koyomi.DateTimeRange{from: DateTime, to: DateTime},
in UTC. The type casts this struct, a {from, to} tuple, a map with
"from" and "to" (two DateTime, or two ISO 8601 strings with an
offset, "2027-03-15T14:00:00+01:00", as two date and time pickers
with a time_zone post them), and an ISO 8601 interval of two such
strings. Both ends empty cast to nil. A span that ends before it
starts is invalid.
Summary
Functions
Casts a value to a Koyomi.DateTimeRange (see the module docs for the
forms it takes).
Dumps a span to a PostgreSQL tstzrange (Postgrex.Range), [from, to).
The length of the span.
Loads a PostgreSQL tstzrange (Postgrex.Range); a span without a
bound (infinite) or an empty one loads as nil.
The span as ISO 8601 strings in UTC: %{"from" => iso, "to" => iso}.
Types
@type t() :: %Koyomi.DateTimeRange{from: DateTime.t(), to: DateTime.t()}
Functions
Casts a value to a Koyomi.DateTimeRange (see the module docs for the
forms it takes).
Dumps a span to a PostgreSQL tstzrange (Postgrex.Range), [from, to).
@spec duration(t(), System.time_unit()) :: integer()
The length of the span.
Examples
iex> {:ok, span} = Koyomi.DateTimeRange.cast(%{"from" => "2027-03-15T14:00:00Z", "to" => "2027-03-15T16:30:00Z"})
iex> Koyomi.DateTimeRange.duration(span, :minute)
150
Loads a PostgreSQL tstzrange (Postgrex.Range); a span without a
bound (infinite) or an empty one loads as nil.
The span as ISO 8601 strings in UTC: %{"from" => iso, "to" => iso}.
Examples
iex> {:ok, span} = Koyomi.DateTimeRange.cast(%{"from" => "2027-03-15T14:00:00+01:00", "to" => "2027-03-15T16:00:00+01:00"})
iex> Koyomi.DateTimeRange.to_params(span)
%{"from" => "2027-03-15T13:00:00Z", "to" => "2027-03-15T15:00:00Z"}