Calendrical. Date
(Calendrical v0.4.0)
Copy Markdown
Date parsing and helpers built on Calendrical's calendar implementations and Localize's CLDR data.
See Calendrical.Date.Parser for the parsing engine details.
Summary
Functions
@spec parse(String.t(), Keyword.t()) :: {:ok, Date.t()} | {:error, Exception.t()}
Parses a locale-formatted date string.
Tries, in order: bare ISO-8601 (YYYY-MM-DD), then the
locale's CLDR short/medium/long/full patterns for the
requested calendar. The patterns encode the locale's
preferred field order and any era markers — so the same
input may parse to different dates under different locales
by design.
Returns a Date.t/0. By default (with return_calendar: :iso), the result is in Calendar.ISO (Gregorian); pass
return_calendar: :native to receive the date in its input
calendar (e.g. a Calendrical.Islamic.Civil date).
Arguments
inputis the raw user input string.optionsis a keyword list of options.
Options
:locale— the locale to interpret the string under. Defaults toLocalize.get_locale/0.:calendar— the CLDR calendar key (e.g.:gregorian,:buddhist,:islamic_civil,:japanese,:persian,:hebrew). Defaults to:gregorian.:reference_date— the "today" anchor for two-digit-year pivoting. Defaults toDate.utc_today/0.:return_calendar—:iso(default) converts the result to Gregorian.:nativekeeps it in the input calendar.
Returns
{:ok, Date.t()}on success.{:error, Calendrical.DateParseError.t()}when no pattern matched.
Examples
iex> Calendrical.Date.parse("2026-05-16", locale: :en)
{:ok, ~D[2026-05-16]}
iex> Calendrical.Date.parse("5/16/26", locale: :en)
{:ok, ~D[2026-05-16]}
iex> Calendrical.Date.parse("16.05.2026", locale: :de)
{:ok, ~D[2026-05-16]}
@spec parse_range(String.t() | {String.t(), String.t()}, Keyword.t()) :: {:ok, Date.Range.t()} | {:error, Exception.t()}
Parses a locale-formatted date range.
Accepts either a single string (e.g. "May 5 – May 10, 2026")
in which case the parser splits on the locale's CLDR
intervalFormatFallback separator, or a 2-tuple
{from_string, to_string} for two-input UIs that already
have the endpoints split.
Each endpoint is parsed independently via parse/2. The
result is a Date.Range.t/0 (Gregorian).
Arguments
inputis either a binary or a{from_binary, to_binary}tuple.optionsis a keyword list of options.
Options
Same as parse/2: :locale, :calendar, :reference_date.
Plus:
:allow_inverted— whentrue, an end-before-start range is returned as-is (Elixir'sDate.range/3builds a descending range). Whenfalse(the default), an inverted range is rejected with aCalendrical.DateRangeParseError.
Returns
{:ok, Date.Range.t()}on success.{:error, Calendrical.DateParseError.t() | Calendrical.DateRangeParseError.t()}on failure.
Examples
iex> {:ok, range} = Calendrical.Date.parse_range({"2026-05-05", "2026-05-10"})
iex> {range.first, range.last}
{~D[2026-05-05], ~D[2026-05-10]}
iex> {:ok, range} = Calendrical.Date.parse_range("May 5, 2026 – May 10, 2026", locale: :en)
iex> {range.first, range.last}
{~D[2026-05-05], ~D[2026-05-10]}