Module:Roman Date
Revision as of 20:25, 15 February 2024 by 2.124.47.92 (talk)
This module implements the {{Roman Date}} template. For behavioural documentation, please see the template page.
- This module supports dates formatted in the form YYYY-MM-DD or MM-DD
- This is a new module and may be subject to bugs, to report bugs please use the discord
- This module also supports leap years
Known Bugs
- Doesn't check for dates that are past the maximum number of days in a month
- Doesn't check for dates below 1 and thus may fail
-- This Module implements {{Roman Date}}
local numeral = require("Module:Roman Numeral")
local p = {}
local function month_ides_lookup(month)
if month == 3 then
return 15
elseif month == 5 then
return 15
elseif month == 7 then
return 15
elseif month == 10 then
return 15
else
return 13
end
end
local function checkLeapYear(year)
return (((year % 4 == 0) and (year % 100 ~= 0)) or (year % 400 == 0));
end
local function _main(args)
local months = {
accusative = {
'Januarias',
'Februarias',
'Martias',
'Apriles',
'Maias',
'Junias',
'Julias',
'Augustas',
'Septembres',
'Octobres',
'Novembres',
'Decembres'
},
ablative = {
'Januariis',
'Februariis',
'Martiis',
'Aprilibus',
'Maiis',
'Juniis',
'Juliis',
'Augustis',
'Septembribus',
'Octobribus',
'Novembribus',
'Decembribus'
}
}
local dayLookup = { { 'Kal. ', 'Kal. ', 'Kal. ', 'Kal. ', 'Kal. ', 'Kal. ', 'Kal. ', 'Kal. ', 'Kal. ', 'Kal. ', 'Kal. ', 'Kal. ', 'Kal. ' }, { 'a.d. IV Non. ', 'a.d. IV Non. ', 'a.d. VI Non. ', 'a.d. IV Non. ', 'a.d. VI Non. ', 'a.d. IV Non. ', 'a.d. VI Non. ', 'a.d. IV Non. ', 'a.d. IV Non. ', 'a.d. VI Non. ', 'a.d. IV Non. ', 'a.d. IV Non. ', 'a.d. IV Non. ' }, { 'a.d. III Non. ', 'a.d. III Non. ', 'a.d. V Non. ', 'a.d. III Non. ', 'a.d. V Non. ', 'a.d. III Non. ', 'a.d. V Non. ', 'a.d. III Non. ', 'a.d. III Non. ', 'a.d. V Non. ', 'a.d. III Non. ', 'a.d. III Non. ', 'a.d. III Non. ' }, { 'pr. Non. ', 'pr. Non. ', 'a.d. IV Non. ', 'pr. Non. ', 'a.d. IV Non. ', 'pr. Non. ', 'a.d. IV Non. ', 'pr. Non. ', 'pr. Non. ', 'a.d. IV Non. ', 'pr. Non. ', 'pr. Non. ', 'pr. Non. ' }, { 'Non. ', 'Non. ', 'a.d. III Non. ', 'Non. ', 'a.d. III Non. ', 'Non. ', 'a.d. III Non. ', 'Non. ', 'Non. ', 'a.d. III Non. ', 'Non. ', 'Non. ', 'Non. ' }, { 'a.d. VIII Id. ', 'a.d. VIII Id. ', 'pr. Non. ', 'a.d. VIII Id. ', 'pr. Non. ', 'a.d. VIII Id. ', 'pr. Non. ', 'a.d. VIII Id. ', 'a.d. VIII Id. ', 'pr. Non. ', 'a.d. VIII Id. ', 'a.d. VIII Id. ', 'a.d. VIII Id. ' }, { 'a.d. VII Id. ', 'a.d. VII Id. ', 'Non. ', 'a.d. VII Id. ', 'Non. ', 'a.d. VII Id. ', 'Non. ', 'a.d. VII Id. ', 'a.d. VII Id. ', 'Non. ', 'a.d. VII Id. ', 'a.d. VII Id. ', 'a.d. VII Id. ' }, { 'a.d. VI Id. ', 'a.d. VI Id. ', 'a.d. VIII Id. ', 'a.d. VI Id. ', 'a.d. VIII Id. ', 'a.d. VI Id. ', 'a.d. VIII Id. ', 'a.d. VI Id. ', 'a.d. VI Id. ', 'a.d. VIII Id. ', 'a.d. VI Id. ', 'a.d. VI Id. ', 'a.d. VI Id. ' }, { 'a.d. V Id. ', 'a.d. V Id. ', 'a.d. VII Id. ', 'a.d. V Id. ', 'a.d. VII Id. ', 'a.d. V Id. ', 'a.d. VII Id. ', 'a.d. V Id. ', 'a.d. V Id. ', 'a.d. VII Id. ', 'a.d. V Id. ', 'a.d. V Id. ', 'a.d. V Id. ' }, { 'a.d. IV Id. ', 'a.d. IV Id. ', 'a.d. VI Id. ', 'a.d. IV Id. ', 'a.d. VI Id. ', 'a.d. IV Id. ', 'a.d. VI Id. ', 'a.d. IV Id. ', 'a.d. IV Id. ', 'a.d. VI Id. ', 'a.d. IV Id. ', 'a.d. IV Id. ', 'a.d. IV Id. ' }, { 'a.d. III Id. ', 'a.d. III Id. ', 'a.d. V Id. ', 'a.d. III Id. ', 'a.d. V Id. ', 'a.d. III Id. ', 'a.d. V Id. ', 'a.d. III Id. ', 'a.d. III Id. ', 'a.d. V Id. ', 'a.d. III Id. ', 'a.d. III Id. ', 'a.d. III Id. ' }, { 'pr. Id. ', 'pr. Id. ', 'a.d. IV Id. ', 'pr. Id. ', 'a.d. IV Id. ', 'pr. Id. ', 'a.d. IV Id. ', 'pr. Id. ', 'pr. Id. ', 'a.d. IV Id. ', 'pr. Id. ', 'pr. Id. ', 'pr. Id. ' }, { 'Id. ', 'Id. ', 'a.d. III Id. ', 'Id. ', 'a.d. III Id. ', 'Id. ', 'a.d. III Id. ', 'Id. ', 'Id. ', 'a.d. III Id. ', 'Id. ', 'Id. ', 'Id. ' }, { 'a.d. XIX Kal. ', 'a.d. XVI Kal. ', 'pr. Id. ', 'a.d. XVIII Kal. ', 'pr. Id. ', 'a.d. XVIII Kal. ', 'pr. Id. ', 'a.d. XIX Kal. ', 'a.d. XVIII Kal. ', 'pr. Id. ', 'a.d. XVIII Kal. ', 'a.d. XIX Kal. ', None }, { 'a.d. XVIII Kal. ', 'a.d. XV Kal. ', 'Id. ', 'a.d. XVII Kal. ', 'Id. ', 'a.d. XVII Kal. ', 'Id. ', 'a.d. XVIII Kal. ', 'a.d. XVII Kal. ', 'Id. ', 'a.d. XVII Kal. ', 'a.d. XVIII Kal. ', None }, { 'a.d. XVII Kal. ', 'a.d. XIV Kal. ', 'a.d. XVII Kal. ', 'a.d. XVI Kal. ', 'a.d. XVII Kal. ', 'a.d. XVI Kal. ', 'a.d. XVII Kal. ', 'a.d. XVII Kal. ', 'a.d. XVI Kal. ', 'a.d. XVII Kal. ', 'a.d. XVI Kal. ', 'a.d. XVII Kal. ', None }, { 'a.d. XVI Kal. ', 'a.d. XIII Kal. ', 'a.d. XVI Kal. ', 'a.d. XV Kal. ', 'a.d. XVI Kal. ', 'a.d. XV Kal. ', 'a.d. XVI Kal. ', 'a.d. XVI Kal. ', 'a.d. XV Kal. ', 'a.d. XVI Kal. ', 'a.d. XV Kal. ', 'a.d. XVI Kal. ', None }, { 'a.d. XV Kal. ', 'a.d. XII Kal. ', 'a.d. XV Kal. ', 'a.d. XIV Kal. ', 'a.d. XV Kal. ', 'a.d. XIV Kal. ', 'a.d. XV Kal. ', 'a.d. XV Kal. ', 'a.d. XIV Kal. ', 'a.d. XV Kal. ', 'a.d. XIV Kal. ', 'a.d. XV Kal. ', None }, { 'a.d. XIV Kal. ', 'a.d. XI Kal. ', 'a.d. XIV Kal. ', 'a.d. XIII Kal. ', 'a.d. XIV Kal. ', 'a.d. XIII Kal. ', 'a.d. XIV Kal. ', 'a.d. XIV Kal. ', 'a.d. XIII Kal. ', 'a.d. XIV Kal. ', 'a.d. XIII Kal. ', 'a.d. XIV Kal. ', None }, { 'a.d. XIII Kal. ', 'a.d. X Kal. ', 'a.d. XIII Kal. ', 'a.d. XII Kal. ', 'a.d. XIII Kal. ', 'a.d. XII Kal. ', 'a.d. XIII Kal. ', 'a.d. XIII Kal. ', 'a.d. XII Kal. ', 'a.d. XIII Kal. ', 'a.d. XII Kal. ', 'a.d. XIII Kal. ', None }, { 'a.d. XII Kal. ', 'a.d. IX Kal. ', 'a.d. XII Kal. ', 'a.d. XI Kal. ', 'a.d. XII Kal. ', 'a.d. XI Kal. ', 'a.d. XII Kal. ', 'a.d. XII Kal. ', 'a.d. XI Kal. ', 'a.d. XII Kal. ', 'a.d. XI Kal. ', 'a.d. XII Kal. ', None }, { 'a.d. XI Kal. ', 'a.d. VIII Kal. ', 'a.d. XI Kal. ', 'a.d. X Kal. ', 'a.d. XI Kal. ', 'a.d. X Kal. ', 'a.d. XI Kal. ', 'a.d. XI Kal. ', 'a.d. X Kal. ', 'a.d. XI Kal. ', 'a.d. X Kal. ', 'a.d. XI Kal. ', None }, { 'a.d. X Kal. ', 'a.d. VII Kal. ', 'a.d. X Kal. ', 'a.d. IX Kal. ', 'a.d. X Kal. ', 'a.d. IX Kal. ', 'a.d. X Kal. ', 'a.d. X Kal. ', 'a.d. IX Kal. ', 'a.d. X Kal. ', 'a.d. IX Kal. ', 'a.d. X Kal. ', None }, { 'a.d. IX Kal. ', 'a.d. VI Kal. ', 'a.d. IX Kal. ', 'a.d. VIII Kal. ', 'a.d. IX Kal. ', 'a.d. VIII Kal. ', 'a.d. IX Kal. ', 'a.d. IX Kal. ', 'a.d. VIII Kal. ', 'a.d. IX Kal. ', 'a.d. VIII Kal. ', 'a.d. IX Kal. ', 'a.d. bis VI Kal. ' }, { 'a.d. VIII Kal. ', 'a.d. V Kal. ', 'a.d. VIII Kal. ', 'a.d. VII Kal. ', 'a.d. VIII Kal. ', 'a.d. VII Kal. ', 'a.d. VIII Kal. ', 'a.d. VIII Kal. ', 'a.d. VII Kal. ', 'a.d. VIII Kal. ', 'a.d. VII Kal. ', 'a.d. VIII Kal. ', 'a.d. VI Kal. ' }, { 'a.d. VII Kal. ', 'a.d. IV Kal. ', 'a.d. VII Kal. ', 'a.d. VI Kal. ', 'a.d. VII Kal. ', 'a.d. VI Kal. ', 'a.d. VII Kal. ', 'a.d. VII Kal. ', 'a.d. VI Kal. ', 'a.d. VII Kal. ', 'a.d. VI Kal. ', 'a.d. VII Kal. ', 'a.d. V Kal. ' }, { 'a.d. VI Kal. ', 'a.d. III Kal. ', 'a.d. VI Kal. ', 'a.d. V Kal. ', 'a.d. VI Kal. ', 'a.d. V Kal. ', 'a.d. VI Kal. ', 'a.d. VI Kal. ', 'a.d. V Kal. ', 'a.d. VI Kal. ', 'a.d. V Kal. ', 'a.d. VI Kal. ', 'a.d. IV Kal. ' }, { 'a.d. V Kal. ', 'pr. Kal. ', 'a.d. V Kal. ', 'a.d. IV Kal. ', 'a.d. V Kal. ', 'a.d. IV Kal. ', 'a.d. V Kal. ', 'a.d. V Kal. ', 'a.d. IV Kal. ', 'a.d. V Kal. ', 'a.d. IV Kal. ', 'a.d. V Kal. ', 'a.d. III Kal. ' }, { 'a.d. IV Kal. ', {}, 'a.d. IV Kal. ', 'a.d. III Kal. ', 'a.d. IV Kal. ', 'a.d. III Kal. ', 'a.d. IV Kal. ', 'a.d. IV Kal. ', 'a.d. III Kal. ', 'a.d. IV Kal. ', 'a.d. III Kal. ', 'a.d. IV Kal. ', 'pr. Kal. ' }, { 'a.d. III Kal. ', {}, 'a.d. III Kal. ', 'pr. Kal. ', 'a.d. III Kal. ', 'pr. Kal. ', 'a.d. III Kal. ', 'a.d. III Kal. ', 'pr. Kal. ', 'a.d. III Kal. ', 'pr. Kal. ', 'a.d. III Kal. ', {} }, { 'pr. Kal. ', {}, 'pr. Kal. ', {}, 'pr. Kal. ', {}, 'pr. Kal. ', 'pr. Kal. ', {}, 'pr. Kal. ', {}, 'pr. Kal. ', {} } }
-- if only one argument then not a valid date
if args[1] == nil then return end
-- if two arguments then date without year
if #args[1] == 2 then
local MonthDay = {tonumber(args[1][1]), tonumber(args[1][2])}
if MonthDay[1] > 13 then return end
if MonthDay[1] == 2 and MonthDay[2] > 28 then
MonthDay[1] = 13
end
local day = dayLookup[MonthDay[2]][MonthDay[1]]
if day == 'Kal. ' then
return day .. months.ablative[MonthDay[1]]
elseif day == 'Non. ' then
return day .. months.ablative[MonthDay[1]]
elseif day == 'Id. ' then
return day .. months.ablative[MonthDay[1]]
else
if MonthDay[2] > month_ides_lookup(MonthDay[1]) then
if tonumber(MonthDay[1]) == 12 then
return day .. months.accusative[1]
elseif MonthDay[1] == 13 then
return day .. months.accusative[3]
end
return day .. months.accusative[MonthDay[1] + 1]
end
return day .. months.accusative[MonthDay[1]]
end
-- if 3 arguments then date with year-month-day
elseif #args[1] == 3 then
local YearMonthDay = {tonumber(args[1][1]), tonumber(args[1][2]), tonumber(args[1][3])}
MonthDay = {YearMonthDay[2], YearMonthDay[3]}
if YearMonthDay[1] > 0 then
avc = 753
elseif YearMonthDay[1] < 0 then
avc = 754
end
if MonthDay[1] > 13 then return end
if checkLeapYear(YearMonthDay[1]) then
if YearMonthDay[2] == 2 then
YearMonthDay[2] = 13
MonthDay = {13, YearMonthDay[3]}
end
else
if YearMonthDay[2] == 2 and tonumber(YearMonthDay[3]) > 28 then return end
end
local day = dayLookup[MonthDay[2]][MonthDay[1]]
if day == 'Kal. ' then
return day .. months.ablative[MonthDay[1]] .. ' ' .. numeral.main({YearMonthDay[1]+avc}) .. ' AVC'
elseif day == 'Non. ' then
return day .. months.ablative[MonthDay[1]] .. ' ' .. numeral.main({YearMonthDay[1]+avc}) .. ' AVC'
elseif day == 'Id. ' then
return day .. months.ablative[MonthDay[1]] .. ' ' .. numeral.main({YearMonthDay[1]+avc}) .. ' AVC'
else
if MonthDay[2] > month_ides_lookup(MonthDay[1]) then
if tonumber(MonthDay[1]) == 12 then
return day .. months.accusative[1] .. ' ' .. numeral.main({YearMonthDay[1]+avc}) .. ' AVC'
elseif MonthDay[1] == 13 then
return #dayLookup[24]
-- return day .. months.accusative[3] .. ' ' .. numeral.main({YearMonthDay[1]+avc}) .. ' AVC'
end
return day .. months.accusative[MonthDay[1] + 1] .. ' ' .. numeral.main({YearMonthDay[1]+avc}) .. ' AVC'
end
if tonumber(MonthDay[1]) == 13 then
MonthDay[1] = 2
end
return day .. months.accusative[MonthDay[1]] .. ' ' .. numeral.main({YearMonthDay[1]+avc}) .. ' AVC'
end
else return end
end
function p.main(frame)
-- If called via #invoke, use the args passed into the invoking
-- template, or the args passed to #invoke if any exist. Otherwise
-- assume args are being passed directly in from the debug console
-- or from another Lua module.
-- All dates must be passed via ISO 8601 (YYYY-MM-DD) or (MM-DD)
local origArgs
if frame == mw.getCurrentFrame() then
origArgs = frame:getParent().args
for k, v in pairs(frame.args) do
origArgs = frame.args
break
end
else
origArgs = frame['args']
end
-- Trim whitespace and remove blank arguments.
local args = {}
for k, v in pairs(origArgs) do
if type( v ) == 'string' then
v = mw.text.trim(v)
end
if v ~= '' then
args[k] = v
end
end
-- exit if not given anything
if args == nil or args == {} then return end
-- Remove dashes from args to get a table representing {year, month, day}
if type(args[1]) == 'string' then
args[1] = mw.text.split(args[1], '%f[^%d]%-')
end
return _main(args)
end
return p