# `Localize.DateTime`
[🔗](https://github.com/elixir-localize/localize/blob/v1.2.0/lib/localize/datetime.ex#L1)

Provides localized formatting of `DateTime`, `NaiveDateTime`,
and datetime-like maps.

The primary function is `to_string/2` which accepts a datetime
value and an options keyword list. Format patterns are defined
in CLDR and described in
[TR35](http://unicode.org/reports/tr35/tr35-dates.html).

## Predefined formats

* `:short` — abbreviated date and time (e.g., "1/2/25, 3:04 PM").

* `:medium` — standard date and time (default).

* `:long` — includes time zone name.

* `:full` — verbose day-of-week, date, and time zone.

Custom CLDR skeleton strings and raw format patterns are also
supported via the `:format` option.

# `to_parts`

```elixir
@spec to_parts(map(), Keyword.t()) ::
  {:ok, [%{type: atom(), value: String.t()}]} | {:error, Exception.t()}
```

Formats a datetime 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`, `:hour`, `:minute`, `:second`, `:day_period`, `:time_zone_name`, `:era`, `:fractional_second`, `:literal`, …). Standard formats, skeleton atoms, explicit pattern strings, and combined date+time wrappers all decompose.

### Arguments

* `datetime` is a `t:DateTime.t/0`, `t:NaiveDateTime.t/0`, or any map with date and time keys.

* `options` is a keyword list of options.

### Options

See `to_string/2` for the supported options.

### Returns

* `{:ok, parts}` where `parts` is a list of `%{type: atom(), value: String.t()}` maps.

* `{:error, exception}` if the datetime cannot be formatted.

### Examples

    iex> Localize.DateTime.to_parts(~N[2017-07-10 14:30:00], format: :hm, locale: :en, prefer: :ascii)
    {:ok,
     [
       %{type: :hour, value: "2"},
       %{type: :literal, value: ":"},
       %{type: :minute, value: "30"},
       %{type: :literal, value: " "},
       %{type: :day_period, value: "PM"}
     ]}

# `to_parts!`

```elixir
@spec to_parts!(map(), Keyword.t()) :: [%{type: atom(), value: String.t()}]
```

Same as `to_parts/2` but raises on error.

### Arguments

* `datetime` is a `t:DateTime.t/0`, `t:NaiveDateTime.t/0`, or any map with date and time keys.

* `options` is a keyword list of options. See `to_parts/2`.

### Returns

* A list of `%{type: atom(), value: String.t()}` maps.

### Raises

* Raises an exception if the datetime cannot be formatted.

### Examples

    iex> Localize.DateTime.to_parts!(~N[2017-07-10 14:30:00], format: :hm, locale: :en, prefer: :ascii) |> length()
    5

# `to_string`

```elixir
@spec to_string(map(), Keyword.t()) :: {:ok, String.t()} | {:error, Exception.t()}
```

Formats a datetime according to a CLDR format pattern.

### Arguments

* `datetime` is a `t:DateTime.t/0`, `t:NaiveDateTime.t/0`,
  or any map with date and time keys.

* `options` is a keyword list of options.

### Options

* `:format` is a standard format name (`:short`, `:medium`,
  `:long`, `:full`) or a format pattern string. The default
  is `:medium`. It sets the width of the date and the time
  together; `:date_format` and `:time_format` override each
  axis separately.

* `:date_format` and `:time_format` are standard format names
  that set the width of the date half and the time half
  independently, each defaulting to `:format`. Use them for
  the common "full date, short time" pairing:
  `date_format: :full, time_format: :short` renders
  "Wednesday, April 8, 2026, 12:00 PM". When `:date_format`
  is given it also selects the wrapper width.

* `:style` selects the CLDR pattern that joins the date and
  the time. `:default` (the default) uses the standard
  wrapper ("April 8, 2026, 12:00:00 PM"); `:at` uses the
  locale's "at time" wrapper ("April 8, 2026 at 12:00:00 PM",
  de "8. April 2026 um 12:00:00"). CLDR defines the "at time"
  wrapper only for `:full` and `:long`, so `:at` falls back to
  the standard wrapper for `:medium` and `:short`.

* `:locale` is a locale identifier. The default is `:en`.

* `:number_system` is 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.

* `:prefer` selects between CLDR `alt` variants. 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` (mostly time formats — NBSP and
  curly quotes vs ASCII-only). Examples: `prefer: :variant`,
  `prefer: [:variant, :ascii]`. The default is
  `[:standard, :unicode]`.

### Returns

* `{:ok, formatted_string}` on success.

* `{:error, exception}` if the datetime cannot be formatted.

### Examples

    iex> Localize.DateTime.to_string(~N[2017-07-10 14:30:00], locale: :en, prefer: :ascii)
    {:ok, "Jul 10, 2017, 2:30:00 PM"}

    iex> Localize.DateTime.to_string(~N[2017-07-10 14:30:00], format: :short, locale: :en, prefer: :ascii)
    {:ok, "7/10/17, 2:30 PM"}

# `to_string!`

```elixir
@spec to_string!(map(), Keyword.t()) :: String.t()
```

Same as `to_string/2` but raises on error.

### Arguments

* `datetime` is a `t:DateTime.t/0`, `t:NaiveDateTime.t/0`,
  or any map with date and time keys.

* `options` is a keyword list of options.

### Options

See `to_string/2` for the supported options.

### Returns

* A formatted string.

* Raises an exception if the datetime cannot be formatted.

### Examples

    iex> Localize.DateTime.to_string!(~N[2017-07-10 14:30:00], locale: :en, prefer: :ascii)
    "Jul 10, 2017, 2:30:00 PM"

    iex> Localize.DateTime.to_string!(~N[2017-07-10 14:30:00], format: :short, locale: :en, prefer: :ascii)
    "7/10/17, 2:30 PM"

---

*Consult [api-reference.md](api-reference.md) for complete listing*
