Module:Sandbox/DixonD/Datetime

From English Wikipedia @ Freddythechick
local Error = require('Module:Error')
local this = {};

this.calendars = {};

function this.registerCalendar(moduleName, ...)
    moduleName = require(moduleName); --debug only: not lazily
    this.calendars[#(this.calendars)] = moduleName; --indexed by number, module loaded lazily
    for i = 1, arg.n do    
        this.calendars[arg[i]] = moduleName; -- indexed by code, module loaded lazily
    end;
end;

this.registerCalendar("Module:Sandbox/DixonD/Datetime/Gregorian", "Gregorian", "g"); --first position is the default
this.registerCalendar("Module:Sandbox/DixonD/Datetime/Julian",    "Julian",    "j");
-- more calendars may be added later in new modules pluggable here into this factory...

function this.selectCalendar(index)
    if index == nil then
        index = 0; -- use the default calendar (Gregorian as set above)
    end;

    local calendar = this.calendars[index];
    if calendar == nil then
        return index; -- fast path: assume that index is a calendar object (not indexed) already loaded
    end;

    if type(calendar) == "string" then -- calendar is a string (i.e. a module name)
        local moduleName = calendar;
        calendar = require(moduleName); -- effective loading of calendar object
        if calendar == nil then
            return tostring(Error.error{"Calendar module name ''" .. moduleName .. "'' is either missing or cannot be loaded!"});
        end;
        -- replace the moduleName given ad value of any calendar key by the newly loaded calendar object
        for k, v in pairs(this.calendars) do
            if v == moduleName then
                this.calendars[k] = calendar;
            end;
        end;
    end; -- else assume calendar is a valid calendar object

    return calendar;
end;

-- main functions
function this.julianDay(year, month, day, hour, minute, second, calendar)
    calendar = this.selectCalendar(calendar);
    if calendar == nil then
        return tostring(Error.error{"Calendar ''" .. calendar .. "'' is either missing or unknown!"});
    end;

    return calendar.julianDay(year, month, day, hour, minute, second);
end;

function this.dateOfJulianDay(julianDay, calendar)
    calendar = this.selectCalendar(calendar);
    if calendar == nil then
        return tostring(Error.error{"Calendar ''" .. calendar .. "'' is either missing or unknown!"});
    end;

    return calendar.dateOfJulianDay(julianDay);
end;

function this.yearOfJulianDay(julianDay, calendar)
    calendar = this.selectCalendar(calendar);
    if calendar == nil then
        return tostring(Error.error{"Calendar ''" .. calendar .. "'' is either missing or unknown!"});
    end;

    return calendar.yearOfJulianDay(julianDay);
end;
 
function this.monthOfJulianDay(julianDay, calendar)   
    calendar = this.selectCalendar(calendar);
    if calendar == nil then
        return tostring(Error.error{"Calendar ''" .. calendar .. "'' is either missing or unknown!"});
    end;

    return calendar.monthOfJulianDay(julianDay);
end;
 
function this.dayOfJulianDay(julianDay, calendar)   
    calendar = this.selectCalendar(calendar);
    if calendar == nil then
        return tostring(Error.error{"Calendar ''" .. calendar .. "'' is either missing or unknown!"});
    end;

    return calendar.dayOfJulianDay(julianDay);
end;
 
function this.weekdayOfJulianDay(julianDay, calendar)   
    calendar = this.selectCalendar(calendar);
    if calendar == nil then
        return tostring(Error.error{"Calendar ''" .. calendar .. "'' is either missing or unknown!"});
    end;

    return calendar.weekdayOfJulianDay(julianDay);
end;
 
function this.hourOfJulianDay(julianDay, calendar)   
    calendar = this.selectCalendar(calendar);
    if calendar == nil then
        return tostring(Error.error{"Calendar ''" .. calendar .. "'' is either missing or unknown!"});
    end;

    return calendar.hourOfJulianDay(julianDay);
end;
 
function this.minuteOfJulianDay(julianDay, calendar)   
    calendar = this.selectCalendar(calendar);
    if calendar == nil then
        return tostring(Error.error{"Calendar ''" .. calendar .. "'' is either missing or unknown!"});
    end;

    return calendar.minuteOfJulianDay(julianDay);
end;
 
function this.secondOfJulianDay(julianDay, calendar)   
    calendar = this.selectCalendar(calendar);
    if calendar == nil then
        return tostring(Error.error{"Calendar ''" .. calendar .. "'' is either missing or unknown!"});
    end;

    return calendar.secondOfJulianDay(julianDay);
end;

return this;