TypeDB.Duration (TypeDB v0.2.2)

Copy Markdown View Source

A TypeDB duration value.

TypeDB durations are ISO-8601 durations. They are not a fixed number of seconds: a month is a calendar month and a day is a calendar day, so they are kept as three independent components exactly as TypeDB stores them.

iex> TypeDB.Duration.parse("P1Y2M3DT4H5M6.5S")
%TypeDB.Duration{months: 14, days: 3, nanos: 14_706_500_000_000, raw: "P1Y2M3DT4H5M6.5S"}

raw always holds the original wire representation, so nanosecond precision is never lost even when converting to coarser Elixir types.

Summary

Functions

Parses an ISO-8601 duration, returning {:ok, duration} or :error.

Parses an ISO-8601 duration.

Returns the time component in nanoseconds.

Renders the duration back to ISO-8601.

Types

t()

@type t() :: %TypeDB.Duration{
  days: integer(),
  months: integer(),
  nanos: integer(),
  raw: String.t() | nil
}

Functions

from_iso8601(string)

@spec from_iso8601(String.t()) :: {:ok, t()} | :error

Parses an ISO-8601 duration, returning {:ok, duration} or :error.

parse(string)

@spec parse(String.t()) :: t() | String.t()

Parses an ISO-8601 duration.

Returns the original string unchanged if it cannot be parsed, so that an unexpected server-side format degrades instead of crashing.

time_in_nanoseconds(duration)

@spec time_in_nanoseconds(t()) :: integer()

Returns the time component in nanoseconds.

Calendar components (months, days) are deliberately excluded — their length depends on the date they are applied to.

to_iso8601(duration)

@spec to_iso8601(t()) :: String.t()

Renders the duration back to ISO-8601.

A duration that came off the wire renders as the exact string TypeDB sent, so nanosecond precision and TypeDB's own choice of units survive the round trip — but only while raw still describes the components. Edit any of :months, :days or :nanos and the components win, because otherwise a read-modify-write would silently send the original value back.

Raises TypeDB.Error with kind :encode for a negative component — a deliberate, frozen choice, not an oversight. Rendering functions in Elixir raise on a value they cannot render (Date.to_iso8601/1 does), returning {:ok, string} here would make every caller handle a case no driver-produced duration can be in, and normalising silently would send a value nobody asked for. TypeDB has no negative durations: TypeQL's grammar rejects P-1Y, -P1Y and every other form, and P-1Y-2M is misread as a type label, so the server answers "Type label 'P-1Y-2M' not found". Failing here says what is actually wrong. Note this is a deliberate divergence from Elixir's own Duration, which does render "P-14M" — that type does calendar arithmetic, where a negative duration is meaningful; this one is a wire value for a database that has no such thing.