--- Akan day-name calendar. -- A day name is a pair {prefix, stem} of two concurrent cycles; the -- pairs repeat every 42 days (the adaduanan). -- -- * `prefix` (1..6): the day of the six-day cycle, the nnanson. -- * `stem` (1..7): the day of the seven-day week, the nnawɔtwe, which -- follows the Gregorian week: 1 Wednesday, 2 Thursday, 3 Friday, -- 4 Saturday, 5 Sunday, 6 Monday, 7 Tuesday. -- -- Both are numbers; names are left to the caller. -- 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.2 2026-10-13 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}: the day of the nnanson (1..6) and of -- the nnawɔtwe (1..7, 1 = Wednesday). 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