CTAN Comprehensive TeX Archive Network

Directory macros/luatex/generic/lua-calendrica

README.md

lua-calendrica 0.2 2026-10-13

Lua port of the calendrical algorithms from Calendrical Calculations (4th edition) by Nachum Dershowitz and Edward M. Reingold.

Covers a wide range of calendars including Gregorian, Hebrew, Islamic, Persian, Chinese, Hindu (modern and old), Tibetan, Balinese, Mayan, Julian, Coptic, Ethiopic, French Revolutionary, Icelandic, Akan, Bahá'í, and more, along with astronomical calculations for sunrise, sunset, lunar phases, and solar terms.

Requirements

  • Lua 5.3 or later

Usage

High-level API

Dates

Dates are immutable value objects, tied to a calendar: a built-in one by name (see calendrica.calendars() for the full list), or a calendar object, e.g. one of your own made with calendrica.calendar{...}. The built-in names are fixed; nothing is registered under a name, so they cannot clash.

local calendrica = require("calendrica")

-- Create a date on one calendar and convert to another
local d = calendrica.date({year=2024, month=1, day=1}, "gregorian")
print(d)                       -- gregorian(year=2024, month=1, day=1, rd=738886)

-- Convert with date(...) or the :to / :as / :date methods (all equivalent)
local h = calendrica.date(d, "hebrew")
local h2 = d:to("hebrew")
print(h)                       -- hebrew(year=5784, month=10, day=20, rd=738886)
print(h.year, h.month, h.day)  -- 5784   10   20

-- Every date exposes .rd (its fixed Rata Die integer) and .calendar (an object)
print(d.rd, d.calendar.name)   -- 738886   gregorian

-- A date can also be built directly from an RD integer (the inverse of .rd)
print(calendrica.date(738886, "gregorian"))

Holidays

holiday and holidays take an optional trailing calendar (name or object) for the returned dates (default "gregorian").

-- Occurrences of a named holiday in a Gregorian year
print(calendrica.holiday("shavuot", 2026)[1])            -- gregorian(year=2026, month=5, day=22, rd=739758)

-- ...expressed in another calendar (same underlying day)
print(calendrica.holiday("shavuot", 2026, "hebrew")[1])  -- hebrew(year=5786, month=3, day=6, rd=739758)

-- All holidays in a year, sorted by date
for _, hol in ipairs(calendrica.holidays(2026)) do
  print(hol.name, hol.dates[1])
end

Astronomy

A location takes its time zone in hours from UTC. sunrise, sunset, moonrise and moonset return a moment: a date object that also carries a time-of-day (.hour, .minute, .second, .zone, and the fractional .moment).

local jerusalem = calendrica.location(31.78, 35.24, 754, 2)  -- lat, lon, elevation (m), UTC+2
print(jerusalem)               -- location(latitude=31.78, longitude=35.24, elevation=754, zone=UTC+2)

local sr = calendrica.sunrise(d, jerusalem)
print(sr)                      -- gregorian(year=2024, month=1, day=1, rd=738886, 06:33:32 UTC+2)
print(sr.hour, sr.minute)      -- 6   33
print(sr:to("hebrew"))         -- same moment, Hebrew calendar (time preserved)

-- These (and lunar_phase) also accept a plain RD integer
print(calendrica.sunrise(738886, jerusalem))
print(calendrica.lunar_phase(738886))   -- lunar phase in degrees (0 new, 180 full)

-- Dates of a lunar phase across a Gregorian year; optional calendar for the result
local full_moons = calendrica.lunar_phases(180, 2026)              -- Gregorian
local full_moons_hijri = calendrica.lunar_phases(180, 2026, "islamic")

Low-level API

Each calendar is also available as a standalone module:

local gregorian = require("calendrica-gregorian")
local hebrew    = require("calendrica-hebrew")

local fixed = gregorian.fixed_from_gregorian({2024, 1, 1})
local h     = hebrew.hebrew_from_fixed(fixed)
print(h[1], h[2], h[3])  -- year, month, day

The standalone modules sometimes have more functionality, such as leap year predicate.

Modules

Each module name links to its page in the API documentation.

Module Description
calendrica High-level API: date objects, calendar conversion, calendar objects, holidays
calendrica-akan Akan day-name calendar
calendrica-astro Astronomical calculations (solar, lunar, location)
calendrica-astronomical-lunar Observational lunar calendars (Babylonian, Samaritan, observational Islamic and Hebrew)
calendrica-bahai Bahá'í calendar (arithmetic and astronomical)
calendrica-balinese Balinese Pawukon calendar
calendrica-basic Core arithmetic and utility functions
calendrica-chinese Chinese, Japanese, Korean, and Vietnamese calendars
calendrica-coptic-ethiopic Coptic and Ethiopic calendars
calendrica-ecclesiastical Easter and Christian holidays
calendrica-egyptian-armenian Egyptian and Armenian calendars
calendrica-french-revolutionary French Revolutionary calendar
calendrica-gregorian Gregorian calendar
calendrica-hebrew Hebrew calendar
calendrica-icelandic Icelandic calendar
calendrica-islamic Arithmetic Islamic calendars and tabular variants (TBLA, Umm al-Qura, Turkish/Diyanet)
calendrica-iso ISO week calendar
calendrica-julian Julian calendar and Roman dates
calendrica-mayan Mayan and Aztec calendars
calendrica-modern-civil Modern civil calendars not in the book: Indian National (reformed Śaka), Minguo/ROC, Thai solar (Buddhist Era), revised Bengali, Nanakshahi, Amazigh (Berber), Japanese era (nengō)
calendrica-modern-hindu Modern Hindu solar and lunar calendars
calendrica-old-hindu Old Hindu solar and lunar calendars
calendrica-persian Astronomical and arithmetic Persian calendars
calendrica-tibetan Tibetan calendar

Testing

The tests run with l3build in plain Lua and compare the results with values computed by the book's own code, the authors' calendar.l (from calendar-code2), with the corrections of the book's errata list applied. These values are not in the repository; compute them first (needs SBCL and curl):

l3build reference   # writes testfiles/support/reference.lua
l3build check

l3build reference downloads calendar.l into build/ and runs reference.lisp on it; run it again only after changing reference.lisp.

Documentation

API documentation is available at https://polyglossia.codeberg.page/lua-calendrica/topics/manual.md.html#

The site also has Calendars and Holidays pages listing all built-in calendars and holidays.

Repository

Maintainer

Udi Fogiel <udifogiel@proton.me>

License

The algorithms are ported from CALENDRICA 4.0, which is licensed under the Apache License 2.0. See the source files for details.

Download the contents of this package in one zip archive (168.9k).

Lua-calendrica – Lua implementation of Calendrical Calculations by Dershowitz & Reingold

This is a Lua port of the calendrical algorithms from Calendrical Calculations (4th edition) by Nachum Dershowitz and Edward M. Reingold.

It covers a wide range of calendars including Gregorian, Hebrew, Islamic, Persian, Chinese, Hindu (modern and old), Tibetan, Balinese, Mayan, Julian, Coptic, Ethiopic, French Revolutionary, Icelandic, Akan, Bahá’í, and more, along with astronomical calculations for sunrise, sunset, lunar phases, and solar terms.

PackageLua-calendrica
Bug tracker
Repository
Version0.2 2026-10-13
LicensesApache License, version 2.0
MaintainerUdi Fogiel
Contained inTeX Live as lua-calendrica
MiKTeX as lua-calendrica
TopicsGeneric Macros
Lua
Calendar
...
Guest Book Sitemap Contact Contact Author