Localize - next generation localisation (ex_cldr v3.0)

Next up in calendrical. I’ve always been fascinated by calendars and time keeping.While ex_cldr_calendars has done a solid job for many years, it was never complete in my eyes. Calendrical is definitely next generation.

Lunar calendars

While we had solar and lunisolar calendars for a some time now (which enables Persian, Chinese/Japanese/Korean calendars), we didn’t have support for lunar calendars (used to support Islamic and Hebrew calendars). That required a lot of work in Astro to support moonrise and moonset. And also to do simulated lunar crescent detection. As a result, the moonrise/set functional accuracy is as good as it gets and the Islamic and Hebrew calendars are as accurate as they can practically be.

Composable calendars

This is special-purpose calendar in which you actually compose a set of calendars. It’s particularly useful if you’re doing historical research and you need to track when the switch from Julian to Gregorian calendars occurred. It’s very niche. But it’s also very cool.

User-defined calendars

This is made very easy by having a simple use Calendrical macro in a module and defining a few parameters. Lets you build almost any variant of a month-based or week-based calendar, Including calendars with leap years. And not only Gregorian calendars - you can override functions to have the behaviour you want. In fact most calendars in the library are defined this way now.

Calendrical Features

  • 17 CLDR-aligned calendar implementations — Gregorian, Persian, Coptic, Ethiopic (two eras), Japanese, Chinese, Korean (Dangi), Lunar Japanese, four Islamic variants (Civil, TBLA, Umm al-Qura, observational), Hebrew, Buddhist, Republic of China (Minguo), Indian National (Saka), and Julian.

  • Calendrical.Behaviour — a defmacro __using__ template that supplies default implementations of every Calendar and Calendrical callback. Users can define a new calendar in 60–200 lines by overriding only the parts that differ from the defaults.

  • Composite calendarsCalendrical.Composite lets you build a calendar that uses one base calendar before a specified date and another after, supporting historical Julian-to-Gregorian transitions and similar splices.

  • Localized formatting — era names, quarter names, month names, day names, day periods (AM/PM), and full date formatting via Calendrical.localize/3 and Calendrical.strftime_options!/1. Falls through to all 766+ CLDR locales available from Localize.

  • Fiscal-year calendars — pre-built fiscal calendars for ~50 territories (US, UK, AU, JP, …) plus a configurable Calendrical.FiscalYear.calendar_for/1 factory.

  • Date arithmetic — the standard Date.shift/2 and NaiveDateTime.shift/2 work across every Calendrical calendar.

  • Date intervalsCalendrical.Interval returns Date.Range values for years, quarters, months, weeks, and days in any supported calendar, with relation/2 implementing Allen’s interval algebra.

  • k-day calculationsCalendrical.Kday finds the n-th occurrence of a given weekday relative to a date (e.g. “the second Tuesday in November”).

  • Calendar formattersCalendrical.Format and Calendrical.Formatter provide a behaviour-based plugin system for rendering calendars as HTML, Markdown, or any custom format.

  • Astronomical calendar support — observational lunar calendars (Persian, Chinese, Korean, Lunar Japanese, observational Islamic, Saudi Rgsa, astronomical Umm al-Qura) use the Astro library for equinox, lunar phase, and crescent visibility calculations.

  • Ecclesiastical calendarsCalendrical.Ecclesiastical provides Reingold-style algorithms for the movable and fixed Christian feasts of three different traditions: Western (easter_sunday/1, good_friday/1, pentecost/1, advent/1, christmas/1, epiphany/1), Eastern Orthodox (orthodox_easter_sunday/1, orthodox_good_friday/1, orthodox_pentecost/1, orthodox_advent/1, eastern_orthodox_christmas/1), and astronomical (astronomical_easter_sunday/1, astronomical_good_friday/1, paschal_full_moon/1 — the WCC 1997 proposed reckoning).

  • Sigils — every Calendrical calendar works with Elixir’s native ~D/~U/~N sigils via the standard calendar suffix: ~D[2024-09-01 Calendrical.Hebrew], ~D[1446-09-01 Calendrical.Islamic.UmmAlQura].

11 Likes