Provides localized formatting of Date structs and date-like maps.
Supports both full dates (%{year: _, month: _, day: _}) and partial
dates (any map with one or more of :year, :month, :day). For a
partial date a standard format, or no format, derives the skeleton from
the fields present; a skeleton or pattern that asks for a field the date
does not have returns Localize.DateTimeInvalidInputError.
Formats are defined in CLDR and described in TR35.
Ordinal days are a technical preview
CLDR 49 adds the ddd field, which formats the day as a date ordinal
taken from the locale's dayOfMonths data — :yMMMddd renders
"Jul 6th, 2024" in en and "1er juil. 2024" in fr. A locale without
that data, and any pattern whose month is numeric, format the plain day.
TR35 designates the dayOfMonth section a technical preview, and the
element shape was narrowed once during CLDR 49's development. Only the
abbreviated width and the ordinal-keyed forms are read, and
Localize.Interval cannot yet request an ordinal skeleton. Treat both
the output and the surface as subject to change.
Summary
Functions
Parses a localized date string.
Formats a date into typed parts, mirroring ECMA-402's formatToParts.
Same as to_parts/2 but raises on error.
Formats a date according to a CLDR format pattern.
Same as to_string/2 but raises on error.
Functions
@spec parse(String.t(), Keyword.t()) :: {:ok, Date.t()} | {:error, Exception.t()}
Parses a localized date string.
Accepts any shape the locale accepts, including the locale's CLDR short, medium, long and full patterns and ISO 8601.
A date in another calendar is parsed by passing that calendar's module
as :calendar; the companion
calendrical package supplies the
calendars Localize formats for.
Arguments
stringis a string in any shape the locale accepts, including the locale's CLDR short, medium, long and full patterns and ISO 8601.optionsis a keyword list of options.
Options
:localeis a locale identifier. The default is the locale returned byLocalize.get_locale/0.:calendaris a calendar module, such asCalendar.ISO(the default),Calendrical.GregorianorCalendrical.Hebrew. The input is read with the locale's patterns for the calendar's CLDR type, and the date is built and returned in this module. A week date, in any form ISO 8601 writes one in ("2024-W05-4","2024W054"and the week alone,"2024-W05"), is the calendar's own: every calendar answersdate_from_week_date/3, so it is ISO 8601's week forCalendar.ISOand the fifth week of its own year for a calendar built of weeks. Text that none of the calendar's own formats reads is read in the calendar itsinfo/0names as:parsing_calendar, and converted: a calendar built of weeks, whose months are"M02"and not"Feb", namesCalendar.ISO, so"Feb 1, 2024"is 1 February 2024 in it. A composite calendar, whose dates are written with the formats of whichever of its calendars was in effect, names those calendars with itsparsing_calendars/0, and a date is then read in each and converted, held to the calendar its day is written in. A calendar's own formats come before ISO 8601: a year, a month and a day between hyphens that any of them reads, as CLDR's root short date of the Chinese calendar does (r-MM-dd), is the calendar's own date, and where none does it is an ISO 8601 date, converted into the calendar. Anything that is not a calendar module, including a CLDR calendar name such as:hebrewor"gregorian", and a module that implements only theCalendarbehaviour, returns aLocalize.UnknownCalendarError.t/0.:formatis the format the text was written with, asto_string/2takes it: a standard format (:short,:medium,:longor:full), a skeleton atom such as:yMd, aLocalize.DateTime.SemanticSkeletonor a pattern string such as"d/M/y". The text is read with that format and no other, after the calendar's own notation, so a date written by a skeleton whose fields stand in another order than the locale's standard formats' reads back as itself:mt's:yMdwrites 3 April 2024 as "4/3/2024", which is 4 March where no format is given. A pattern string is read before the notation, which is never what it writes, and the notation where the pattern reads nothing. A format of fewer fields than a date has, such as:yMMM, needsas: :map. The default isnil: the text is read in whichever of the locale's formats reads it first.:reference_dateis theDate.t/0that partial input is completed against, taken in the calendar the input is read in. A week written without its year is a week of the reference date's week-based year, which is not the year of its days about the new year. The default is today.:asis:structor:map.:mapreturns only the fields the input actually carried, rather than completing them. They must still be fields some date has, so"June 31"is an error in both forms while"February 29"is a partial date. A date read in another calendar and converted, as a composite calendar reads one of an earlier calendar, comes back whole, as a partial date has no fields in the other calendar. What names no day to convert is the exception: a year is%{year: 2026}, and a year and a quarter are the two. The default is:struct.
Returns
{:ok, value}wherevalueis aDate.t/0, or{:error, exception}if the string does not parse, aLocalize.DateTimeFormatErroror aLocalize.DateTimeUnresolvedFormatErrorif:formatis no format of a date, or aLocalize.InvalidValueError.t/0ifstringis not a string or an option is malformed.
Examples
iex> Localize.Date.parse("22.03.2026", locale: :de)
{:ok, ~D[2026-03-22]}
iex> Localize.Date.parse("March 22, 2026", locale: :en)
{:ok, ~D[2026-03-22]}
iex> Localize.Date.parse("4/3/2024", locale: :en)
{:ok, ~D[2024-04-03]}
iex> Localize.Date.parse("4/3/2024", locale: :en, format: "d/M/y")
{:ok, ~D[2024-03-04]}
@spec to_parts(map(), Keyword.t()) :: {:ok, [%{type: atom(), value: String.t()}]} | {:error, Exception.t()}
Formats a date into typed parts, mirroring ECMA-402's formatToParts.
The parts concatenate to exactly the string to_string/2 produces with the same options. Each pattern field is tagged with its type: :year, :month, :day, :weekday, :era, and :literal for separators.
Arguments
dateis aDate.t/0or any map with date keys.optionsis a keyword list of options.
Options
See to_string/2 for the supported options.
Returns
{:ok, parts}wherepartsis a list of%{type: atom(), value: String.t()}maps.{:error, exception}if the date cannot be formatted.
Examples
iex> Localize.Date.to_parts(~D[2017-07-10], locale: :en)
{:ok,
[
%{type: :month, value: "Jul"},
%{type: :literal, value: " "},
%{type: :day, value: "10"},
%{type: :literal, value: ", "},
%{type: :year, value: "2017"}
]}
Same as to_parts/2 but raises on error.
Arguments
dateis aDate.t/0or any map with date keys.optionsis a keyword list of options. Seeto_parts/2.
Returns
- A list of
%{type: atom(), value: String.t()}maps.
Raises
- Raises an exception if the date cannot be formatted.
Examples
iex> Localize.Date.to_parts!(~D[2017-07-10], locale: :en) |> length()
5
@spec to_string(map(), Keyword.t()) :: {:ok, String.t()} | {:error, Exception.t()}
Formats a date according to a CLDR format pattern.
Arguments
dateis aDate.t/0or any map with one or more of:year,:month,:daykeys.optionsis a keyword list of options.
Options
:formatis a standard format name (:short,:medium,:long,:full), a format skeleton atom, aLocalize.DateTime.SemanticSkeletonor a format pattern string. The default is:medium. For a partial date a standard format derives its skeleton from the fields present, with the month numeric at:short, abbreviated at:mediumand wide at:longand:full. Every calendar's date is written from its year, its month and its day: a calendar built of weeks, such asCalendrical.ISOWeek, has the months of its pattern of weeks, named as CLDR's generic calendar names them ("M06 16, 2026 AD"), and its week is written by a format that names one (:yw,"week 25 of 2026").:localeis a locale identifier. The default is:en.:number_systemis a CLDR numbering system name (for example,:thai). All numeric fields render in that system; a-u-nu-locale extension may be used instead. The default is the locale's number system.:numeric_date_separatoris a string replacing the locale'snumericDateSeparatorwherever it separates the fields of a numeric-month date, as TR35 allows an implementation to offer.Localize.DateTime.numeric_separators/2returns the locale's own. The default is the locale's separator.:numeric_time_separatoris a string replacing the locale'snumericTimeSeparatorwherever it separates time fields. The default is the locale's separator.:preferselects between CLDRaltvariants. Accepts an atom or a list of atoms in priority order. Recognised values::standard/:variant(locales like en-CA publish both an ISO pattern"y-MM-dd"and a locale-variant"d/M/yy"), and:unicode/:ascii(NBSP and curly quotes vs ASCII). Examples:prefer: :variant,prefer: [:variant, :ascii]. The default is[:standard, :unicode].
Returns
{:ok, formatted_string}on success.{:error, exception}if the date cannot be formatted.
Examples
iex> Localize.Date.to_string(~D[2017-07-10], locale: :en)
{:ok, "Jul 10, 2017"}
iex> Localize.Date.to_string(~D[2017-07-10], format: :full, locale: :en)
{:ok, "Monday, July 10, 2017"}
iex> Localize.Date.to_string(~D[2017-07-10], format: :short, locale: :en)
{:ok, "7/10/17"}
iex> Localize.Date.to_string(~D[2017-07-10], format: :short, locale: :fr)
{:ok, "10/07/2017"}
iex> Localize.Date.to_string(%{year: 2024, month: 6}, format: :yMMM, locale: :fr)
{:ok, "juin 2024"}
iex> Localize.Date.to_string(%{year: 2024, month: 6}, format: :long, locale: :en)
{:ok, "June 2024"}
Same as to_string/2 but raises on error.
Arguments
dateis aDate.t/0or any map with one or more of:year,:month,:daykeys.optionsis a keyword list of options.
Options
See to_string/2 for the supported options.
Returns
A formatted string.
Raises an exception if the date cannot be formatted.
Examples
iex> Localize.Date.to_string!(~D[2017-07-10], locale: :en)
"Jul 10, 2017"
iex> Localize.Date.to_string!(%{year: 2024, month: 6}, format: :yMMM, locale: :fr)
"juin 2024"