--- Akan day-name calendar. -- Ported from "Calendrical Calculations" (4th edition) -- by Nachum Dershowitz and Edward M. Reingold. -- Original Lisp code (CALENDRICA 4.0) is Apache 2.0 licensed. -- @module calendrica-akan -- @release 0.1 2026-07-19 local M = {} local basic = require("calendrica-basic") -- === Epoch === -- RD date of Akan day-name epoch. local AKAN_DAY_NAME_EPOCH = basic.rd(37) -- === Name constructor and accessors === local function akan_name(prefix, stem) return {prefix, stem} end local function akan_prefix(name) return name[1] end local function akan_stem(name) return name[2] end -- n-th name of the 42-day Akan cycle. local function akan_day_name(n) return akan_name(basic.amod(n, 6), basic.amod(n, 7)) end -- Days from a_name1 to the next occurrence of a_name2. local function akan_name_difference(a_name1, a_name2) local prefix1 = akan_prefix(a_name1) local prefix2 = akan_prefix(a_name2) local stem1 = akan_stem(a_name1) local stem2 = akan_stem(a_name2) local prefix_difference = prefix2 - prefix1 local stem_difference = stem2 - stem1 return basic.amod( prefix_difference + 36 * (stem_difference - prefix_difference), 42 ) end --- Akan day name for fixed `date`. -- @tparam number date Fixed date. -- @treturn table {prefix, stem} function M.akan_name_from_fixed(date) return akan_day_name(date - AKAN_DAY_NAME_EPOCH) end local akan_name_from_fixed = M.akan_name_from_fixed -- Latest date on or before date with the given Akan name. local function akan_day_name_on_or_before(name, date) return basic.mod3( akan_name_difference(akan_name_from_fixed(0), name), date, date - 42 ) end -- === Exports === --- The n-th name of the 42-day Akan cycle. -- @function akan_day_name -- @tparam number n Position in cycle. -- @treturn table {prefix, stem} M.akan_day_name = akan_day_name --- Days from `a_name1` to the next occurrence of `a_name2` in the Akan cycle. -- @function akan_name_difference -- @tparam table a_name1 Akan name {prefix, stem}. -- @tparam table a_name2 Akan name {prefix, stem}. -- @treturn number Count (1..42). M.akan_name_difference = akan_name_difference --- Latest fixed date on or before `date` with the given Akan `name`. -- @function akan_day_name_on_or_before -- @tparam table name Akan name {prefix, stem}. -- @tparam number date Fixed date. -- @treturn number Fixed date. M.akan_day_name_on_or_before = akan_day_name_on_or_before return M