Precision-preserving Ion timestamp representation.
Ion timestamps carry precision and local offset semantics that native Elixir
date/time types cannot represent. Two timestamps are Ion-equivalent only when
they have the same precision, the same offset status, and the same component
values. For example, 2001T and 2001-01T represent the same instant but
have different precisions — they are NOT equivalent in Ion.
Fields
:year— always present:month— nil for year precision:day— nil for year/month precision:hour— nil for date-only precision (always paired with minute):minute— nil for date-only precision:second— nil for minute precision:fraction— fractional seconds as a digit string (e.g."123","00300"), preserving trailing zeros for precision. nil if no fractional seconds.:offset—:unknownfor-00:00, integer (minutes from UTC) for known offsets, nil when no time component is present:precision— one of:year,:month,:day,:minute,:second,:fractional_second
Summary
Functions
Build a DateTime, NaiveDateTime, or Date from timestamp components.
Format a UTC offset in seconds as a zone abbreviation like "+05:30" or "-08:00".
Build a %Eyeon.Timestamp{} directly from parsed components.
Parse an Ion timestamp string into a %Eyeon.Timestamp{}.
Returns true if the given year is a leap year.
Maximum number of days in a given month, accounting for leap years.
Parse a fractional seconds string (like ".123456" or "123456") into a
{microseconds, precision} tuple.
Convert to an Ion text representation string.
Convert to a native Elixir date/time type.
Convert to a UTC DateTime for timeline comparison.
Types
@type offset() :: :unknown | integer() | nil
@type precision() :: :year | :month | :day | :minute | :second | :fractional_second
@type t() :: %Eyeon.Timestamp{ day: pos_integer() | nil, fraction: String.t() | nil, hour: non_neg_integer() | nil, minute: non_neg_integer() | nil, month: pos_integer() | nil, offset: offset(), precision: precision(), second: non_neg_integer() | nil, year: pos_integer() }
Functions
@spec components_to_native( integer(), integer() | nil, integer() | nil, integer() | nil, integer() | nil, integer() | nil, String.t() | nil, integer() ) :: Date.t() | NaiveDateTime.t() | DateTime.t()
Build a DateTime, NaiveDateTime, or Date from timestamp components.
offsetis in minutes, with -0x800 meaning unknown offset.- When hour/minute/day/month are nil, returns coarser types (Date).
Format a UTC offset in seconds as a zone abbreviation like "+05:30" or "-08:00".
@spec from_components( integer(), integer() | nil, integer() | nil, integer() | nil, integer() | nil, integer() | nil, String.t() | nil, integer() ) :: t()
Build a %Eyeon.Timestamp{} directly from parsed components.
Used by the binary decoder which already has components parsed.
offset uses the binary encoding convention: -0x800 for unknown offset,
minutes from UTC otherwise.
Parse an Ion timestamp string into a %Eyeon.Timestamp{}.
Accepts all Ion timestamp formats:
2024T(year)2024-01T(year-month)2024-01-15or2024-01-15T(date)2024-01-15T12:30Z(minute with offset)2024-01-15T12:30:00Z(second with offset)2024-01-15T12:30:00.123Z(fractional second with offset)
Returns true if the given year is a leap year.
Maximum number of days in a given month, accounting for leap years.
@spec parse_frac_to_microsecond(nil | String.t()) :: {non_neg_integer(), non_neg_integer()}
Parse a fractional seconds string (like ".123456" or "123456") into a
{microseconds, precision} tuple.
Convert to an Ion text representation string.
@spec to_native(t()) :: Date.t() | NaiveDateTime.t() | DateTime.t()
Convert to a native Elixir date/time type.
Returns DateTime, NaiveDateTime, or Date depending on precision and offset.
@spec to_utc(t()) :: DateTime.t()
Convert to a UTC DateTime for timeline comparison.
All timestamps are normalized to UTC. Unknown offsets are treated as UTC. Date-only timestamps are treated as midnight UTC.