Boxic.FEEL.Duration (boxic_feel v0.1.0)

Copy Markdown View Source

FEEL duration value.

FEEL defines year-month and day-time durations as distinct, generally incomparable kinds. A single elapsed-seconds value cannot represent calendar months, while Elixir's date/time APIs do not provide a value that preserves this FEEL distinction or fractional duration seconds.

The explicit kind field prevents accidental comparison or property access across the two domains. Year-month values use months; day-time values use seconds, with Decimal retained when fractional precision is present.

Summary

Functions

Returns the absolute duration.

Adds durations of the same kind.

Adds a duration to an Elixir date.

Adds a duration to an Elixir date-time.

Adds a day-time duration to an Elixir time.

Compares durations of the same kind.

Creates a day-time duration from whole days.

Creates a day-time duration from seconds.

Negates a duration.

Parses an ISO 8601 year-month or day-time duration.

Divides two durations of the same kind.

Multiplies a duration by a decimal factor.

Subtracts right from left.

Serializes a duration as ISO 8601 text.

Types

kind()

@type kind() :: :year_month | :day_time

t()

@type t() :: %Boxic.FEEL.Duration{
  kind: kind(),
  months: integer(),
  seconds: integer() | Decimal.t()
}

Functions

abs(duration)

@spec abs(t()) :: t()

Returns the absolute duration.

Boxic.FEEL.Duration.abs(duration)

add(left, right)

@spec add(t(), t()) :: t()

Adds durations of the same kind.

Boxic.FEEL.Duration.add(left, right)

add_to_date(date, duration)

@spec add_to_date(Date.t(), t()) :: Date.t()

Adds a duration to an Elixir date.

Boxic.FEEL.Duration.add_to_date(~D[2026-01-01], duration)

add_to_datetime(datetime, duration)

@spec add_to_datetime(DateTime.t(), t()) :: DateTime.t()

Adds a duration to an Elixir date-time.

Boxic.FEEL.Duration.add_to_datetime(datetime, duration)

add_to_time(time, duration)

@spec add_to_time(Time.t(), t()) :: Time.t()

Adds a day-time duration to an Elixir time.

Boxic.FEEL.Duration.add_to_time(~T[12:00:00], duration)

compare(left, right)

@spec compare(t(), t()) :: :lt | :eq | :gt | :unordered

Compares durations of the same kind.

Boxic.FEEL.Duration.compare(left, right)

from_days(days)

@spec from_days(integer()) :: t()

Creates a day-time duration from whole days.

Boxic.FEEL.Duration.from_days(2)

from_seconds(seconds)

@spec from_seconds(integer() | Decimal.t()) :: t()

Creates a day-time duration from seconds.

Boxic.FEEL.Duration.from_seconds(90)

negate(duration)

@spec negate(t()) :: t()

Negates a duration.

Boxic.FEEL.Duration.negate(duration)

parse_iso8601(value)

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

Parses an ISO 8601 year-month or day-time duration.

Boxic.FEEL.Duration.parse_iso8601("P1Y2M")

ratio(left, right)

@spec ratio(t(), t()) :: {:ok, Decimal.t()} | :error

Divides two durations of the same kind.

Boxic.FEEL.Duration.ratio(left, right)

scale(duration, factor)

@spec scale(t(), Decimal.t()) :: t()

Multiplies a duration by a decimal factor.

Boxic.FEEL.Duration.scale(duration, Decimal.new("1.5"))

subtract(left, right)

@spec subtract(t(), t()) :: t()

Subtracts right from left.

Boxic.FEEL.Duration.subtract(left, right)

to_string(duration)

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

Serializes a duration as ISO 8601 text.

Boxic.FEEL.Duration.to_string(duration)