# `Cldr.DateTime`
[🔗](https://github.com/elixir-cldr/cldr_dates_times/blob/v2.25.6/lib/cldr/date_time.ex#L1)

Provides localized formatting of full or partial date_times.

A date_time is any `t:DateTime.t/0` or `t:NaiveDateTime.t/0`
struct or any map that contains one or more of the keys `:year`, `:month`, `:day`,
`:hour`, `:minute` and `:second` or `:microsecond` with optional `:time_zone`, `:zone_abbr`,
`:utc_offset`, `:std_offset` and `:calendar` fields.

`Cldr.DateTime` provides support for the built-in calendar
`Calendar.ISO` or any calendars defined with
[ex_cldr_calendars](https://hex.pm/packages/ex_cldr_calendars)

For information about specifying formats, see `Cldr.DateTime.Format`.

# `available_formats`

```elixir
@spec available_formats(
  Cldr.Locale.locale_reference(),
  Cldr.Calendar.calendar(),
  Cldr.backend()
) :: {:ok, map()} | {:error, {atom(), String.t()}}
```

Returns a map of the available date_time formats for a
given locale and calendar.

## Arguments

* `locale` is any locale returned by `Cldr.known_locale_names/0`
  or a `t:Cldr.LanguageTag.t/0`. The default is `Cldr.get_locale/0`.

* `calendar` is any calendar returned by `Cldr.DateTime.Format.calendars_for/1`
  The default is `:gregorian`.

* `backend` is any module that includes `use Cldr` and therefore
  is a `Cldr` backend module. The default is `Cldr.default_backend/0`.

## Examples:

    iex> Cldr.DateTime.available_formats(:en)
    {:ok,
     %{
       MMMMW: %{
         other: "'week' W 'of' MMMM",
         one: "'week' W 'of' MMMM",
         pluralize: :week_of_month
       },
       Ehm: %{unicode: "E h:mm a", ascii: "E h:mm a"},
       y: "y",
       MMMd: "MMM d",
       yyMd: "M/d/yy",
       GyM: "M/y G",
       hv: %{unicode: "h a v", ascii: "h a v"},
       Hm: "HH:mm",
       Bhms: "h:mm:ss B",
       ms: "mm:ss",
       yMd: "M/d/y",
       GyMMM: "MMM y G",
       GyMMMEd: "E, MMM d, y G",
       yMMMd: "MMM d, y",
       EBh: "E h B",
       Gy: "y G",
       Hmsv: "HH:mm:ss v",
       hmv: %{unicode: "h:mm a v", ascii: "h:mm a v"},
       M: "L",
       h: %{unicode: "h a", ascii: "h a"},
       Hms: "HH:mm:ss",
       yMMMMd: "MMMM d, y",
       EHm: "E HH:mm",
       ahmmsszzzz: %{unicode: "h:mm:ss a zzzz", ascii: "h:mm:ss a zzzz"},
       MMM: "LLL",
       ahmmssz: %{unicode: "h:mm:ss a z", ascii: "h:mm:ss a z"},
       d: "d",
       Hmv: "HH:mm v",
       GyMd: "M/d/y G",
       yQQQ: "QQQ y",
       yMMMEd: "E, MMM d, y",
       ahmmss: %{unicode: "h:mm:ss a", ascii: "h:mm:ss a"},
       MMMMd: "MMMM d",
       H: "HH",
       MEd: "E, M/d",
       Md: "M/d",
       GyMEd: "E, M/d/y G",
       yMMM: "MMM y",
       EBhms: "E h:mm:ss B",
       yw: %{
         other: "'week' w 'of' Y",
         one: "'week' w 'of' Y",
         pluralize: :week_of_year
       },
       hmsv: %{unicode: "h:mm:ss a v", ascii: "h:mm:ss a v"},
       MMMEd: "E, MMM d",
       hms: %{unicode: "h:mm:ss a", ascii: "h:mm:ss a"},
       EBhm: "E h:mm B",
       EHms: "E HH:mm:ss",
       Hv: "HH'h' v",
       ahmm: %{unicode: "h:mm a", ascii: "h:mm a"},
       hm: %{unicode: "h:mm a", ascii: "h:mm a"},
       GyMMMd: "MMM d, y G",
       yMEd: "E, M/d/y",
       Eh: %{unicode: "E h a", ascii: "E h a"},
       Bh: "h B",
       Ehms: %{unicode: "E h:mm:ss a", ascii: "E h:mm:ss a"},
       yMMMM: "MMMM y",
       yQQQQ: "QQQQ y",
       yMMMMEEEEd: "EEEE, MMMM d, y",
       E: "ccc",
       yM: "M/y",
       Bhm: "h:mm B",
       Ed: "d E"
     }}

# `formats`

```elixir
@spec formats(
  Cldr.Locale.locale_reference(),
  Cldr.Calendar.calendar(),
  Cldr.backend()
) :: {:ok, map()} | {:error, {atom(), String.t()}}
```

Returns a map of the standard date_time formats for a given locale and calendar.

## Arguments

* `locale` is any locale returned by `Cldr.known_locale_names/0`
  or a `t:Cldr.LanguageTag.t/0`. The default is `Cldr.get_locale/0`.

* `calendar` is any calendar returned by `Cldr.DateTime.Format.calendars_for/1`
  The default is `:gregorian`.

* `backend` is any module that includes `use Cldr` and therefore
  is a `Cldr` backend module. The default is `Cldr.default_backend/0`.

## Examples:

    iex> Cldr.DateTime.Format.date_time_formats(:en)
    {:ok,
     %Cldr.DateTime.Formats{
       short: "{1}, {0}",
       medium: "{1}, {0}",
       long: "{1}, {0}",
       full: "{1}, {0}"
     }}

    iex> Cldr.DateTime.Format.date_time_formats(:en, :buddhist, MyApp.Cldr)
    {:ok,
     %Cldr.DateTime.Formats{
       short: "{1}, {0}",
       medium: "{1}, {0}",
       long: "{1}, {0}",
       full: "{1}, {0}"
     }}

# `has_date`
*macro* 

Guards whether the given date_time has components of
a date.

# `has_date_and_time`
*macro* 

Guard whether the given date_time has components of
both a date and a time.

# `has_time`
*macro* 

Guards whether the given date_time has components of
a time.

# `is_any_date_time`
*macro* 

Indicates if a given map fulfills the requirements
for a naive date time or date time.

# `is_date_time`
*macro* 

Indicates if a given map fulfills the requirements
for a date time.

# `is_naive_date_time`
*macro* 

Indicates if a given map fulfills the requirements
for a naive date time.

# `is_skeleton`
*macro* 

Guard whether a format is a format skeleton

# `to_string`

```elixir
@spec to_string(Cldr.Calendar.any_date_time(), Cldr.backend(), options()) ::
  {:ok, String.t()} | {:error, {module(), String.t()}}
@spec to_string(Cldr.Calendar.any_date_time(), options(), []) ::
  {:ok, String.t()} | {:error, {module(), String.t()}}
```

Formats a `t:DateTime.t/0` or `t:NaiveDateTime.t/0` according to the formats
defined in CLDR and described in [TR35](http://unicode.org/reports/tr35/tr35-dates.html).

### Arguments

* `date_time` is a `t:DateTime.t/0` or `t:NaiveDateTime.t/0` struct or any map that contains
  one or more of the keys `:year`, `:month`, `:day`, `:hour`, `:minute` and `:second` or
  `:microsecond` with optional `:time_zone`, `:zone_abbr`, `:utc_offset`, `:std_offset`
  and `:calendar` fields.

* `backend` is any module that includes `use Cldr` and therefore
  is a `Cldr` backend module. The default is `Cldr.default_backend!/0`.

* `options` is a keyword list of options for formatting.

## Options

* `:format` is either a [standard format](Cldr.DateTime.Format.html#module-standard-formats)
  (one of `:short`, `:medium`, `:long`, `:full`), a [format skeleton](Cldr.DateTime.Format.html#module-format-skeletons)
  or a [format pattern](Cldr.DateTime.Format.html#module-format-patterns).

  * The default is `:medium` for full *date_times* (that is, *dates_times* having `:year`,
    `:month`, `:day`, `:hour`, `:minutes`, `:second` and `:calendar` fields).

  * The default for partial *date_times* is to derive a format skeleton from the
    *date_time* and find the best match from the formats returned by
    `Cldr.DateTime.available_formats/3`.

  * See `Cldr.DateTime.Format` for more information about specifying formats.

* `:date_format` is used to format the *date* part of a *date_time* and is either a standard
  format or a format skeleton.

  * If `:date_format` is not specified then the *date* format is defined by the `:format`
    option.

  * If `:date_format` is a format skeleton it may only include format fields
    appropriate for a *date*.

  * :date_format` may only be specified if `:format` is a standard format.

* `:time_format` is used to format the *time* part of a *date_time* and is either a standard
  format or a format skeleton.

  * If `:time_format` is not specified then the *time* format is defined by the `:format`
    option.

  * If `:time_format` is a format skeleton it may only include format fields
    appropriate for a *time*.

  * :time_format` may only be specified if `:format` is a standard format.

* `:style` is either `:at` or `:default`. When set to `:at` the *date_time* may
  be formatted with a localised string representing `<date> at <time>` if such
  a format exists. See `Cldr.DateTime.Format.date_time_at_formats/2`.

* `:prefer` is either `:unicode` (the default) or `:ascii`. A small number of
  formats have two variants - one using Unicode spaces (typically non-breaking space) and
  another using only ASCII whitespace. The `:ascii` format is primarily to support legacy
  use cases and is not recommended. See `Cldr.DateTime.available_formats/3`
  to see which formats have these variants. See [Variant Preference](#variant-preference)
  below for more information.

* `:locale` is any valid locale name returned by `Cldr.known_locale_names/0`
  or a `t:Cldr.LanguageTag.t/0` struct.  The default is `Cldr.get_locale/0`.

* `:number_system` a number system into which the formatted *date_time* digits should
  be transliterated. See `Cldr.known_number_systems/0`. The default is
  the number system associated with the `:locale`.

* `:separators` selects which of the available symbol
  sets should be used when formatting fractional seconds (format
  character `S`).  The default is `:standard`. Some limited locales have an alternative `:us`
  variant that can be used. See `Cldr.Number.Symbol.number_symbols_for/3`
  for the symbols supported for a given locale and number system.

* `:era` which, if set to `:variant`, will use a variant for the era if one
  is available in the requested locale. In the `:en` locale, for example, `era: :variant`
  will return `CE` instead of `AD` and `BCE` instead of `BC`.

* `:period` which, if set to `:variant`, will use a variant for the time period and flexible
  time period if one is available in the locale.  For example, in the `:en` locale
  `period: :variant` will return "pm" instead of "PM".

### Variant Preference

* A small number of formats have one of two different alternatives, each with their own
  preference specifier. The preferences are specified with the `:prefer` option to
  `Cldr.Date.to_string/3`. The preference is expressed as an atom, or a list of one or two
  atoms with one atom being either `:unicode` or `:ascii` and one atom being either
  `:default` or `:variant`.

  * Some formats (at the time of publishng only *time* formats but that
    may change in the future) have `:unicode` and `:ascii` versions of the format. The
    difference is the use of ascii space (0x20) as a separateor in the `:ascii` verison
    whereas the `:unicode` version may use non-breaking or other space characters. The
    default is `:unicode` and this is the strongly preferred option. The `:ascii` format
    is primarily to support legacy use cases and is not recommended. See
    `Cldr.Time.available_formats/3` to see which formats have these variants.

  * Some formats (at the time of publishing, only *date* and *date_time* formats) have
    `:default` and `:variant` versions of the format. These variant formats are only
    included in a small number of locales. For example, the `:"en-CA"` locale, which has
    a `:default` format respecting typical Canadian formatting and a `:variant` that is
    more closely aligned to US formatting. The default is `:default`.

### Notes

* If the provided `date_time` contains only *date* fields, the call is delegated to
  `Cldr.Date.to_string/2`.

* If the provided `date_time` contains only *time* fields, the call is delegated to
  `Cldr.Time.to_string/2`.

### Returns

* `{:ok, formatted_date_time}` or

* `{:error, reason}`

### Examples

    iex> {:ok, date_time} = DateTime.from_naive(~N[2000-01-01 23:59:59.0], "Etc/UTC")
    iex> Cldr.DateTime.to_string(date_time)
    {:ok, "Jan 1, 2000, 11:59:59 PM"}
    iex> Cldr.DateTime.to_string(date_time, MyApp.Cldr, locale: :en)
    {:ok, "Jan 1, 2000, 11:59:59 PM"}
    iex> Cldr.DateTime.to_string(date_time, MyApp.Cldr, format: :long, locale: :en)
    {:ok, "January 1, 2000, 11:59:59 PM UTC"}
    iex> Cldr.DateTime.to_string(date_time, MyApp.Cldr, format: :hms, locale: :en)
    {:ok, "11:59:59 PM"}
    iex> Cldr.DateTime.to_string(date_time, MyApp.Cldr, format: :full, locale: :en)
    {:ok, "Saturday, January 1, 2000, 11:59:59 PM Coordinated Universal Time"}
    iex> Cldr.DateTime.to_string(date_time, MyApp.Cldr, format: :full, locale: :fr)
    {:ok, "samedi 1 janvier 2000, 23:59:59 temps universel coordonné"}
    iex> Cldr.DateTime.to_string(date_time, MyApp.Cldr, format: :full, style: :at, locale: :en)
    {:ok, "Saturday, January 1, 2000 at 11:59:59 PM Coordinated Universal Time"}
    iex> Cldr.DateTime.to_string(date_time, MyApp.Cldr, format: :full, style: :at, locale: :fr)
    {:ok, "samedi 1 janvier 2000 à 23:59:59 temps universel coordonné"}
    iex> Cldr.DateTime.to_string(date_time, MyApp.Cldr, format: :MMMMW, locale: :fr)
    {:ok, "semaine 1 (janvier)"}
    iex> Cldr.DateTime.to_string(date_time, MyApp.Cldr, format: :yw, locale: :fr)
    {:ok, "semaine 1 de 2000"}
    iex> Cldr.DateTime.to_string(date_time, MyApp.Cldr, format: :full, date_format: :yMd, time_format: :hms)
    {:ok, "1/1/2000, 11:59:59 PM"}

# `to_string!`

```elixir
@spec to_string!(Cldr.Calendar.any_date_time(), Cldr.backend(), options()) ::
  String.t() | no_return()
@spec to_string!(Cldr.Calendar.any_date_time(), options(), []) ::
  String.t() | no_return()
```

Formats a `t:DateTime.t/0` or `t:NaiveDateTime.t/0` according to the formats
defined in CLDR and described in [TR35](http://unicode.org/reports/tr35/tr35-dates.html)
or raises on error.

### Arguments

* `date_time` is a `t:DateTime.t/0` or `t:NaiveDateTime.t/0` struct or any map that contains
  one or more of the keys `:year`, `:month`, `:day`, `:hour`, `:minute` and `:second` or
  `:microsecond` with optional `:time_zone`, `:zone_abbr`, `:utc_offset`, `:std_offset`
  and `:calendar` fields.

* `backend` is any module that includes `use Cldr` and therefore
  is a `Cldr` backend module. The default is `Cldr.default_backend!/0`.

* `options` is a keyword list of options for formatting.

## Options

* `:format` is either a [standard format](Cldr.DateTime.Format.html#module-standard-formats)
  (one of `:short`, `:medium`, `:long`, `:full`), a [format skeleton](Cldr.DateTime.Format.html#module-format-skeletons)
  or a [format pattern](Cldr.DateTime.Format.html#module-format-patterns).

  * The default is `:medium` for full *date_times* (that is, *dates_times* having `:year`,
    `:month`, `:day`, `:hour`, `:minutes`, `:second` and `:calendar` fields).

  * The default for partial *date_times* is to derive a format skeleton from the
    *date_time* and find the best match from the formats returned by
    `Cldr.DateTime.available_formats/3`.

  * See `Cldr.DateTime.Format` for more information about specifying formats.

* `:date_format` is used to format the *date* part of a *date_time* and is either a standard
  format or a format skeleton.

  * If `:date_format` is not specified then the *date* format is defined by the `:format`
    option.

  * If `:date_format` is a format skeleton it may only include format fields
    appropriate for a *date*.

  * :date_format` may only be specified if `:format` is a standard format.

* `:time_format` is used to format the *time* part of a *date_time* and is either a standard
  format or a format skeleton.

  * If `:time_format` is not specified then the *time* format is defined by the `:format`
    option.

  * If `:time_format` is a format skeleton it may only include format fields
    appropriate for a *time*.

  * :time_format` may only be specified if `:format` is a standard format.

* `:style` is either `:at` or `:default`. When set to `:at` the *date_time* may
  be formatted with a localised string representing `<date> at <time>` if such
  a format exists. See `Cldr.DateTime.Format.date_time_at_formats/2`.

* `:prefer` is either `:unicode` (the default) or `:ascii`. A small number of
  formats have two variants - one using Unicode spaces (typically non-breaking space) and
  another using only ASCII whitespace. The `:ascii` format is primarily to support legacy
  use cases and is not recommended. See `Cldr.DateTime.available_formats/3`
  to see which formats have these variants. See [Variant Preference](#variant-preference)
  below for more information.

* `:locale` is any valid locale name returned by `Cldr.known_locale_names/0`
  or a `t:Cldr.LanguageTag.t/0` struct.  The default is `Cldr.get_locale/0`.

* `:number_system` a number system into which the formatted *date_time* digits should
  be transliterated. See `Cldr.known_number_systems/0`. The default is
  the number system associated with the `:locale`.

* `:separators` selects which of the available symbol
  sets should be used when formatting fractional seconds (format
  character `S`).  The default is `:standard`. Some limited locales have an alternative `:us`
  variant that can be used. See `Cldr.Number.Symbol.number_symbols_for/3`
  for the symbols supported for a given locale and number system.

* `:era` which, if set to `:variant`, will use a variant for the era if one
  is available in the requested locale. In the `:en` locale, for example, `era: :variant`
  will return `CE` instead of `AD` and `BCE` instead of `BC`.

* `:period` which, if set to `:variant`, will use a variant for the time period and flexible
  time period if one is available in the locale.  For example, in the `:en` locale
  `period: :variant` will return "pm" instead of "PM".

### Variant Preference

* A small number of formats have one of two different alternatives, each with their own
  preference specifier. The preferences are specified with the `:prefer` option to
  `Cldr.Date.to_string/3`. The preference is expressed as an atom, or a list of one or two
  atoms with one atom being either `:unicode` or `:ascii` and one atom being either
  `:default` or `:variant`.

  * Some formats (at the time of publishng only *time* formats but that
    may change in the future) have `:unicode` and `:ascii` versions of the format. The
    difference is the use of ascii space (0x20) as a separateor in the `:ascii` verison
    whereas the `:unicode` version may use non-breaking or other space characters. The
    default is `:unicode` and this is the strongly preferred option. The `:ascii` format
    is primarily to support legacy use cases and is not recommended. See
    `Cldr.Time.available_formats/3` to see which formats have these variants.

  * Some formats (at the time of publishing, only *date* and *date_time* formats) have
    `:default` and `:variant` versions of the format. These variant formats are only
    included in a small number of locales. For example, the `:"en-CA"` locale, which has
    a `:default` format respecting typical Canadian formatting and a `:variant` that is
    more closely aligned to US formatting. The default is `:default`.

### Notes

* If the provided `date_time` contains only *date* fields, the call is delegated to
  `Cldr.Date.to_string/2`.

* If the provided `date_time` contains only *time* fields, the call is delegated to
  `Cldr.Time.to_string/2`.

### Returns

* `formatted_date_time` or

* raises an exception.

### Examples

    iex> {:ok, date_time} = DateTime.from_naive(~N[2000-01-01 23:59:59.0], "Etc/UTC")
    iex> Cldr.DateTime.to_string!(date_time, MyApp.Cldr, locale: :en)
    "Jan 1, 2000, 11:59:59 PM"
    iex> Cldr.DateTime.to_string!(date_time, MyApp.Cldr, format: :long, locale: :en)
    "January 1, 2000, 11:59:59 PM UTC"
    iex> Cldr.DateTime.to_string!(date_time, MyApp.Cldr, format: :full, locale: :en)
    "Saturday, January 1, 2000, 11:59:59 PM Coordinated Universal Time"
    iex> Cldr.DateTime.to_string!(date_time, MyApp.Cldr, format: :full, locale: :fr)
    "samedi 1 janvier 2000, 23:59:59 temps universel coordonné"
    iex> Cldr.DateTime.to_string!(date_time, MyApp.Cldr, format: :MMMMW, locale: :fr)
    "semaine 1 (janvier)"
    iex> Cldr.DateTime.to_string!(date_time, MyApp.Cldr, format: :yw, locale: :fr)
    "semaine 1 de 2000"
    iex> Cldr.DateTime.to_string!(date_time, MyApp.Cldr, format: :full, date_format: :yMd, time_format: :hms)
    "1/1/2000, 11:59:59 PM"

---

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