# `Cldr.Unit`
[🔗](https://github.com/elixir-cldr/cldr_units/blob/v3.20.3/lib/cldr/unit.ex#L1)

Supports the CLDR Units definitions which provide for the localization of many
unit types.

The primary public API defines:

* `Cldr.Unit.to_string/3` which, given a unit or unit list will
  output a localized string.

* `Cldr.Unit.known_units/0` identifies the available units for localization.

* `Cldr.Unit.compare/2` to compare one unit to another unit as long as they
  are convertible.

* `Cldr.Unit.convert/2` to convert one unit to another unit as long as they
  are convertible.

* `Cldr.Unit.add/2` and `Cldr.Unit.sub/2` will add and subtract units as
  long as they are convertible.

* `Cldr.Unit.localize/3` will convert a unit into the units preferred for a
  given locale and usage.

* `Cldr.Unit.preferred_units/3` which, for a given unit and locale,
  will return a list of preferred units that can be applied to
  `Cldr.Unit.decompose/2`.

* `Cldr.Unit.decompose/2` to take a unit and return a list of units decomposed
  by a list of smaller units.

# `base_conversion`

```elixir
@type base_conversion() :: {translatable_unit(), Cldr.Unit.Conversion.t()}
```

# `category`

```elixir
@type category() :: atom()
```

# `conversion`

```elixir
@type conversion() :: [base_conversion()] | {[base_conversion()], [base_conversion()]}
```

# `grammatical_case`

```elixir
@type grammatical_case() ::
  :vocative
  | :translative
  | :terminative
  | :superessive
  | :sublative
  | :sociative
  | :prepositional
  | :partitive
  | :oblique
  | :nominative
  | :localtivecopulative
  | :locative
  | :instrumental
  | :inessive
  | :illative
  | :genitive
  | :ergative
  | :elative
  | :delative
  | :dative
  | :comitative
  | :causal
  | :allative
  | :adessive
  | :accusative
  | :ablative
  | :abessive
```

# `grammatical_gender`

```elixir
@type grammatical_gender() ::
  :neuter | :masculine | :feminine | :common | :personal | :inanimate | :animate
```

# `locale`

```elixir
@type locale() :: Cldr.Locale.locale_name() | Cldr.LanguageTag.t()
```

# `measurement_system`

```elixir
@type measurement_system() ::
  :ussystem
  | :uksystem
  | :si_acceptable
  | :si
  | :prefixable
  | :person_age
  | :metric_adjacent
  | :metric
  | :jpsystem
  | :astronomical
```

# `rounding_mode`

```elixir
@type rounding_mode() ::
  :down | :up | :ceiling | :floor | :half_even | :half_up | :half_down
```

# `style`

```elixir
@type style() :: :narrow | :short | :long
```

# `t`

```elixir
@type t() :: %Cldr.Unit{
  backend: term(),
  base_conversion: conversion(),
  format_options: Keyword.t(),
  unit: unit(),
  usage: usage(),
  value: value()
}
```

# `translatable_unit`

```elixir
@type translatable_unit() :: atom()
```

# `unit`

```elixir
@type unit() :: translatable_unit() | String.t()
```

# `usage`

```elixir
@type usage() :: atom()
```

# `value`

```elixir
@type value() :: Cldr.Math.number_or_decimal()
```

# `add`

```elixir
@spec add(t(), t()) :: t() | {:error, {module(), String.t()}}
```

Adds two compatible `t:Cldr.Unit.t/0` types.

## Arguments

* `unit_1` and `unit_2` are compatible Units
  returned by `Cldr.Unit.new/2`.

## Returns

* A `t:Cldr.Unit.t/0` of the same type as `unit_1` with a value
  that is the sum of `unit_1` and the potentially converted
  `unit_2`, or

* `{:error, {IncompatibleUnitError, message}}`.

## Examples

    iex> Cldr.Unit.add Cldr.Unit.new!(:foot, 1), Cldr.Unit.new!(:foot, 1)
    Cldr.Unit.new!(:foot, 2)

    iex> Cldr.Unit.add Cldr.Unit.new!(:foot, 1), Cldr.Unit.new!(:mile, 1)
    Cldr.Unit.new!(:foot, 5281)

    iex> Cldr.Unit.add Cldr.Unit.new!(:foot, 1), Cldr.Unit.new!(:gallon, 1)
    {:error, {Cldr.Unit.IncompatibleUnitsError,
      "Operations can only be performed between units with the same base unit. Received :foot and :gallon"}}

# `add!`

```elixir
@spec add!(t(), t()) :: t() | no_return()
```

Adds two compatible `t:Cldr.Unit.t/0` types
and raises on error.

## Arguments

* `unit_1` and `unit_2` are compatible Units
  returned by `Cldr.Unit.new/2`.

## Returns

* A `t:Cldr.Unit.t/0` of the same type as `unit_1` with a value
  that is the sum of `unit_1` and the potentially converted
  `unit_2` or

* Raises an exception.

# `base_unit`

Returns the base unit for a given unit.

### Argument

* `unit` is either a `t:Cldr.Unit.t/0`, an `atom` or
  a `t:String.t/0`

### Returns

* `{:ok, base_unit}` or

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

### Example

    iex> Cldr.Unit.base_unit :square_kilometer
    {:ok, :square_meter}

    iex> Cldr.Unit.base_unit :square_table
    {:error, {Cldr.UnknownUnitError, "Unknown unit was detected at \"table\""}}

# `base_unit_category_map`

```elixir
@spec base_unit_category_map() :: %{required(String.t()) =&gt; category()}
```

Returns a mapping of base units to their respective
unit categories.

Base units are a common unit for a given unit
category which are used in two scenarios:

1. When converting between units.  If two units
  have the same base unit they can be converted
  to each other. See `Cldr.Unit.Conversion`.

2. When identifying the preferred units for a given
  locale or territory, the base unit is used to
  aid identification of preferences for given use
  cases. See `Cldr.Unit.Preference`.

### Example

    => Cldr.Unit.base_unit_category_map
    %{
      "kilogram_square_meter_per_cubic_second_ampere" => :voltage,
      "kilogram_meter_per_meter_square_second" => :torque,
      "square_meter" => :area,
      "kilogram" => :mass,
      "kilogram_square_meter_per_square_second" => :energy,
      "revolution" => :angle,
      "candela_per_square_meter" => :luminance,
      ...
    }

# `base_units`

Returns a mapping from unit categories to the
base unit.

# `compare`

```elixir
@spec compare(unit_1 :: t(), unit_2 :: t()) :: :eq | :lt | :gt
```

Compare two units, converting to a common unit
type if required.

If conversion is performed, the results are both
rounded to a single decimal place before
comparison.

### Arguments

* `unit_1` is any unit returned by `Cldr.Unit.new/2`.

* `unit_2` is any unit returned by `Cldr.Unit.new/2`.

### Returns

* One of `:gt`, `:lt`, or `:eq`.

### Example

    iex> x = Cldr.Unit.new!(:kilometer, 1)
    iex> y = Cldr.Unit.new!(:meter, 1000)
    iex> Cldr.Unit.compare(x, y)
    :eq

# `compatible?`

```elixir
@spec compatible?(t() | unit(), t() | unit()) :: boolean()
```

Returns a boolean indicating if two units are
of the same unit category.

### Arguments

* `unit_1` and `unit_2` are any units returned by
  `Cldr.Unit.new/2` or a valid unit name.

### Returns

* `true` or `false`

### Examples

    iex> Cldr.Unit.compatible? :foot, :meter
    true

    iex> Cldr.Unit.compatible? Cldr.Unit.new!(:foot, 23), :meter
    true

    iex> Cldr.Unit.compatible? :foot, :liter
    false

    iex> Cldr.Unit.compatible? "light_year_per_second", "meter_per_gallon"
    false

# `convert`

# `convert!`

# `decompose`

```elixir
@spec decompose(unit :: t(), unit_list :: [unit()], options :: Keyword.t()) :: [t()]
```

Decomposes a unit into subunits.

Any list compatible units can be provided
however a list of units of decreasing scale
is recommended.  For example `[:foot, :inch]`
or `[:kilometer, :meter, :centimeter, :millimeter]`

### Arguments

* `unit` is any unit returned by `Cldr.Unit.new/2`

* `unit_list` is a list of valid units (one or
  more from the list returned by `Cldr.Unit.known_units/0`. All
  units must be from the same unit category.

* `format_options` is a Keyword list of options
  that is added to the *last* unit in `unit_list`.
  The `format_options` will be applied when calling
  `Cldr.Unit.to_string/3` on the `unit`. The
  default is `[]`.

### Returns

* a list of units after decomposition or an error
  tuple

### Examples

    iex> u = Cldr.Unit.new!(10.3, :foot)
    iex> Cldr.Unit.decompose u, [:foot, :inch]
    [Cldr.Unit.new!(:foot, 10), Cldr.Unit.new!(:inch, "3.6")]

    iex> u = Cldr.Unit.new!(:centimeter, 1111)
    iex> Cldr.Unit.decompose u, [:kilometer, :meter, :centimeter, :millimeter]
    [Cldr.Unit.new!(:meter, 11), Cldr.Unit.new!(:centimeter, 11)]

# `default_style`

```elixir
@spec default_style() :: style()
```

Returns the default formatting style.

### Example

    iex> Cldr.Unit.default_style()
    :long

# `display_name`

```elixir
@spec display_name(translatable_unit() | t(), Keyword.t()) ::
  String.t() | {:error, {module(), binary()}}
```

Returns the localized display name
for a unit.

The returned text is generally suitable
for including in UI elements such as
selection boxes.

### Arguments

* `unit` is any `t:Cldr.Unit.t/0` or any
  unit name returned by `Cldr.Unit.known_units/0`.

* `options` is a keyword list of options.

### Options

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

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

* `:style` is one of those returned by `Cldr.Unit.known_styles/0`.
  The current styles are `:long`, `:short` and `:narrow`.
  The default is `style: :long`.

### Examples

    iex> Cldr.Unit.display_name :liter
    "liters"

    iex> Cldr.Unit.display_name :liter, locale: "fr"
    "litres"

    iex> Cldr.Unit.display_name :liter, locale: "fr", style: :short
    "l"

# `from_map`

Returns a new `Unit.t` struct from a map.

A map representation of a unit may be generated
from json or other external format data.

The map provided must have the keys `unit` and
`value` in either `String.t` or `atom` (both keys
must be of the same type).

`value` must be either an integer, a float or a map
representation of a rational number. A rational number
map has the keys `numerator` and `denominator` in either
`String.t` or `atom` format (both keys must be of
the same type).

### Arguments

* `map` is a map with the keys `unit` and `value`

### Returns

* `{:ok, unit}` or

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

### Examples

    Cldr.Unit.from_map %{value: 1, unit: "kilogram"}
    => {:ok, #Cldr.Unit<:kilogram, 1>}

    Cldr.Unit.from_map %{value: %{numerator: 3, denominator: 4}, unit: "kilogram"}
    => {:ok, #Cldr.Unit<:kilogram, 3 <|> 4>}

    Cldr.Unit.from_map %{"value" => 1, "unit" => "kilogram"}
    => {:ok, #Cldr.Unit<:kilogram, 1>}

# `grammatical_gender`
*since 3.5.0* 

```elixir
@spec grammatical_gender(t(), Keyword.t()) :: grammatical_gender()
```

Return the grammatical gender for a
unit.

### Arguments

### Options

### Returns

### Examples

# `grammatical_gender_error`

# `invert`

```elixir
@spec invert(t()) :: {:ok, t()} | {:error, {module(), String.t()}}
```

Inverts a unit

Only "per" units can be inverted.

# `known_grammatical_cases`
*since 3.5.0* 

Returns a list of the known grammatical
cases.

A grammatical case can be provided as an option to
`Cldr.Unit.to_string/2` in order to localise a unit
appropriate to the context in which it is used.

### Example

    iex> Cldr.Unit.known_grammatical_cases()
    [
      :abessive,
      :ablative,
      :accusative,
      :adessive,
      :allative,
      :causal,
      :comitative,
      :dative,
      :delative,
      :elative,
      :ergative,
      :genitive,
      :illative,
      :inessive,
      :instrumental,
      :locative,
      :localtivecopulative,
      :nominative,
      :oblique,
      :partitive,
      :prepositional,
      :sociative,
      :sublative,
      :superessive,
      :terminative,
      :translative,
      :vocative
    ]

# `known_grammatical_genders`
*since 3.5.0* 

Returns a list of the known grammatical genders.

A gender can be provided as an option to
`Cldr.Unit.to_string/2` in order to localise a unit
appropriate to the context in which it is used.

### Example

    iex> Cldr.Unit.known_grammatical_genders()
    [
      :animate,
      :inanimate,
      :personal,
      :common,
      :feminine,
      :masculine,
      :neuter
    ]

# `known_measurement_systems`

```elixir
@spec known_measurement_systems() :: [measurement_system(), ...]
```

Return a list of known measurement systems.

### Example

    iex> Cldr.Unit.known_measurement_systems()
    [:astronomical, :jpsystem, :metric, :metric_adjacent, :person_age, :prefixable, :si, :si_acceptable, :uksystem, :ussystem]

# `known_styles`

```elixir
@spec known_styles() :: [style(), ...]
```

Returns the known styles for a unit.

### Example

    iex> Cldr.Unit.known_styles()
    [:long, :short, :narrow]

# `known_unit_categories`

```elixir
@spec known_unit_categories() :: [category(), ...]
```

Returns a list of the known unit categories.

### Example

    iex> Cldr.Unit.known_unit_categories()
    [:acceleration, :angle, :area, :concentr, :consumption, :digital,
     :duration, :electric, :energy, :force, :frequency, :graphics, :length, :light, :magnetic,
     :mass, :power, :pressure, :speed, :temperature, :torque, :volume]

# `known_units`

```elixir
@spec known_units() :: [translatable_unit(), ...]
```

Returns the known units that are directly
translatable.

These units have localised content in CLDR
and are used as a key to retrieving that
content.

### Example

    => Cldr.Unit.known_units
    [:acre, :acre_foot, :ampere, :arc_minute, :arc_second, :astronomical_unit, :bit,
     :bushel, :byte, :calorie, :carat, :celsius, :centiliter, :centimeter, :century,
     :cubic_centimeter, :cubic_foot, :cubic_inch, :cubic_kilometer, :cubic_meter,
     :cubic_mile, :cubic_yard, :cup, :cup_metric, :day, :deciliter, :decimeter,
     :degree, :fahrenheit, :fathom, :fluid_ounce, :foodcalorie, :foot, :furlong,
     :g_force, :gallon, :gallon_imperial, :generic, :gigabit, :gigabyte, :gigahertz,
     :gigawatt, :gram, :hectare, :hectoliter, :hectopascal, :hertz, :horsepower,
     :hour, :inch, ...]

# `known_units_by_category`
*since 3.4.0* 

```elixir
@spec known_units_by_category() :: %{
  required(category()) =&gt; [translatable_unit(), ...]
}
```

Returns the units that are defined for
a given category (such as :volume, :length)

See also `Cldr.Unit.known_unit_categories/0`.

### Example

    => Cldr.Unit.known_units_by_category
    %{
      acceleration: [:g_force, :meter_per_square_second],
      angle: [:arc_minute, :arc_second, :degree, :radian, :revolution],
      area: [:acre, :dunam, :hectare, :square_centimeter, :square_foot,
       :square_inch, :square_kilometer, :square_meter, :square_mile, :square_yard],
      concentr: [:karat, :milligram_per_deciliter, :millimole_per_liter, :mole,
       :percent, :permille, :permillion, :permyriad], ...
     }

# `known_units_for_category`
*since 3.4.0* 

```elixir
@spec known_units_for_category(category()) ::
  {:ok, [translatable_unit(), ...]} | {:error, {module(), String.t()}}
```

Returns the list of units defined for a given
category.

### Arguments

* `category` is any unit category returned by
  `Cldr.Unit.known_unit_categories/0`.

See also `Cldr.Unit.known_units_by_category/0`.

### Example

    => Cldr.Unit.known_units_for_category :volume
    {
      :ok,
      [
        :cubic_centimeter,
        :centiliter,
        :hectoliter,
        :cubic_kilometer,
        :acre_foot,
        ...
      ]
    }

# `localize`

```elixir
@spec localize(t()) :: [t(), ...] | {:error, {module(), String.t()}}
```

Localizes a unit according to the current
processes locale and backend.

The current process's locale is set with
`Cldr.put_locale/1`.

See `Cldr.Unit.localize/3` for further
details.

# `localize`

```elixir
@spec localize(t(), Cldr.backend(), Keyword.t()) ::
  [t(), ...] | {:error, {module(), String.t()}}
```

Localizes a unit according to a territory

A territory can be derived from a `t:Cldr.Locale.locale_name`
or `t:Cldr.LangaugeTag`.

Use this function if you have a unit which
should be presented in a user interface using
units relevant to the audience. For example, a
unit `#Cldr.Unit100, :meter>` might be better
presented to a US audience as `#Cldr.Unit<328, :foot>`.

### Arguments

* `unit` is any unit returned by `Cldr.Unit.new/2`

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

* `options` is a keyword list of options

### Options

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

* `:territory` is any valid territory code returned by
  `Cldr.known_territories/0`. The default is the territory defined
  as part of the `:locale`. The option `:territory` has a precedence
  over the territory in a locale.

* `:usage` is the way in which the unit is intended
  to be used.  The available `usage` varyies according
  to the unit category.  See `Cldr.Unit.preferred_units/3`.

### Examples

    iex> unit = Cldr.Unit.new!(1.83, :meter)
    iex> Cldr.Unit.localize(unit, usage: :person_height, territory: :US)
    [
      Cldr.Unit.new!(:foot, 6, usage: :person_height),
      Cldr.Unit.new!(:inch, "0.04724409448818897637795275598", usage: :person_height)
    ]

# `maybe_new`

# `measurement_system?`
*since 3.4.0* 

```elixir
@spec measurement_system?(t() | unit(), measurement_system() | [measurement_system()]) ::
  boolean() | {:error, {module(), String.t()}}
```

Returns a boolean indicating if a given
unit belongs to one or more measurement
systems.

When a list or more than one measurement
system is provided, the test is one of
inclusion. That is, if the unit belongs to
any of the provided measurement systems
the return is `true`.

### Arguments

* `system` is any measurement system or list
  of measurement systems returned by
  `Cldr.Unit.known_measurement_systems/0`

### Returns

* `true` or `false` or

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

### Examples

    iex> Cldr.Unit.measurement_system? :foot, :uksystem
    true

    iex> Cldr.Unit.measurement_system? :foot, [:uksystem, :ussystem]
    true

    iex> Cldr.Unit.measurement_system? :foot, [:metric]
    false

    iex> Cldr.Unit.measurement_system? :invalid, [:metric]
    {:error, {Cldr.UnknownUnitError, "The unit :invalid is not known."}}

# `measurement_system_for_territory`

```elixir
@spec measurement_system_for_territory(atom(), atom()) ::
  :metric
  | :ussystem
  | :uksystem
  | :a4
  | :us_letter
  | {:error, {module(), String.t()}}
```

Returns the default measurement system for a territory
and a given system key.

### Arguments

* `territory` is any valid territory returned by
  `Cldr.validate_territory/1`

* `key` is any measurement system key.
  The known keys are `:default`, `:temperature`
  and `:paper_size`. The default key is `:default`.

### Examples

    iex> Cldr.Unit.measurement_system_for_territory :US
    :ussystem

    iex> Cldr.Unit.measurement_system_for_territory :GB
    :uksystem

    iex> Cldr.Unit.measurement_system_for_territory :AU
    :metric

    iex> Cldr.Unit.measurement_system_for_territory :US, :temperature
    :ussystem

    iex> Cldr.Unit.measurement_system_for_territory :GB, :temperature
    :uksystem

    iex> Cldr.Unit.measurement_system_for_territory :GB, :volume
    {:error,
     {Cldr.Unit.InvalidSystemKeyError,
      "The key :volume is not known. Valid keys are :default, :paper_size and :temperature"}}

# `measurement_system_from_locale`
*since 3.4.0* 

```elixir
@spec measurement_system_from_locale(
  Cldr.LanguageTag.t() | Cldr.Locale.locale_name(),
  measurement_system() | Cldr.backend()
) :: measurement_system() | {:error, {module(), String.t()}}
```

Determines the preferred measurement system
from a locale.

See also `Cldr.Unit.known_measurement_systems/0`.

### Arguments

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

* `key` is any measurement system key.
  The known keys are `:default`, `:temperature`
  and `:paper_size`. The default key is `:default`.

### Examples

    iex> Cldr.Unit.measurement_system_from_locale "en"
    :ussystem

    iex> Cldr.Unit.measurement_system_from_locale "en-GB"
    :uksystem

    iex> Cldr.Unit.measurement_system_from_locale "en-AU"
    :metric

    iex> Cldr.Unit.measurement_system_from_locale "en-AU-u-ms-ussystem"
    :ussystem

    iex> Cldr.Unit.measurement_system_from_locale "en-GB", :temperature
    :uksystem

    iex> Cldr.Unit.measurement_system_from_locale "en-AU", :paper_size
    :a4

    iex> Cldr.Unit.measurement_system_from_locale "en-GB", :invalid
    {:error,
     {Cldr.Unit.InvalidSystemKeyError,
      "The key :invalid is not known. Valid keys are :default, :paper_size and :temperature"}}

# `measurement_system_from_locale`
*since 3.4.0* 

```elixir
@spec measurement_system_from_locale(
  Cldr.Locale.locale_reference(),
  Cldr.backend(),
  measurement_system()
) :: measurement_system() | {:error, {module(), String.t()}}
```

# `measurement_system_units`
*since 3.4.0* 

```elixir
@spec measurement_system_units(measurement_system()) ::
  [translatable_unit(), ...] | {:error, {module(), String.t()}}
```

Returns the list of units defined in a given
measurement system.

### Arguments

* `system` is any measurement system returned by
  `Cldr.Unit.known_measurement_systems/0`

### Returns

* A list of translatable units as atoms or

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

### Example

    => Cldr.Unit.measurement_system_units :uksystem
    [
      :ton,
      :inch,
      :yard,
      ...
    ]

# `measurement_systems`

> This function is deprecated. Use Cldr.Unit.measurement_systems_by_territory/0.

# `measurement_systems_by_territory`

```elixir
@spec measurement_systems_by_territory() :: %{
  required(Cldr.Locale.territory_code()) =&gt; map()
}
```

Returns a map of measurement systems by territory.

### Example

    => Cldr.Unit.measurement_systems_by_territory
    %{
      KE: %{default: :metric, paper_size: :a4, temperature: :metric},
      GU: %{default: :metric, paper_size: :a4, temperature: :metric},
      ...
    }

# `measurement_systems_for_unit`
*since 3.4.0* 

```elixir
@spec measurement_systems_for_unit(t() | unit()) ::
  [measurement_system(), ...] | {:error, {module(), String.t()}}
```

Returns the measurement systems for a given
unit.

### Arguments

* `unit` is any `t:Cldr.Unit.t/0` or any unit
  returned by `Cldr.Unit.known_units/0` or a
  string unit name.

### Returns

* A list of measurement systems to which
  the `unit` belongs.

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

### Examples

    iex> Cldr.Unit.measurement_systems_for_unit :foot
    [:uksystem, :ussystem]

    iex> Cldr.Unit.measurement_systems_for_unit :meter
    [:metric, :prefixable, :si]

    iex> Cldr.Unit.measurement_systems_for_unit :invalid
    {:error, {Cldr.UnknownUnitError, "The unit :invalid is not known."}}

# `new`

```elixir
@spec new(unit() | value(), value() | unit(), Keyword.t()) ::
  {:ok, t()} | {:error, {module(), String.t()}}
```

Returns a new `Unit.t` struct.

### Arguments

* `value` is any float, integer or `Decimal`

* `unit` is any unit name returned by `Cldr.Unit.known_units/0`

* `options` is Keyword list of options. The default
  is `[]`

### Options

* `:usage` is the intended use of the unit. This
  is used during localization to convert the unit
  to that appropriate for the unit category,
  usage, target territory and unit value. The usage
  must be defined for the unit's category. See
  `Cldr.Unit.unit_category_usage/0` for the known
  usage types for each category.

### Returns

* `unit` or

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

### Examples

    iex> Cldr.Unit.new(23, :gallon)
    {:ok, Cldr.Unit.new!(:gallon, 23)}

    iex> Cldr.Unit.new(:gallon, 23)
    {:ok, Cldr.Unit.new!(:gallon, 23)}

    iex> Cldr.Unit.new(14, :gadzoots)
    {:error, {Cldr.UnknownUnitError,
      "Unknown unit was detected at \"gadzoots\""}}

    Cldr.Unit.new(:gallon, 23, usage: :fluid)
    #=> {:ok, #Cldr.Unit<:gallon, 23, usage: :fluid, format_options: []>}

# `new!`

Returns a new `Unit.t` struct or raises on error.

### Arguments

* `value` is any float, integer or `Decimal`

* `unit` is any unit returned by `Cldr.Unit.known_units/0`

### Returns

* `unit` or

* raises an exception

### Examples

    iex> Cldr.Unit.new! 23, :gallon
    Cldr.Unit.new!(:gallon, 23)

    Cldr.Unit.new! 14, :gadzoots
    ** (Cldr.UnknownUnitError) The unit :gadzoots is not known.
        (ex_cldr_units) lib/cldr/unit.ex:57: Cldr.Unit.new!/2

# `parse`
*since 3.6.0* 

Parse a string to create a new unit.

This function attempts to parse a string
into a `number` and `unit type`. If successful
it attempts to create a new unit using
`Cldr.Unit.new/3`.

The parsed `unit type` is aliased against all the
known unit names for a give locale (or the current
locale if no locale is specified). The known
aliases for unit types can be returned with
`MyApp.Cldr.Unit.unit_strings_for/1` where `MyApp.Cldr`
is the name of a backend module.

### Arguments

* `unit string` is any string to be parsed and if
  possible used to create a new `t:Cldr.Unit.t/0`

* `options` is a keyword list of options

### Options

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

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

* `:only` is a unit category or unit, or a list of unit categories and units.
  The parsed unit must match one of the categories or units in order to
  be valid. This is helpful when disambiguating parsed units. For example,
  parsing "2w" could be either "2 watts" or "2 weeks". Specifying `only: :duration`
  would return "2 weeks". Specifying `only: :power` would return
  "2 watts"

* `:except` is the oppostte of `:only`. The parsed unit must *not*
  match the specified unit or category, or unit categories and units.

### Returns

* `{:ok, unit}` or

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

### Notes

* When both `:only` and `:except` options are passed, both
  conditions must be true in order to return a parsed result.

* Only units returned by `Cldr.Unit.known_units/0` can be
  used in the `:only` and `:except` filters.

### Examples

    iex> Cldr.Unit.parse "1kg"
    Cldr.Unit.new(1, :kilogram)

    iex> Cldr.Unit.parse "1w"
    Cldr.Unit.new(1, :watt)

    iex> Cldr.Unit.parse "1w", only: :duration
    Cldr.Unit.new(1, :week)

    iex> Cldr.Unit.parse "1m", only: [:year, :month, :day]
    Cldr.Unit.new(1, :month)

    iex> Cldr.Unit.parse "1 tages", locale: "de"
    Cldr.Unit.new(1, :day)

    iex> Cldr.Unit.parse "1 tag", locale: "de"
    Cldr.Unit.new(1, :day)

    iex> Cldr.Unit.parse("42 millispangels")
    {:error, {Cldr.UnknownUnitError, "Unknown unit was detected at \"spangels\""}}

# `parse!`
*since 3.6.0* 

Parse a string to create a new unit or
raises an exception.

This function attempts to parse a string
into a `number` and `unit type`. If successful
it attempts to create a new unit using
`Cldr.Unit.new/3`.

The parsed `unit type` is un-aliased against all the
known unit names for a give locale (or the current
locale if no locale is specified). The known
aliases for unit types can be returned with
`MyApp.Cldr.Unit.unit_strings_for/1` where `MyApp.Cldr`
is the name of a backend module.

### Arguments

* `unit string` is any string to be parsed and if
  possible used to create a new `t:Cldr.Unit.t/0`

* `options` is a keyword list of options

### Options

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

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

* `:only` is a unit category or unit, or a list of unit categories and units.
  The parsed unit must match one of the categories or units in order to
  be valid. This is helpful when disambiguating parsed units. For example,
  parsing "2w" could be either "2 watts" or "2 weeks". Specifying `only: :duration`
  would return "2 weeks". Specifying `only: :power` would return
  "2 watts"

* `:except` is the oppostte of `:only`. The parsed unit must *not*
  match the specified unit or category, or unit categories and units.

### Notes

* When both `:only` and `:except` options are passed, both
  conditions must be true in order to return a parsed result.

* Only units returned by `Cldr.Unit.known_units/0` can be
  used in the `:only` and `:except` filters.

### Returns

* `unit` or

* raises an exception

### Examples

    iex> Cldr.Unit.parse! "1kg"
    Cldr.Unit.new!(1, :kilogram)

    iex> Cldr.Unit.parse! "1 tages", locale: "de"
    Cldr.Unit.new!(1, :day)

    iex> Cldr.Unit.parse!("42 candela per lux")
    Cldr.Unit.new!(42, "candela per lux")

    iex> Cldr.Unit.parse!("42 millispangels")
    ** (Cldr.UnknownUnitError) Unknown unit was detected at "spangels"

# `parse_unit_name`
*since 3.14.0* 

```elixir
@spec parse_unit_name(binary(), Keyword.t()) ::
  {:ok, atom()} | {:error, {module(), binary()}}
```

Parse a string to find a matching unit-atom.

This function attempts to parse a string and
extract the `unit type`.

The parsed `unit type` is aliased against all the
known unit names for a give locale (or the current
locale if no locale is specified). The known
aliases for unit types can be returned with
`MyApp.Cldr.Unit.unit_strings_for/1` where `MyApp.Cldr`
is the name of a backend module.

### Arguments

* `unit_name_string` is any string to be parsed and converted into a `unit type`

* `options` is a keyword list of options

### Options

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

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

* `:only` is a unit category or unit, or a list of unit categories and units.
  The parsed unit must match one of the categories or units in order to
  be valid. This is helpful when disambiguating parsed units. For example,
  parsing "w" could be either `:watt` or `:weeks`. Specifying `only: :duration`
  would return `:weeks`. Specifying `only: :power` would return `:watt`

* `:except` is the oppostte of `:only`. The parsed unit must *not*
  match the specified unit or category, or unit categories and units.

### Returns

* `{:ok, unit_name}` or

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

### Notes

* When both `:only` and `:except` options are passed, both
  conditions must be true in order to return a parsed result.

* Only units returned by `Cldr.Unit.known_units/0` can be
  used in the `:only` and `:except` filters.

### Examples

    iex> Cldr.Unit.parse_unit_name "kg"
    {:ok, :kilogram}

    iex> Cldr.Unit.parse_unit_name "w"
    {:ok, :watt}

    iex> Cldr.Unit.parse_unit_name "w", only: :duration
    {:ok, :week}

    iex> Cldr.Unit.parse_unit_name "m", only: [:year, :month, :day]
    {:ok, :month}

    iex> Cldr.Unit.parse_unit_name "tages", locale: "de"
    {:ok, :day}

    iex> Cldr.Unit.parse_unit_name "tag", locale: "de"
    {:ok, :day}

    iex> Cldr.Unit.parse_unit_name("millispangels")
    {:error, {Cldr.UnknownUnitError, "Unknown unit was detected at \"spangels\""}}

# `parse_unit_name!`
*since 3.14.0* 

Parse a string to find a matching unit-atom.

This function attempts to parse a string and
extract the `unit type`.

The parsed `unit type` is aliased against all the
known unit names for a give locale (or the current
locale if no locale is specified). The known
aliases for unit types can be returned with
`MyApp.Cldr.Unit.unit_strings_for/1` where `MyApp.Cldr`
is the name of a backend module.

### Arguments

* `unit_name_string` is any string to be parsed and converted into a `unit type`

* `options` is a keyword list of options

### Options

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

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

* `:only` is a unit category or unit, or a list of unit categories and units.
  The parsed unit must match one of the categories or units in order to
  be valid. This is helpful when disambiguating parsed units. For example,
  parsing "w" could be either `watts` or `:week`. Specifying `only: :duration`
  would return `:week`. Specifying `only: :power` would return `:watts`

* `:except` is the oppostte of `:only`. The parsed unit must *not*
  match the specified unit or category, or unit categories and units.

### Returns

* `unit_name` or

* raises an exception

### Notes

* When both `:only` and `:except` options are passed, both
  conditions must be true in order to return a parsed result.

* Only units returned by `Cldr.Unit.known_units/0` can be
  used in the `:only` and `:except` filters.

### Examples

    iex> Cldr.Unit.parse_unit_name! "kg"
    :kilogram

    iex> Cldr.Unit.parse_unit_name! "w"
    :watt

    iex> Cldr.Unit.parse_unit_name! "w", only: :duration
    :week

    iex> Cldr.Unit.parse_unit_name! "m", only: [:year, :month, :day]
    :month

    iex> Cldr.Unit.parse_unit_name! "tages", locale: "de"
    :day

    iex> Cldr.Unit.parse_unit_name! "tag", locale: "de"
    :day

    iex> Cldr.Unit.parse_unit_name!("millispangels")
    ** (Cldr.UnknownUnitError) Unknown unit was detected at "spangels"

# `preferred_units`

# `preferred_units!`

# `ratio_to_decimal`

> This function is deprecated. Use Cldr.Unit.to_decimal_unit/1.

# `ratio_to_float`

> This function is deprecated. Use Cldr.Unit.to_float_unit/1.

# `round`

```elixir
@spec round(
  unit :: t() | number() | Decimal.t(),
  places :: non_neg_integer(),
  mode :: rounding_mode()
) :: t() | number() | Decimal.t()
```

Rounds the value of a unit.

### Arguments

* `unit` is any unit returned by `Cldr.Unit.new/2`

* `places` is the number of decimal places to round to.
  The default is `0`.

* `mode` is the rounding mode to be applied.  The default
  is `:half_up`.

### Returns

* A `t:Cldr.Unit.t/0` of the same type as `unit` with a value
  that is rounded to the specified number of decimal places.

### Rounding modes

Directed roundings:

* `:down` - Round towards 0 (truncate), eg `10.9` rounds to `10.0`.

* `:up` - Round away from `0`, eg `10.1` rounds to `11.0`. (Non IEEE algorithm).

* `:ceiling` - Round toward +∞ - Also known as rounding up or ceiling.

* `:floor` - Round toward -∞ - Also known as rounding down.

Round to nearest:

* `:half_even` - Round to nearest value, but in a tiebreak, round towards the
  nearest value with an even (zero) least significant bit, which occurs 50%
  of the time. This is the default for IEEE binary floating-point and the recommended
  value for decimal.

* `:half_up` - Round to nearest value, but in a tiebreak, round away from 0.
  This is the default algorithm for Elixir's Kernel.round/2

* `:half_down` - Round to nearest value, but in a tiebreak, round towards 0
  (Non IEEE algorithm)

### Examples

    iex> Cldr.Unit.round(Cldr.Unit.new!(:yard, 1031.61), 1)
    Cldr.Unit.new!(:yard, "1031.6")

    iex> Cldr.Unit.round(Cldr.Unit.new!(:yard, 1031.61), 2)
    Cldr.Unit.new!(:yard, "1031.61")

    iex> Cldr.Unit.round(Cldr.Unit.new!(:yard, 1031.61), 1, :up)
    Cldr.Unit.new!(:yard, "1031.7")

# `styles`

> This function is deprecated. Use Cldr.Unit.known_styles/0.

# `sub`

```elixir
@spec sub(t(), t()) :: t() | {:error, {module(), String.t()}}
```

Subtracts one compatible `t:Cldr.Unit.t/0` type from
another.

## Arguments

* `unit_1` and `unit_2` are compatible Units
  returned by `Cldr.Unit.new/2`.

## Returns

* A `t:Cldr.Unit.t/0` of the same type as `unit_1` with a value
  that is the difference between `unit_1` and the potentially
  converted `unit_2`, or

* `{:error, {IncompatibleUnitError, message}}`.

## Examples

    iex> Cldr.Unit.sub Cldr.Unit.new!(:kilogram, 5), Cldr.Unit.new!(:pound, 1)
    Cldr.Unit.new!(:kilogram, "4.54640763")

    iex> Cldr.Unit.sub Cldr.Unit.new!(:pint, 5), Cldr.Unit.new!(:liter, 1)
    Cldr.Unit.new!(:pint, "2.886623581134812676960800627")

    iex> Cldr.Unit.sub Cldr.Unit.new!(:pint, 5), Cldr.Unit.new!(:pint, 1)
    Cldr.Unit.new!(:pint, 4)

# `sub!`

```elixir
@spec sub!(t(), t()) :: t() | no_return()
```

Subtracts one compatible `t:Cldr.Unit.t/0` type from
another or raises on error.

## Arguments

* `unit_1` and `unit_2` are compatible Units
  returned by `Cldr.Unit.new/2`.

## Returns

* A `t:Cldr.Unit.t/0` of the same type as `unit_1` with a value
  that is the difference between `unit_1` and the potentially
  converted `unit_2` or

* Raises an exception.

# `to_decimal_unit`
*since 3.5.0* 

Convert a float or integer `t:Unit` to a Decimal `t:Unit`.

# `to_float`

# `to_float_unit`
*since 3.5.0* 

Convert a Decimal or integer `t:Unit` to a float `t:Unit`.

# `to_string`

```elixir
@spec to_string(list_or_number :: value() | t() | [t()]) ::
  {:ok, String.t()} | {:error, {atom(), binary()}}
```

Formats a number into a string according to a unit definition
for the current process's locale and backend.

The current process's locale is set with
`Cldr.put_locale/1`.

See `Cldr.Unit.to_string/3` for full details.

# `to_string`

```elixir
@spec to_string(
  value() | t() | [t()],
  Cldr.backend() | Keyword.t(),
  Keyword.t()
) :: {:ok, String.t()} | {:error, {atom(), binary()}}
```

Formats a number into a string according to a unit definition for a locale.

During processing any `:format_options` of a `Unit.t()` are merged with
`options` with `options` taking precedence.

### Arguments

* `list_or_number` is any number (integer, float or Decimal) or a
  `t:Cldr.Unit.t/0` struct or a list of `t:Cldr.Unit.t/0` structs.

* `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.

### Options

* `:unit` is any unit returned by `Cldr.Unit.known_units/0`. Ignored if
  the number to be formatted is a `t:Cldr.Unit.t/0` struct.

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

* `:format` defines how the *number* part of the unit string is
  formatted. This option is passed directly to `Cldr.Number.to_string/2`.
  In particular, note that this option does *not* determine how the
  unit string itself is formed - see the `:style` option for that purpose.
  The default is `:medium`.

* `style` determines how the unit string is composed and is is one of values
  returned by `Cldr.Unit.styles`. The current styles are `:long`, `:short`
  and `:narrow`. The default is `style: :long`.

* `:grammatical_case` indicates that a localisation for the given
  locale and given grammatical case should be used. See `Cldr.Unit.known_grammatical_cases/0`
  for the list of known grammatical cases. Note that not all locales
  define all cases. However all locales do define the `:nominative`
  case, which is also the default.

* `:gender` indicates that a localisation for the given
  locale and given grammatical gender should be used.
  See `Cldr.Unit.known_grammatical_genders/0`
  for the list of known grammatical genders. Note that not all locales
  define all genders.

* `:list_options` is a keyword list of options for formatting a list
  which is passed through to `Cldr.List.to_string/3`. This is only
  applicable when formatting a list of units.

* Any other options are passed to `Cldr.Number.to_string/2`
  which is used to format the `number`.

### Returns

* `{:ok, formatted_string}` or

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

### Examples

    iex> Cldr.Unit.to_string Cldr.Unit.new!(:gallon, 123), MyApp.Cldr
    {:ok, "123 gallons"}

    iex> Cldr.Unit.to_string Cldr.Unit.new!(:gallon, 1), MyApp.Cldr
    {:ok, "1 gallon"}

    iex> Cldr.Unit.to_string Cldr.Unit.new!(:gallon, 1), MyApp.Cldr, locale: "af"
    {:ok, "1 gelling"}

    iex> Cldr.Unit.to_string Cldr.Unit.new!(:gallon, 1), MyApp.Cldr, locale: "bs"
    {:ok, "1 galon"}

    iex> Cldr.Unit.to_string Cldr.Unit.new!(:gallon, 1234), MyApp.Cldr, format: :long
    {:ok, "1 thousand gallons"}

    iex> Cldr.Unit.to_string Cldr.Unit.new!(:gallon, 1234), MyApp.Cldr, format: :short
    {:ok, "1K gallons"}

    iex> Cldr.Unit.to_string Cldr.Unit.new!(:megahertz, 1234), MyApp.Cldr
    {:ok, "1,234 megahertz"}

    iex> Cldr.Unit.to_string Cldr.Unit.new!(:megahertz, 1234), MyApp.Cldr, style: :narrow
    {:ok, "1,234MHz"}

    iex> unit = Cldr.Unit.new!(123, :foot)
    iex> Cldr.Unit.to_string unit, MyApp.Cldr
    {:ok, "123 feet"}

    iex> Cldr.Unit.to_string 123, MyApp.Cldr, unit: :foot
    {:ok, "123 feet"}

    iex> Cldr.Unit.to_string Decimal.new(123), MyApp.Cldr, unit: :foot
    {:ok, "123 feet"}

    iex> Cldr.Unit.to_string 123, MyApp.Cldr, unit: :megabyte, locale: "en", style: :unknown
    {:error, {Cldr.UnknownFormatError, "The unit style :unknown is not known."}}

# `to_string!`

```elixir
@spec to_string!(list_or_number :: value() | t() | [t()]) :: String.t() | no_return()
```

Formats a number into a string according to a unit definition
for the current process's locale and backend or raises
on error.

The current process's locale is set with
`Cldr.put_locale/1`.

See `Cldr.Unit.to_string!/3` for full details.

# `to_string!`

```elixir
@spec to_string!(
  value() | t() | [t()],
  Cldr.backend() | Keyword.t(),
  Keyword.t()
) :: String.t() | no_return()
```

Formats a number into a string according to a unit definition
for the current process's locale and backend or raises
on error.

During processing any `:format_options` of a `t:Cldr.Unit.t/0` are merged with
`options` with `options` taking precedence.

### Arguments

* `number` is any number (integer, float or Decimal) or a
  `t:Cldr.Unit.t/0` struct.

* `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.

### Options

* `:unit` is any unit returned by `Cldr.Unit.known_units/0`. Ignored if
  the number to be formatted is a `t:Cldr.Unit.t/0` struct

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

* `:format` defines how the *number* part of the unit string is
  formatted. This option is passed directly to `Cldr.Number.to_string/2`.
  In particular, note that this option does *not* determine how the
  unit string itself is formed - see the `:style` option for that purpose.
  The default is `:medium`.

* `style` determines how the unit string is composed and is is one of values
  returned by `Cldr.Unit.styles`. The current styles are `:long`, `:short`
  and `:narrow`. The default is `style: :long`.

* Any other options are passed to `Cldr.Number.to_string/2`
  which is used to format the `number`

### Returns

* `formatted_string` or

* raises an exception

### Examples

    iex> Cldr.Unit.to_string! Cldr.Unit.new!(:gallon, 123), MyApp.Cldr
    "123 gallons"

    iex> Cldr.Unit.to_string! Cldr.Unit.new!(:gallon, 1), MyApp.Cldr
    "1 gallon"

    iex> Cldr.Unit.to_string! Cldr.Unit.new!(:gallon, 1), MyApp.Cldr, locale: "af"
    "1 gelling"

# `trunc`

```elixir
@spec trunc(unit_1 :: t()) :: t()
```

Truncates the value of a unit.

### Arguments

* `unit` is any unit returned by `Cldr.Unit.new/2`

### Returns

* A `t:Cldr.Unit.t/0` with a truncated value.

### Example

    iex> {:ok, unit} = Cldr.Unit.new(1.235, :liter)
    iex> Cldr.Unit.trunc(unit)
    Cldr.Unit.new!(:liter, 1)

# `unit`

> This function is deprecated. Use Cldr.Unit.known_units/0.

# `unit_categories`

> This function is deprecated. Use `Cldr.Unit.known_unit_categories/0.

# `unit_category`

```elixir
@spec unit_category(t() | String.t() | atom()) ::
  {:ok, category()} | {:error, {module(), String.t()}}
```

Returns the units category for a given unit

### Options

* `unit` is either a `t:Cldr.Unit.t/0`, an `atom` or
  a `t:String.t/0`

### Returns

* `{:ok, category}` or

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

### Examples

    iex> Cldr.Unit.unit_category :pint_metric
    {:ok, :volume}

    iex> Cldr.Unit.unit_category :stone
    {:ok, :mass}

    iex> Cldr.Unit.unit_category :watt
    {:ok, :power}

    iex> Cldr.Unit.unit_category "kilowatt hour"
    {:ok, :energy}

    iex> Cldr.Unit.unit_category "watt hour per light year"
    {:ok, :force}

    iex> Cldr.Unit.unit_category "watt per kilogram"
    {:error,
     {Cldr.Unit.UnknownCategoryError,
      "The category for \"watt_per_kilogram\" is not known."}}

# `unit_category_usage`

Returns a mapping between Unit categories
and the uses they define.

### Example

    iex> Cldr.Unit.unit_category_usage()
    %{
      area: [:default, :floor, :geograph, :land],
      concentration: [:blood_glucose, :default],
      consumption: [:default, :vehicle_fuel],
      duration: [:default, :media],
      energy: [:default, :food],
      length: [:default, :focal_length, :person, :person_height, :rainfall, :road,
       :snowfall, :vehicle, :visiblty],
      mass: [:default, :person],
      mass_density: [:default],
      power: [:default, :engine],
      pressure: [:baromtrc, :default],
      speed: [:default, :rainfall, :snowfall, :wind],
      temperature: [:default, :weather],
      volume: [:default, :fluid, :oil, :vehicle],
      year_duration: [:default, :person_age]
    }

# `unit_type`

> This function is deprecated. Please use `Cldr.Unit.unit_category/1.

# `validate_grammatical_case`
*since 3.5.0* 

Validates a grammatical case and normalizes it to a
standard downcased atom form

# `validate_grammatical_gender`
*since 3.5.0* 

Validates a grammatical gender and normalizes it to a
standard downcased atom form

# `validate_style`

Validates a unit style and normalizes it to a
standard downcased atom form

# `validate_unit`

Validates a unit name and normalizes it,

A unit name can be expressed as:

* an `atom()` in which case the unit must be
  localizable in CLDR directly

* or a `t:String.t/0` in which case it is parsed
  into a list of composable subunits that
  can be converted but are not guaranteed to
  be output as a localized string.

### Arguments

* `unit_name` is an `atom()` or `t:String.t/0`, supplied
  as is or as part of an `t:Cldr.Unit.t/0` struct.

### Returns

* `{:ok, canonical_unit_name, conversion}` where
  `canonical_unit_name` is the normalized unit name
  and `conversion` is an opaque structure used
  to convert this this unit into its base unit or

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

### Notes

A returned `unit_name` that is an atom is directly
localisable (CLDR has translation data for the unit).

A `unit_name` that is a `t:String.t/0` is composed of
one or more unit names that need to be resolved in
order for the `unit_name` to be localised.

The difference is an implementation detail and should
not be of concern to the user of this library.

### Examples

    iex> Cldr.Unit.validate_unit :meter
    {
      :ok,
      :meter,
      [meter: %Cldr.Unit.Conversion{base_unit: [:meter], factor: 1, offset: 0}]
    }

    iex> Cldr.Unit.validate_unit "meter"
    {:ok, :meter,
     [meter: %Cldr.Unit.Conversion{base_unit: [:meter], factor: 1, offset: 0}]}

    iex> Cldr.Unit.validate_unit "miles_per_liter"
    {:error, {Cldr.UnknownUnitError, "Unknown unit was detected at \"s\""}}

    iex> Cldr.Unit.validate_unit "mile_per_liter"
    {:ok, "mile_per_liter",
     {[
        mile: %Cldr.Unit.Conversion{
          factor: Decimal.new("1609.3440"),
          offset: 0,
          base_unit: [:meter]
        }
      ],
      [
        liter: %Cldr.Unit.Conversion{
          factor: Decimal.new("0.001"),
          offset: 0,
          base_unit: [:cubic_meter]
        }
      ]}}

# `value`

```elixir
@spec value(unit :: t()) :: value()
```

Return the value of the Unit struct

### Arguments

* `unit` is any unit returned by `Cldr.Unit.new/2`

### Returns

* an integer, float or Decimal representing the amount
of the unit

### Example

    iex> Cldr.Unit.value Cldr.Unit.new!(:kilogram, 23)
    23

# `zero`

Returns a new unit of the same unit
type but with a zero value.

### Argument

* `unit` is any unit returned by `Cldr.Unit.new/2`

### Example

    iex> u = Cldr.Unit.new!(:foot, 23.3)
    Cldr.Unit.new!(:foot, "23.3")
    iex> Cldr.Unit.zero(u)
    Cldr.Unit.new!(:foot, 0)

# `zero?`

Returns a boolean indicating whether a given unit
has a zero value.

### Argument

* `unit` is any unit returned by `Cldr.Unit.new/2`

### Examples

    iex> u = Cldr.Unit.new!(:foot, 23.3)
    Cldr.Unit.new!(:foot, 23.3)
    iex> Cldr.Unit.zero?(u)
    false

    iex> u = Cldr.Unit.new!(:foot, 0)
    Cldr.Unit.new!(:foot, 0)
    iex> Cldr.Unit.zero?(u)
    true

---

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