Getting Started with Cldr

Build StatusHex pmLicense

Getting Started

Cldr is an Elixir library for the Unicode Consortium’sCommon Locale Data Repository (CLDR). The intentions of CLDR, and this library, is to simplify the locale specific formatting of numbers, lists, currencies, calendars, units of measure and dates/times. As of November 2nd 2017 and Version 0.10.0, Cldr is based upon CLDR version 32.0.0.

The functions you are mostly likely to user are in the modules Cldr and Cldr.Locale. In particular:

To access the raw Cldr data for a locale the Cldr.Config module is available. Note that the functions in Cldr.Config are typically used by library authors. The most useful function is:

Use this package when you have a requirement to…

It is highly likely that you will also want to install one or more of the dependent packages that provide localization and formatting for a particular data domain. See Additional Cldr Packages below.

Elixir Version Requirements

Installation

Add ex_cldr as a dependency to your mix project:

defp deps do
  [
    {:ex_cldr, "~> 1.0"},
    # Posion or any other compatible json library
    # that implements `encode!/1` and `decode!/1`
    # {:jason, "~> 1.0 or ~> 1.0-rc"}
    {:poison, "~> 2.1 or ~> 3.0"}
  ]
end

then retrieve ex_cldr from hex:

mix deps.get
mix deps.compile

Although Cldr is purely a library application, it should be added to your application list so that it gets bundled correctly for release. This applies for Elixir versions up to 1.3.x; version 1.4 and later will automatically do this for you.

def application do
  [applications: [:ex_cldr]]
end

Additional Cldr Packages

ex_cldr includes only basic functions to maintain the CLDR data repository in an accessible manner and to manage locale definitions. Additional functionality is available by adding additional packages:

Each of these packages includes ex_cldr as a dependency so configuring any of these additional packages will automatically install ex_cldr.

Configuration

Cldr attempts to maximise runtime performance at the expense of additional compile time. Where possible Cldr will create functions to encapsulate data at compile time. To perform these optimizations for all 523 locales known to Cldr wouldn’t be an effective use of your time or your computer’s. Therefore Cldr requires that you configure the locales you want to use. You can do this in your mix.exs by specifying the locales you want to configure or by telling Cldr about a Gettext module you may already have configured - in which case Cldr will configure whatever locales you have configured in Gettext as well.

Here’s an example configuration that uses all of the available configuration keys:

 config :cldr,
   default_locale: "en",
   locales: ["fr", "en", "bs", "si", "ak", "th"],
   gettext: MyApp.Gettext,
   data_dir: "./priv/cldr",
   precompile_number_formats: ["¤¤#,##0.##"],
   precompile_transliterations: [{:latn, :arab}, {:thai, :latn}],
   json_library: Poison

Configuration Keys

The configuration keys available for Cldr are:

Recompiling after a configuration change

Cldr includes a “compiler” that will detect locale configuration changes and compile the necessary components of Cldr that depend on that configuration. To make this automatic recompilation happen the [:cldr] compiler needs to be added to you mix.exs. For example:

  def project do
    [
      app: :app_name,
      ...
      compilers: Mix.compilers ++ [:cldr],
      start_permanent: Mix.env == :prod,
      deps: deps()
    ]
  end

Note the addition of [:cldr] as the last compiler on the list. This is a firm requirement.

Downloading Configured Locales

Cldr can be installed from either github or from hex.

Localizing and Formatting Numbers

The Cldr.Number module implemented in the ex_cldr_numbers package provides number formatting. The public API for number formatting is Cldr.Number.to_string/2. Some examples:

iex> Cldr.Number.to_string 12345
"12,345"

iex> Cldr.Number.to_string 12345, locale: "fr"
"12 345"

iex> Cldr.Number.to_string 12345, locale: "fr", currency: "USD"
"12 345,00 $US"

iex> Cldr.Number.to_string 12345, format: "#E0"
"1.2345E4"

iex(> Cldr.Number.to_string 1234, format: :roman
"MCCXXXIV"

iex> Cldr.Number.to_string 1234, format: :ordinal
"1,234th"

iex> Cldr.Number.to_string 1234, format: :spellout
"one thousand two hundred thirty-four"

See h Cldr.Number and h Cldr.Number.to_string in iex for further information.

Localizing Lists

The Cldr.List module provides list formatting and is implemented in the ex_cldr_lists package. The public API for list formating is Cldr.List.to_string/2. Some examples:

iex> Cldr.List.to_string(["a", "b", "c"], locale: "en")
"a, b, and c"

iex> Cldr.List.to_string(["a", "b", "c"], locale: "en", format: :unit_narrow)
"a b c"

iex> Cldr.List.to_string(["a", "b", "c"], locale: "fr")
"a, b et c"

Seer h Cldr.List and h Cldr.List.to_string in iex for further information.

Localizing Units

The Cldr.Unit module provides unit localization and is implemented in the ex_cldr_units package. The public API for unit localization is Cldr.Unit.to_string/3. Some examples:

  iex> Cldr.Unit.to_string 123, :gallon
  "123 gallons"

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

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

  iex> Cldr.Unit.to_string 1234, :megahertz
  "1,234 megahertz"

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

See h Cldr.Unit and h Cldr.Unit.to_string in iex for further information.

Localizing Dates, Times and DateTimes

Formatting of relative dates and date times is supported in the Cldr.DateTime.Relative module implemented in the ex_cldr_dates_times package. The public API is Cldr.DateTime.to_string/2 and Cldr.DateTime.Relative.to_string/2. Some examples:

  iex> Cldr.Date.to_string Date.utc_today()
  {:ok, "Aug 18, 2017"}

  iex> Cldr.Time.to_string Time.utc_now
  {:ok, "11:38:55 AM"}

  iex> Cldr.DateTime.to_string DateTime.utc_now
  {:ok, "Aug 18, 2017, 11:39:08 AM"}

  iex> Cldr.DateTime.Relative.to_string 1, unit: :day, format: :narrow
  {:ok, "tomorrow"}

  iex> Cldr.DateTime.Relative.to_string(1, unit: :day, locale: "fr")
  "demain"

  iex> Cldr.DateTime.Relative.to_string(1, unit: :day, format: :narrow)
  "tomorrow"

  iex> Cldr.DateTime.Relative.to_string(1234, unit: :year)
  "in 1,234 years"

  iex> Cldr.DateTime.Relative.to_string(1234, unit: :year, locale: "fr")
  "dans 1 234 ans"

Gettext Backend Pluralization Support

There is an experimental plurals module for Gettext called Cldr.Gettext.Plural. It is configured in Gettext by:

defmodule MyApp.Gettext do
  use Gettext, plural_forms: Cldr.Gettext.Plural
end

Cldr.Gettext.Plural will fall back to Gettext pluralisation if the locale is not known to Cldr. This module is only compiled if Gettext is configured as a dependency in your project.

Note that Cldr.Gettext.Plural does not guarantee to return the same plural index as Gettext‘s own pluralization engine which can introduce some compatibility issues if you plan to mix plural engines.

Plugs

Cldr provides two plugs to aid integration into an HTTP workflow. These two plugs are:

About Locale strings

Note that Cldr defines locale string according to the Unicode standard:

Testing

Tests cover the full 523 locales defined in CLDR. Since Cldr attempts to maximize the work done at compile time in order to minimize runtime execution, the compilation phase for tests is several minutes.

Tests are run on Elixir 1.5.x. Cldr will not run on Elixir version before 1.5.

Updating the CDLR data repository if installing from Github

The CLDR data is maintained in JSON format by the Unicode Consortium. The appropriate content is maintained as submodules in the data directory of this Cldr repository.

To update the CDLR data, git pull each of the submodules. For example:

git submodule -q foreach git pull -q origin master

After updating the respository, the locales need to be consolidated into the format used by Cldr. This is done by:

mix cldr.consolidate