Ex_cldr - Common Locale Data Repository (CLDR) functions for Elixir

I second this. And for all the generous support that comes with it!

1 Like

TLDR; I plan to delay releases of ex_cldr libraries based upon CLDR 44 that is due to drop in October by 6-8 weeks to complete some refactoring and ready ex_cldr_person_names for release. Please let me know if this causes you an issue.

CLDR version 44 will be out of beta soon and my usual practise is to ensure that ex_cldr and related libraries are updated and available the same day.

This time I propose to hold off a new release cycle for a few weeks in order to complete the following:

  1. ex_cldr_person_names which requires some rework given the revised specification for CLDR 44. I think this is going to be a very useful library so I also want to make sure it passes all the conformance tests at 100%.
  2. Update ex_cldr_units to separate localisation from unit manipulation. And in particular to refactor the whole algebra engine so it works correctly. This was a kind of experimental feature but it shouldn’t be.
  3. Add an integration test suite that is basically an app that configures all locales with all backends. This will detect, at least at a compile time level, any incompatibilities.
  4. Fix or close the 9 outstanding issues agains the approx. 40 repositories in the family.

I expect this will take about 6 to 8 weeks to complete. I am looking for feedback as to whether this is ok for you. If you have any immediate need for an interim release of a CLDR 44-based version then please let me know. I have done preliminary integration of the last few betas and there aren’t any blocking issues so far.

Many thanks to everyone that has been supporting this endeavour which is now in its 8th year and which continues to see community adoption (its going to hit 3m downloads this week. The first 1m took 5 years, the second took 2 years and the third just about a year).

5 Likes

I’ve published new versions of several of the ex_cldr_* libraries in the last 24 hours to remove any warnings on Elixir 1.16. Some of the less-used libraries I still need to review.

If anyone finds any Elixir 1.16 warnings being emitted for any ex_cldr_* library, please do open an issue - I would be greatly appreciated.

My goal is to always have zero regressions, errors or warnings on Day #1 when a new Elixir release is officially published.

3 Likes

CLDR 45 was released on April 17th and now the updated ex_cldr libraries have been published. This release cycle has minimal changes to the underlying locale data.

New Person Name Formatting

This release cycle also sees the introduction of a new Person Name Formatting library, unsurprisingly called ex_cldr_person_names. This continues the efforts of the CLDR team to simplying localisation of applications to create a more personal and engaging experience.

I had the opportunity to introduce this new library at the Sydney Elixir Meetup and a video of that presentation is available on Youtube. The associated slides are also available in Powerpoint format and PDF format.

There is also a Livebook you can experiment with:

Run in Livebook

Elixir Mix Interview on CLDR and ex_cldr

The team at Elixir Mix kindly invited me to their podcast which was great fun. The podcast episode is now available online.

What’s next?

Attention now turns to the following priorities:

  • Fix adding custom units in ex_cldr_units. This is a long-standing issue that has been very difficult to pin down. It’s the next immediate priority.

  • Fix (actually, properly implement) the arithmetic operators in Cldr.Unit.Math. I really made a mess of this implementation and it simply doesn’t do the right thing. I will get this fixed next.

  • Add an implementation of the new Message Format 2 to ex_cldr_messages. This time it looks like the CLDR community, including the big players, are committed to standardising on this message format.

  • Revisit collations. It’s time I got this properly done.

Other library updates

As usual, several ex_cldr-related libraries have been updated. Here’s the brief changlog entries for the key libraries:

ex_cldr

  • Update to CLDR 45.0 data.

  • Adds Cldr.validate_locale!/2. Thanks to @jarrodmoldrich for the suggestion.

  • Add decimal separator and grouping separator to the currency data for each locale. In some rare cases, like the currency CVE in the locale pt-CV the currency symbol is placed where decimal separator is normally placed. The same can apply for the grouping separator although it appears no locale uses this field.

  • Adjust the Inspect protocol implementation for t:Cldr.LanguageTag.t/0 types. When the language tag is resolved to a CLDR locale then the output is executable code. For example:

iex> MyApp.Cldr.Locale.new!("en-US")
MyApp.Cldr.Locale.new!("en-US")
  • Fix dialyzer warnings. Thanks to @Munksgaard for the PR. Closes #220. Also fixes :underspecs warning and the :underspecs dialyzer flag is now configured.

  • Add configuration for the new ex_cldr_person_names backend module generator.

ex_cldr_numbers

  • Update to CLDR 45.0 data.

  • Support currency formatting when the given currency in a given locale uses a specific symbol that replaces the decimal separator. The only known example is the Cape Verde escudo. A formatted example formatting 20 CVE is 20$00.

ex_cldr_dates_times

  • Fix formatting with formats that have may have pluralization like the :MMMMW and :yw formats.

  • Fix :underspecs for dialyzer.

  • Update to CLDR 45.0 data.

  • Adds support for formats that have both unicode whitespace and ascii whitespace versions. The option :prefer is added to Cldr.DateTime.to_string/3. The default is prefer: :unicode. The option prefer: :ascii is included for backwards compatibility of older applications. The formats that provide both :unicode and :ascii versions can be seen from the results of Cldr.DateTime.Format.date_time_available_formats/2.

ex_cldr_units

  • Fixes canonical unit name formation. More units can now be resolved to a base unit and therefore compared and converted with other units. The primary change is to add elimination of common factors in ā€œperā€ units.

  • Add conversion support for Beaufort. This conversion is non linear and therefore cannot be expressed using the normal unit conversion method.

  • Cldr.Unit.Math.mult/2 and Cldr.Unit.Math.div/2 now support scalar values as the second argument. Its therefore now possible to say Cldr.Unit.Math.mult(Cldr.Unit.new!(:meter, 10), 2).

ex_money

  • Money.sum/2 default exchange rates is always %{} even if the exchange rate server is not running. Thanks to @haste for the report. Closes #168.

  • When parsing numbers, use the localized number system separators where they exist. Thanks to @pshoukry for the report. Closes #167.

  • Surface errors when starting the exchange rates retrieveer. Thanks to @danschultzer for the PR. Closes #165.

  • Update to CLDR 45.0 data.

  • Return structured errors for Money.ExchangeRates.latest_rates/0, Money.ExchangeRates.historic_rates/1, Money.ExchangeRates.last_updated/0 and Money.ExchangeRates.latest_rates_available?/0 when the exchange rates retrieval process is not running.

12 Likes

Thank you for your great work, as always!

2 Likes

Thanks @kip for the fix!

I am so embarrassed that I’ve thought for years that CLDR is just short for calendar and there’s no need for me to look into that…

3 Likes

After a long period of reflection, I have decided to embark on ex_cldr version 3.0. There are several objectives and there’s a full writeup in the github discussion.

The primary changes will be:

  • Rename to localize to better reflect the libraries intent and to improve discoverability
  • Remove the ā€œbackendā€ approach to hosting CLDR data (this is the main architectural change that will enable runtime locale configuration and improve compilation times significantly)
  • Separate core CLDR data ingestion into a standalone library
  • Simplify library packaging and testing. For example, I might combine current ex_cldr , ex_cldr_numbers , ex_cldr_currencies , ex_cldr_dates_times , ex_cldr_calendars , ex_cldr_units (formatting only), ex_cldr_territories and ex_cldr_languages into a single library.
  • Use canonical Elixir error and exception handling
  • Leverage the emerging type system
  • Build a new translator library and ecosystem
  • Re-implement units of measure
  • Fill out the missing pieces of CLDR (collations, transforms, …)

I will continue to support and update ex_cldr 2.x for the foreseeable future - and of course until at least localize 1.0 is ready. Which I anticipate to be towards the end of 2025.

The user-facing API should also be sufficiently similar for a shim library to be able to aid migration to the new set of libraries.

10 Likes

Enjoying your continuously work on ex_cldr a LOT!

1 Like

Last week, Unicode released CLDR 47. Any affected ex_cldr_* libraries have now been updated and are available for use.

Major features of CLDR 47

  • [Not available in ex_cldr yet] MessageFormat has advanced from Final Candidate to Stable. For details, see below.
  • New locales:
    • Core data for Coptic (cop), Haitian Creole (ht)
    • Locale data for 11 English locales and Cantonese (Macau) (yue_Hant_MO)
  • Updated time zone data to tzdata 2025a
  • RBNF (Rule Based Number Formatting): Number spellout data improvements for multiple languages
  • Assorted transforms improvements
  • Updated and revised population data
  • [No library in ex_cldr] Addition of derived emoji annotations that were missing: emoji with skin tones facing right
  • Fixes to make the ja, ko, yue, zh datetimeSkeletons useful for generating the standard patterns
  • Improved date/time test data

Updated libraries

Several add-on calendars and calendar-related libraries are also updated and several moved to 1.0.0 release status:

Other ex_cldr_* libraries do not currently appear to require any update (I’m still testing the various add-on calendars). Please open issues if you find a bug!

8 Likes

Thanks for all the amazing work you do on the ex_cldr_* libraries!

5 Likes

I’ve published updates to ex_cldr, ex_cldr_numbers, ex_cldr_units and ex_cldr_calendars to be compatible with the upcoming Elixir 1.19 and also with OTP 28.

If I’ve done my job properly then you won’t see any differences with one small exception. The updated OTP re module upon which Elixir’s Regex module is based, is not 100% compatible with previous versions. For the ex_cldr_* libraries there are two considerations:

  1. Assigning compiled regular expressions to a module attribute and then unquoting them into code is not supported. There are quite a few of these in ex_cldr_* and they’ve all been replaced with runtime compilation. I have not assessed if this creates material performance impacts but I suspect not.
  2. The version of Unicode used by the old/current :re module is Unicode 7.0 from 2014 (thanks @adamu). The Bitcoin symbol ₿ was introduced in Unicode 10 in 2017. The consequence is that if you’re formatting money with a bitcoin currency symbol, the formatting will be ever so slightly different between OTP 27 and OTP 28.
6 Likes