Cldr for Units
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:
Cldr.Unit.to_string/2
for formatting unitsCldr.Unit.new/2
to create a newUnit.t
struct that encapsulated a unit and a value that can be used for arithmetic, comparison and conversionCldr.Unit.convert/2
to convert one compatible unit to anotherCldr.Unit.add/2
,Cldr.Unit.sub/2
,Cldr.Unit.mult/2
,Cldr.Unit.div/2
provide basic arithmetic operations on compatibleUnit.t
structs.
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 aUnit.t
struct returned byCldr.Unit.new/2
options
are:unit
is any unit returned byCldr.Unit.units/0
. This option is required unless aUnit.t
is passed as the first argument.locale
is any configured locale. SeeCldr.known_locales()
. The default islocale: Cldr.get_current_locale()
style
is one of those returned byCldr.Unit.available_styles
. The current styles are:long
,:short
and:narrow
. The default isstyle: :long
Any other options are passed to
Cldr.Number.to_string/2
which is used to format thenumber
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