kip
Calendrical - over 17 localised calendar implementations and date/time parsing
Somehow I missed introducing Calendrical, which implements a significant number of the calendars used around the world. Its the spiritual successor to ex_cldr_calendars and friends, but it also several additional calendars like:
- Buddhist
- Hebrew
- Islamic - Civil, Observational, Rgsa, Tbla and Um Al Qura (including a version based upon the published tables and a version based upon astronomical calculation)
- Indian
New Date, Time, DateTime and Interval string parsers
New in Calendarical version 0.6.0 published today is flexible date/time parsing.
If you’ve got user-typed date/time strings coming in from a form, an import, or a chat command, this should save you some pain.
There’s a single entry point — Calendrical.parse/2 — that figures out what kind of value you typed and dispatches to the right sub-parser:
iex> Calendrical.parse("2026-05-16", locale: :en)
{:ok, ~D[2026-05-16]}
iex> Calendrical.parse "23 May"
{:ok, ~D[2026-05-23]}
iex> Calendrical.parse("14:30", locale: :en)
{:ok, ~T[14:30:00]}
iex> Calendrical.parse("May 16, 2026, 2:30 PM", locale: :en)
{:ok, ~N[2026-05-16 14:30:00]}
iex> Calendrical.parse("May 5, 2026 – May 10, 2026", locale: :en)
{:ok, Date.range(~D[2026-05-05], ~D[2026-05-10])}
Parsing is locale aware
Every parser reads CLDR data, so the same string may parse differently depending on the locale you pass:
iex> Calendrical.Date.parse("3/4/26", locale: :en)
{:ok, ~D[2026-03-04]}
iex> Calendrical.Date.parse("3/4/26", locale: :"en-GB")
{:ok, ~D[2026-04-03]}
iex> Calendrical.Date.parse("16.05.2026", locale: :de)
{:ok, ~D[2026-05-16]}
iex> Calendrical.parse "23 mai", locale: :fr
{:ok, ~D[2026-05-23]}
iex> Calendrical.Time.parse("2:30 PM", locale: :en)
{:ok, ~T[14:30:00]}
iex> Calendrical.Time.parse("14:30", locale: :de)
{:ok, ~T[14:30:00]}
Parsing supports any known calendar
Pass :calendar to interpret input pretty much all of the worlds major calendars — Gregorian, Buddhist, Japanese imperial, Islamic, Hebrew, Persian, ROC, Coptic, Ethiopic, Indian, and more. The returned Date is in that calendar:
iex> Calendrical.Date.parse("2026-05-16", calendar: Calendrical.Hebrew)
{:ok, ~D[5786-09-29 Calendrical.Hebrew]}
iex> Calendrical.Date.parse("民國115年5月16日", locale: :"zh-Hant-TW", calendar: Calendrical.Roc)
{:ok, ~D[0115-05-16 Calendrical.Roc]}
iex> Calendrical.Date.parse("令和6年7月1日", locale: :"ja-JP", calendar: Calendrical.Japanese)
{:ok, ~D[2024-07-01 Calendrical.Japanese]}
iex> Calendrical.Date.parse("١٧ رمضان ١٤٣٥ هـ", locale: :"ar-SA", calendar: Calendrical.Islamic.Civil)
{:ok, ~D[1435-09-17 Calendrical.Islamic.Civil]}
iex> Calendrical.Date.parse("1 ก.ค. 2567", locale: :"th-TH", calendar: Calendrical.Buddhist)
{:ok, ~D[2567-07-01 Calendrical.Buddhist]}
Parsing date ranges
Date ranges follow the same calendar rule — Date.Range works in any calendar, not just Calendar.ISO:
iex> Calendrical.Date.parse_range({"2026-05-05", "2026-05-10"}, calendar: Calendrical.Buddhist])
{:ok, Date.range(~D[2569-05-05 Calendrical.Buddhist], ~D[2569-05-10 Calendrical.Buddhist])}
iex> Calendrical.Date.parse_range("May 5 – May 10, 2026", locale: :en)
{:ok, Date.range(~D[2026-05-05], ~D[2026-05-10])}
That last example also shows CLDR interval-skeleton inheritance — the left endpoint has no year, so it inherits 2026 from the right.
Going directly to the individual parsers
If you already know the shape of your input, skip Calendrical.parse/2 and call the relevant parser directly:
Calendrical.Date.parse/2Calendrical.Time.parse/2Calendrical.DateTime.parse/2Calendrical.Date.parse_range/2
Each accepts :locale, :calendar (where applicable), and a few specialised options like :allow_inverted for ranges and :reference_date for two-digit-year pivoting.
Links
Most Liked
netoum
Thank you for providing all the Localize libraries. Amazing job, they work great and make the dev life much easier.
Just noticed the GitHub link in the post is not working however the GitHub link in the hex package is working.
Last Post!
kip
I’ve published Calendrical version 0.11.0 the is primarily about robustness, conformance and code quality. It’s based upon Localize version 0.45.0 also released today and which is also focus on robustness, conformance and code quality.
The changelog contains notes on all of the changes.
I expect Calendrical to be a stable release now and the next release will be a 1.0 candidate release, following Localize around the end of July.
Popular in Announcing
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









