Cldr for Units

Build Status Deps Status Hex pm License

Getting Started

ex_cldr_units is an addon library for ex_cldr that provides localisation and formatting for units such as weights, lengths, areas, volumes and so on. It also provides unit conversion and simple arithmetic for compatible units.

The primary api is defined by three functions:

Unit formatting and localization

Cldr.Unit.to_string/2 provides localized unit formatting. It supports two arguments:

  • number is any number (integer, float or Decimal) or a Unit.t struct returned by Cldr.Unit.new/2

  • options are:

    • unit is any unit returned by Cldr.Unit.units/0. This option is required unless a Unit.t is passed as the first argument.

    • locale is any configured locale. See Cldr.known_locales(). The default is locale: Cldr.get_current_locale()

    • style is one of those returned by Cldr.Unit.available_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

iex> Cldr.Unit.to_string 123, unit: :gallon
{:ok, "123 gallons"}

iex> Cldr.Unit.to_string 1234, unit: :gallon, format: :long
{:ok, "1 thousand gallons"}

iex> Cldr.Unit.to_string 1234, unit: :gallon, format: :short
{:ok, "1K gallons"}

iex> Cldr.Unit.to_string 1234, unit: :megahertz
{:ok, "1,234 megahertz"}

iex> Cldr.Unit.to_string 1234, unit: :foot, locale: "fr"
{:ok, "1 234 pieds"}

iex> Cldr.Unit.to_string Cldr.Unit.new(:ampere, 42), locale: "fr"
{:ok, "42 ampères"}

Converting Units

Unit.t structs can be converted to other compatible units. For example, feet can be converted to meters since they are both the length unit type.

# Test for unit compatibility
iex> Cldr.Unit.compatible? :foot, :meter
true
iex> Cldr.Unit.compatible? :foot, :liter
false

# Convert a unit
iex(9)> Cldr.Unit.convert Cldr.Unit.new(:foot, 3), :meter
#Unit<:meter, 0.9144111192392099>

# What units are compatible?
iex> Cldr.Unit.compatible_units :foot
[:astronomical_unit, :centimeter, :decimeter, :fathom, :foot, :furlong, :inch,
 :kilometer, :light_year, :meter, :micrometer, :mile, :mile_scandinavian,
 :millimeter, :nanometer, :nautical_mile, :parsec, :picometer, :point, :yard]

Unit arithmetic

Basic arithmetic is provided by Cldr.Unit.add/2, Cldr.Unit.sub/2, Cldr.Unit.mult/2, Cldr.Unit.div/2 as well as Cldr.Unit.round/3

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

iex> Cldr.Unit.Math.add Cldr.Unit.new!(:foot, 1), Cldr.Unit.new!(:mile, 1)
#Unit<:foot, 5280.945925937846>

iex> Cldr.Unit.Math.add Cldr.Unit.new!(:foot, 1), Cldr.Unit.new!(:gallon, 1)
{:error, {Cldr.Unit.IncompatibleUnitError,
  "Operations can only be performed between units of the same type. Received #Unit<:foot, 1> and #Unit<:gallon, 1>"}}

iex> Cldr.Unit.round Cldr.Unit.new(:yard, 1031.61), 1
#Unit<:yard, 1031.6>

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

Available units

Available units are returned by Cldr.Unit.units/0.

iex> Cldr.Unit.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, ...]

Unit types

Units are grouped by unit type which defines the convertibility of different types. In general, units of the same time are convertible to each other. The function Cldr.Unit.unit_types/0 returns the unit types. Cldr.Unit.unit_tree/0 returns the map of all unit types and their child units.

iex> Cldr.Unit.unit_types
[:acceleration, :angle, :area, :concentr, :consumption, :coordinate, :digital,
 :duration, :electric, :energy, :frequency, :length, :light, :mass, :power,
 :pressure, :speed, :temperature, :volume]

Further information

For help in iex:

iex> h Cldr.Unit.new
iex> h Cldr.Unit.to_string
iex> h Cldr.Unit.convert
iex> h Cldr.Unit.units
iex> h Cldr.Unit.unit_types

Installation

Note that :ex_cldr_units requires Elixir 1.5 or later.

Add ex_cldr_units as a dependency to your mix project:

defp deps do
  [
    {:ex_cldr_units, "~> 1.0"}
  ]
end

then retrieve ex_cldr_units from hex:

mix deps.get
mix deps.compile