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

Interval formats allow for software to format intervals like "Jan 10-12, 2008" as a
shorter and more natural format than "Jan 10, 2008 - Jan 12, 2008". They are designed
to take a start and end date, time or datetime plus a formatting pattern
and use that information to produce a localized format.

See `Cldr.Interval.to_string/3` and `Cldr.Date.Interval.to_string/3`.

# `greatest_difference`

Returns the format code representing the date or
time unit that is the greatest difference between
two dates.

## Arguments

* `from` is any `t:Date.t/0`.

* `to` is any `t:Date.t/0`.

## Returns

* `{:ok, format_code}` where `format_code` is one of

  * `:y` meaning that the greatest difference is in the year
  * `:M` meaning that the greatest difference is in the month
  * `:d` meaning that the greatest difference is in the day

* `{:error, :no_practical_difference}`

## Example

    iex> Cldr.Date.Interval.greatest_difference(~D[2022-04-22], ~D[2022-04-23])
    {:ok, :d}

    iex> Cldr.Date.Interval.greatest_difference(~D[2022-04-22], ~D[2022-04-22])
    {:error, :no_practical_difference}

# `to_string`

```elixir
@spec to_string(Cldr.Interval.range(), Cldr.backend(), Keyword.t()) ::
  {:ok, String.t()} | {:error, {module(), String.t()}}
```

Returns a `t:Date.Range.t/0` or `t:CalendarInterval.t/0` as
a localised string.

## Arguments

* `range` is either a `t:Date.Range.t/0` returned from `Date.range/2`
  or a `CalendarInterval.t`

* `backend` is any module that includes `use Cldr` and
  is therefore a `Cldr` backend module.

* `options` is a keyword list of options. The default is
  `[format: :medium, style: :date]`.

## Options

* `:format` is one of `:short`, `:medium` or `:long` or a
  format skeleton or a format pattern representating an interval
  format. The default is `:medium`.

* `:style` supports different formatting styles. The
  alternatives are `:date`, `:month_and_day`, `:month`
  and `:year_and_month`. The default is `:date`.

* `: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 digits should
  be transliterated.

* `:prefer` expresses the preference for one of the possible alternative
  sub-formats. See the variant preference notes below.

### 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.Date.available_formats/3` to see which formats have these variants.

  * Some formats (at the time of publishing, only date and datetime 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`.

## Returns

* `{:ok, string}` or

* `{:error, {exception, reason}}`

## Notes

* `t:CalendarInterval.t/0` support requires adding the
  dependency [calendar_interval](https://hex.pm/packages/calendar_interval)
  to the `deps` configuration in `mix.exs`.

* For more information on interval format string
  see the `Cldr.Interval`.

* The available predefined formats that can be applied are the
  keys of the map returned by `Cldr.DateTime.Format.interval_formats(:en, :gregorian)`
  where `"en"` can be replaced by any configured locale name and `:gregorian`
  is the underlying CLDR calendar type.

* In the case where `from` and `to` are equal, a single
  date is formatted instead of an interval.

## Examples

    iex> Cldr.Date.Interval.to_string(Date.range(~D[2020-01-01], ~D[2020-12-31]), MyApp.Cldr)
    {:ok, "Jan 1 – Dec 31, 2020"}

    iex> Cldr.Date.Interval.to_string(Date.range(~D[2020-01-01], ~D[2020-01-12]), MyApp.Cldr)
    {:ok, "Jan 1 – 12, 2020"}

    iex> Cldr.Date.Interval.to_string(Date.range(~D[2020-01-01], ~D[2020-01-12]), MyApp.Cldr,
    ...> format: :long)
    {:ok, "Wed, Jan 1 – Sun, Jan 12, 2020"}

    iex> Cldr.Date.Interval.to_string(Date.range(~D[2020-01-01], ~D[2020-12-01]), MyApp.Cldr,
    ...> format: :long, style: :year_and_month)
    {:ok, "January – December 2020"}

    iex> use CalendarInterval
    iex> Cldr.Date.Interval.to_string(~I"2020-01/12", MyApp.Cldr)
    {:ok, "Jan 1 – Dec 31, 2020"}

    iex> Cldr.Date.Interval.to_string(Date.range(~D[2020-01-01], ~D[2020-01-12]), MyApp.Cldr,
    ...> format: :short)
    {:ok, "1/1/2020 – 1/12/2020"}

    iex> Cldr.Date.Interval.to_string(Date.range(~D[2020-01-01], ~D[2020-01-12]), MyApp.Cldr,
    ...> format: :long, locale: "fr")
    {:ok, "mer. 1 – dim. 12 janv. 2020"}

# `to_string`

```elixir
@spec to_string(
  Calendar.date() | nil,
  Calendar.date() | nil,
  Cldr.backend(),
  Keyword.t()
) ::
  {:ok, String.t()} | {:error, {module(), String.t()}}
```

Returns a localised string representing the formatted
interval formed by two dates.

### Arguments

* `from` is any map that conforms to the
  `Calendar.date` type.

* `to` is any map that conforms to the
  `Calendar.date` type. `to` must occur
  on or after `from`.

* `backend` is any module that includes `use Cldr` and
  is therefore an `Cldr` backend module

* `options` is a keyword list of options. The default is
  `[format: :medium, style: :date]`.

Either `from` or `to` may also be `nil` in which case the
interval is formatted as an open interval with the non-nil
side formatted as a standalone date.

### Options

* `:format` is one of `:short`, `:medium` or `:long` or a
  format skeleton or a format pattern representating an interval
  format. The default is `:medium`.

* `:style` supports different formatting styles. The
  alternatives are `:date`, `:month_and_day`, `:month`
  and `:year_and_month`. The default is `:date`.

* `: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 digits should
  be transliterated.

* `:prefer` expresses the preference for one of the possible alternative
  sub-formats. See the variant preference notes below.

### 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.Date.available_formats/3` to see which formats have these variants.

  * Some formats (at the time of publishing, only date and datetime 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`.

### Returns

* `{:ok, string}` or

* `{:error, {exception, reason}}`

## Notes

* For more information on interval format string
  see the `Cldr.Interval`.

* The available predefined formats that can be applied are the
  keys of the map returned by `Cldr.DateTime.Format.interval_formats(:en, :gregorian)`
  where `:en` can be replaced by any configured locale name and `:gregorian`
  is the underlying CLDR calendar type.

* In the case where `from` and `to` are equal, a single
  date is formatted instead of an interval.

### Examples

    iex> Cldr.Date.Interval.to_string(~D[2020-01-01], ~D[2020-12-31], MyApp.Cldr)
    {:ok, "Jan 1 – Dec 31, 2020"}

    iex> Cldr.Date.Interval.to_string(~D[2020-01-01], ~D[2020-01-12], MyApp.Cldr)
    {:ok, "Jan 1 – 12, 2020"}

    iex> Cldr.Date.Interval.to_string(~D[2020-01-01], ~D[2020-01-12], MyApp.Cldr,
    ...> format: :long)
    {:ok, "Wed, Jan 1 – Sun, Jan 12, 2020"}

    iex> Cldr.Date.Interval.to_string(~D[2020-01-01], ~D[2020-12-01], MyApp.Cldr,
    ...> format: :long, style: :year_and_month)
    {:ok, "January – December 2020"}

    iex> Cldr.Date.Interval.to_string(~D[2020-01-01], ~D[2020-01-12], MyApp.Cldr,
    ...> format: :short)
    {:ok, "1/1/2020 – 1/12/2020"}

    iex> Cldr.Date.Interval.to_string(~D[2020-01-01], nil, MyApp.Cldr,
    ...> format: :short)
    {:ok, "1/1/20 –"}

    iex> Cldr.Date.Interval.to_string(~D[2020-01-01], ~D[2020-01-12], MyApp.Cldr,
    ...> format: :long, locale: "fr")
    {:ok, "mer. 1 – dim. 12 janv. 2020"}

    iex> Cldr.Date.Interval.to_string(~D[2020-01-01], ~D[2020-01-12], MyApp.Cldr,
    ...> format: :long, locale: "th", number_system: :thai)
    {:ok, "พุธ ๑ ม.ค. – อาทิตย์ ๑๒ ม.ค. ๒๐๒๐"}

# `to_string!`

```elixir
@spec to_string!(Cldr.Interval.range(), Cldr.backend(), Keyword.t()) ::
  String.t() | no_return()
```

Returns a `t:Date.Range.t/0` or `t:CalendarInterval.t/0` as
a localised string or raises an exception.

### Arguments

* `range` is either a `t:Date.Range.t/0` returned from `Date.range/2`
  or a `CalendarInterval.t`

* `backend` is any module that includes `use Cldr` and
  is therefore a `Cldr` backend module.

* `options` is a keyword list of options. The default is
  `[format: :medium, style: :date]`.

### Options

* `:format` is one of `:short`, `:medium` or `:long` or a
  specific format type or a string representing of an interval
  format. The default is `:medium`.

* `:style` supports different formatting styles. The
  alternatives are `:date`, `:month_and_day`, `:month`
  and `:year_and_month`. The default is `:date`.

* `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 digits should
  be transliterated.

* `:prefer` expresses the preference for one of the possible alternative
  sub-formats. See the variant preference notes below.

### 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.Date.available_formats/3` to see which formats have these variants.

  * Some formats (at the time of publishing, only date and datetime 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`.

## Returns

* `string` or

* raises an exception

### Notes

* `t:CalendarInterval.t/0` support requires adding the
  dependency [calendar_interval](https://hex.pm/packages/calendar_interval)
  to the `deps` configuration in `mix.exs`.

* For more information on interval format string
  see the `Cldr.Interval`.

* The available predefined formats that can be applied are the
  keys of the map returned by `Cldr.DateTime.Format.interval_formats(:en, :gregorian)`
  where `:en` can be replaced by any configured locale name and `:gregorian`
  is the underlying CLDR calendar type.

* In the case where `from` and `to` are equal, a single
  date is formatted instead of an interval.

### Examples

    iex> Cldr.Date.Interval.to_string!(Date.range(~D[2020-01-01], ~D[2020-12-31]), MyApp.Cldr)
    "Jan 1 – Dec 31, 2020"

    iex> Cldr.Date.Interval.to_string!(Date.range(~D[2020-01-01], ~D[2020-01-12]), MyApp.Cldr)
    "Jan 1 – 12, 2020"

    iex> Cldr.Date.Interval.to_string!(Date.range(~D[2020-01-01], ~D[2020-01-12]), MyApp.Cldr,
    ...> format: :long)
    "Wed, Jan 1 – Sun, Jan 12, 2020"

    iex> Cldr.Date.Interval.to_string!(Date.range(~D[2020-01-01], ~D[2020-12-01]), MyApp.Cldr,
    ...> format: :long, style: :year_and_month)
    "January – December 2020"

    iex> use CalendarInterval
    iex> Cldr.Date.Interval.to_string!(~I"2020-01/12", MyApp.Cldr)
    "Jan 1 – Dec 31, 2020"

    iex> Cldr.Date.Interval.to_string!(Date.range(~D[2020-01-01], ~D[2020-01-12]), MyApp.Cldr,
    ...> format: :short)
    "1/1/2020 – 1/12/2020"

    iex> Cldr.Date.Interval.to_string!(Date.range(~D[2020-01-01], ~D[2020-01-12]), MyApp.Cldr,
    ...> format: :long, locale: "fr")
    "mer. 1 – dim. 12 janv. 2020"

# `to_string!`

```elixir
@spec to_string!(
  Calendar.date() | nil,
  Calendar.date() | nil,
  Cldr.backend(),
  Keyword.t()
) ::
  String.t() | no_return()
```

Returns a localised string representing the formatted
interval formed by two dates or raises an
exception.

### Arguments

* `from` is any map that conforms to the
  `Calendar.date` type.

* `to` is any map that conforms to the
  `Calendar.date` type. `to` must occur
  on or after `from`.

* `backend` is any module that includes `use Cldr` and
  is therefore a `Cldr` backend module.

* `options` is a keyword list of options. The default is
  `[format: :medium, style: :date]`.

### Options

* `:format` is one of `:short`, `:medium` or `:long` or a
  specific format type or a string representing of an interval
  format. The default is `:medium`.

* `:style` supports different formatting styles. The
  alternatives are `:date`, `:month_and_day`, `:month`
  and `:year_and_month`. The default is `:date`.

* `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 digits should
  be transliterated.

* `:prefer` expresses the preference for one of the possible alternative
  sub-formats. See the variant preference notes below.

### 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.Date.available_formats/3` to see which formats have these variants.

  * Some formats (at the time of publishing, only date and datetime 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`.

### Returns

* `string` or

* raises an exception

### Notes

* For more information on interval format string
  see `Cldr.Interval`.

* The available predefined formats that can be applied are the
  keys of the map returned by `Cldr.DateTime.Format.interval_formats(:en, :gregorian)`
  where `:en` can be replaced by any configured locale name and `:gregorian`
  is the underlying CLDR calendar type.

* In the case where `from` and `to` are equal, a single
  date is formatted instead of an interval.

### Examples

    iex> Cldr.Date.Interval.to_string!(~D[2020-01-01], ~D[2020-12-31], MyApp.Cldr)
    "Jan 1 – Dec 31, 2020"

    iex> Cldr.Date.Interval.to_string!(~D[2020-01-01], ~D[2020-01-12], MyApp.Cldr)
    "Jan 1 – 12, 2020"

    iex> Cldr.Date.Interval.to_string!(~D[2020-01-01], ~D[2020-01-12], MyApp.Cldr,
    ...> format: :long)
    "Wed, Jan 1 – Sun, Jan 12, 2020"

    iex> Cldr.Date.Interval.to_string!(~D[2020-01-01], ~D[2020-12-01], MyApp.Cldr,
    ...> format: :long, style: :year_and_month)
    "January – December 2020"

    iex> Cldr.Date.Interval.to_string!(~D[2020-01-01], ~D[2020-01-12], MyApp.Cldr,
    ...> format: :short)
    "1/1/2020 – 1/12/2020"

    iex> Cldr.Date.Interval.to_string!(~D[2020-01-01], ~D[2020-01-12], MyApp.Cldr,
    ...> format: :long, locale: "fr")
    "mer. 1 – dim. 12 janv. 2020"

    iex> Cldr.Date.Interval.to_string!(~D[2020-01-01], ~D[2020-01-12], MyApp.Cldr,
    ...> format: :long, locale: "th", number_system: :thai)
    "พุธ ๑ ม.ค. – อาทิตย์ ๑๒ ม.ค. ๒๐๒๐"

---

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