Lossless FEEL date-time composed of an Elixir Date and a FEEL time.
We retain Elixir's Date because its proleptic ISO calendar supports FEEL's
signed year range through ±999,999,999. We do not use Elixir DateTime or
NaiveDateTime for the complete value because they inherit microsecond time
precision, and DateTime depends on a timezone database while normalizing
values around an instant.
FEEL also needs the original temporal form: floating versus offset-based
versus IANA-zoned values can affect equality, ordering, properties, and
serialization. Composing Date with Boxic.FEEL.Time preserves that
information and allows instant normalization to remain an explicit semantic
operation instead of losing source precision or zone identity at parse time.
Summary
Functions
Adds a year-month or day-time duration.
Compares compatible FEEL date-times.
Calculates left - right when both values share a comparable timeline.
Converts a zoned FEEL date-time to seconds on a common timeline.
Combines a date and FEEL time without discarding zone identity.
Parses a FEEL date-time.
Serializes a FEEL date-time.
Types
@type t() :: %Boxic.FEEL.DateTime{date: Date.t(), time: Boxic.FEEL.Time.t()}
Functions
@spec add_duration(t(), Boxic.FEEL.Duration.t()) :: {:ok, t()} | :error
Adds a year-month or day-time duration.
Boxic.FEEL.DateTime.add_duration(value, duration)
Compares compatible FEEL date-times.
Boxic.FEEL.DateTime.compare(left, right)
@spec difference(t(), t()) :: {:ok, Boxic.FEEL.Duration.t()} | :error
Calculates left - right when both values share a comparable timeline.
Boxic.FEEL.DateTime.difference(left, right)
Converts a zoned FEEL date-time to seconds on a common timeline.
Boxic.FEEL.DateTime.instant_seconds(value)
@spec new(Date.t(), Boxic.FEEL.Time.t()) :: t()
Combines a date and FEEL time without discarding zone identity.
Boxic.FEEL.DateTime.new(~D[2026-01-01], time)
Parses a FEEL date-time.
Boxic.FEEL.DateTime.parse("2026-01-01T12:30:00Z")
Serializes a FEEL date-time.
Boxic.FEEL.DateTime.to_string(value)