Module calendrica
High-level calendar and date API.
A date is an immutable value tied to a calendar, created with date or today.
A calendar is given either by the name of a built-in one — a string such as
"gregorian", "hebrew", or "islamic-umalqura" — or as a calendar object, from
calendar(name) or made with calendar{…} for a calendar of your own. The built-in
names are fixed: nothing can be registered under a name, so they always mean the same.
A date exposes its calendar fields (year, month, day, …), its fixed Rata Die day
number .rd, and its calendar object .calendar (with .name and .granularities),
and can be re-expressed in another calendar with d:to(cal) (also d:as(cal) /
d:date(cal)), which returns a new date.
The astronomical functions (sunrise, sunset, moonrise, moonset) return a
moment — a date that also carries a time-of-day, adding .hour, .minute,
.second, .zone (UTC offset), and the fractional .moment. A plain date has no
time-of-day, so those read nil on it.
See the Manual for a guided introduction, and the Calendars and Holidays pages for the full lists.
Usage:
local calendrica = require("calendrica")
local d = calendrica.date({year=2024, month=4, day=23}, "gregorian")
local h = calendrica.date(d, "hebrew") -- the same day in the Hebrew calendar
print(d, h)
Info:
- Release: 0.2 2026-09-21
| calendar (spec) | A calendar object: a built-in calendar by name, or a new calendar. |
| date (source, calendar) | Express a date in a calendar (a built-in name or a calendar object). |
| today ([calendar]) | Return today’s date in the given calendar. |
| holiday (name, g_year[, calendar]) | Return occurrences of a built-in holiday in a Gregorian year as date objects. |
| holidays (g_year[, calendar]) | Return all built-in holidays occurring in a Gregorian year, sorted by date. |
| holiday_names () | Return a sorted list of the built-in holiday names. |
| calendars () | Return a sorted list of the built-in calendar names. |
| location (latitude, longitude, elevation, zone) | Construct a location for use with astronomical functions. |
| lunar_phase (date) | Lunar phase (0–360°) at midnight of date. |
| lunar_phases (phase, g_year[, calendar]) | List of date objects on which the moon reaches lunar phase phase during
Gregorian year g_year. |
| sunrise (date, loc) | Sunrise on date at loc as a moment, or nil if the sun does not rise. |
| sunset (date, loc) | Sunset on date at loc as a moment, or nil if the sun does not set. |
| moonrise (date, loc) | Moonrise on date at loc as a moment, or nil if the moon does not rise. |
| moonset (date, loc) | Moonset on date at loc as a moment, or nil if the moon does not set. |
- calendar (spec)
-
A calendar object: a built-in calendar by name, or a new calendar.
calendar(name)returns the built-in calendarname(e.g."hebrew"), ornilif there is none; see calendars.calendar{name = …, granularities = {…}, from_rd = f, to_rd = g}makes a new calendar.granularitiesis the ordered list of field names;from_rdmaps an RD to a positional table of fields andto_rd(optional) maps a positional table back to an RD — the field names are matched to those positions. Omitto_rdfor a read-only calendar, one that cannot be used to construct a date from fields.nameis only for display (tostring); it is not registered, so a calendar of your own never clashes with a built-in one or another package’s.
A calendar object can be passed wherever a calendar name can. It is read-only and has the fields
nameandgranularities.Parameters:
Returns:
-
table or nil
Calendar object (nil for an unknown name).
Raises:
If a definition lacksgranularitiesorfrom_rd.Usage:
local hebrew = calendrica.calendar("hebrew")
local mine = calendrica.calendar{name = "mine", granularities = {"year", "day"}, from_rd = function(rd) return {rd // 365, rd % 365} end}
- date (source, calendar)
-
Express a date in a calendar (a built-in name or a calendar object).
The first argument is one of:
- a field table — named fields interpreted in the given calendar, e.g.
date({year=2024, month=1, day=1}, "gregorian"); - an existing date (from date or today), re-expressed in the given calendar,
e.g.
date(d, "hebrew"); - a fixed Rata Die integer, e.g.
date(739758, "gregorian")(the inverse of.rd).
Parameters:
- source table or number Field table, date object, or RD integer.
- calendar
string or table
Calendar name (e.g.
"gregorian"; see calendars) or calendar object.
Returns:
-
table
Date object. Fields are accessible by name (e.g.
d.year).Raises:
If the calendar is unknown, if constructing from fields on a read-only calendar, or ifsourceis not a date object, field table, or RD integer. - a field table — named fields interpreted in the given calendar, e.g.
- today ([calendar])
-
Return today’s date in the given calendar.
Parameters:
Returns:
-
table
Date object for today.
Raises:
If the calendar name is unknown. - holiday (name, g_year[, calendar])
-
Return occurrences of a built-in holiday in a Gregorian year as date objects.
Parameters:
- name
string
Holiday name (e.g.
"easter","hanukkah"). See holiday_names for the full list. - g_year number Gregorian year.
- calendar
string or table
Calendar name or object for the returned dates.
Defaults to
"gregorian". (optional)
Returns:
-
{table,...}
List of date objects (may be empty if the holiday does
not fall in the given year).
Raises:
Ifnameis not a built-in holiday, or calendar is unknown. - name
string
Holiday name (e.g.
- holidays (g_year[, calendar])
-
Return all built-in holidays occurring in a Gregorian year, sorted by date.
Parameters:
- g_year number Gregorian year.
- calendar
string or table
Calendar name or object for the returned dates.
Defaults to
"gregorian". (optional)
Returns:
-
{{name=string,dates={table,...}},...}
List of
{name, dates}records, one per holiday that has at least one occurrence in the year.Raises:
If calendar is unknown. - holiday_names ()
-
Return a sorted list of the built-in holiday names.
Returns:
- calendars ()
-
Return a sorted list of the built-in calendar names.
calendar(name)gives each one’s object, with its ordered field names in.granularities.Returns:
Usage:
for _, name in ipairs(calendrica.calendars()) do print(name, table.concat(calendrica.calendar(name).granularities, ", ")) end
- location (latitude, longitude, elevation, zone)
-
Construct a location for use with astronomical functions.
Parameters:
- latitude number Degrees north (negative = south); any value, folded over the poles onto [-90, 90].
- longitude number Degrees east (negative = west); any value, wrapped into [-180, 180).
- elevation number Metres above sea level (negative below).
- zone
number
UTC offset in hours (e.g. 2 for UTC+2, 5.5 for UTC+5:30). This isa raw offset — it is used only to shift between universal and standard time, so a value beyond the usual civil range (-12 to 14) simply shifts the moment (past ±24 h, the day).
Returns:
-
table
Location object with fields
.latitude,.longitude,.elevation,.zone. - lunar_phase (date)
-
Lunar phase (0–360°) at midnight of date.
0 = new moon, 90 = first quarter, 180 = full moon, 270 = last quarter.
Parameters:
- date table or number A date object or an RD integer.
Returns:
-
number
Degrees.
- lunar_phases (phase, g_year[, calendar])
-
List of date objects on which the moon reaches lunar phase
phaseduring Gregorian yearg_year.Note: this function’s name is provisional and likely will change in a future version.
Parameters:
- phase number Lunar phase in degrees: 0 = new moon, 90 = first quarter, 180 = full moon, 270 = last quarter.
- g_year number Gregorian year.
- calendar
string or table
Calendar name or object for the returned dates.
Defaults to
"gregorian". (optional)
Returns:
-
{table,...}
Date objects, one per occurrence.
Raises:
If calendar is unknown.Usage:
local new_moons = calendrica.lunar_phases(0, 2026)
local full_moons = calendrica.lunar_phases(180, 2026) TODO: the name lunar_phases is provisional — it takes a phase and returns dates, so it reads as a near-inverse of lunar_phase; revisit before a stable release.
- sunrise (date, loc)
-
Sunrise on date at
locas a moment, or nil if the sun does not rise. The result is a date object (in date’s calendar, or Gregorian if date is an RD integer) carrying the time-of-day:.hour,.minute,.second,.zone, and the fractional.moment. Reproject it to another calendar with:to(name)and the time is preserved.Parameters:
Returns:
-
table or nil
Moment date object, or nil.
- sunset (date, loc)
-
Sunset on date at
locas a moment, or nil if the sun does not set. See sunrise for the returned moment’s fields.Parameters:
Returns:
-
table or nil
Moment date object, or nil.
- moonrise (date, loc)
-
Moonrise on date at
locas a moment, or nil if the moon does not rise. See sunrise for the returned moment’s fields.Parameters:
Returns:
-
table or nil
Moment date object, or nil.
- moonset (date, loc)
-
Moonset on date at
locas a moment, or nil if the moon does not set. See sunrise for the returned moment’s fields.Parameters:
Returns:
-
table or nil
Moment date object, or nil.