Module:Calendar/gregorian: Difference between revisions

From Nguhcraft Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 86: Line 86:
         datestamp = -(datestamp + 1)
         datestamp = -(datestamp + 1)
         y, m, d = 1969, 12, 31
         y, m, d = 1969, 12, 31
         while datestamp > year_len(y) do datestamp = datestamp - year_len(y); y = y - 1 end
         while datestamp >= year_len(y) do datestamp = datestamp - year_len(y); y = y - 1 end
         while datestamp > month_len(m, y) do
         while datestamp >= month_len(m, y) do
             datestamp = datestamp - month_len(m, y); m = m - 1
             datestamp = datestamp - month_len(m, y); m = m - 1
             d = month_len(m, y)
             d = month_len(m, y)

Revision as of 08:42, 23 May 2026

Documentation for this module may be created at Module:Calendar/gregorian/doc

local calendar = {}

local weekdays = { [0] = 4, 5, 6, 7, 1, 2, 3, 4 }
local month_names = {
    en = {'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'},
    en_short = {'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'},
    oc = {'genièr', 'febrier', 'març', 'abril', 'mai', 'junh', 'julh', 'agost', 'setembre', 'octobre', 'novembre', 'decembre'},
}
local day_names = {
    en = {'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'},
    en_short = {'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'},
    oc = {'diluns', 'dimars', 'dimercrès', 'dijòus', 'divendres', 'disabte', 'dimengue'},
}

local ordinal = {
    en = function(num)
        if num % 10 == 1 and num % 100 ~= 11 then return tostring(num) .. "st"
        elseif num % 10 == 2 and num % 100 ~= 12 then return tostring(num) .. "nd"
        elseif num % 10 == 3 and num % 100 ~= 13 then return tostring(num) .. "rd"
        else return tostring(num) .. "th"
        end
    end
}
local function is_leap(year)
    return (year % 4 == 0 and year % 100 ~= 0) or year % 400 == 0
end
local function year_len(year)
    return is_leap(year) and 366 or 365
end
local function month_len(month, year)
    if month == 1 or month == 3 or month == 5 or month == 7
        or month == 8 or month == 10 or month == 12 then
        return 31
    elseif month == 4 or month == 6 or month == 9 or month == 11 then
        return 30
    elseif month == 2 then
        return is_leap(year) and 29 or 28
    else error(tostring(month) + " is not a valid gregorian month")
    end
end

calendar.from = function (date_info)
    local date = 0
    assert(date_info.year and date_info.month and date_info.day)
    date_info.year = tonumber(date_info.year)
    date_info.month = tonumber(date_info.month)
    date_info.day = tonumber(date_info.day)
    if date_info.year >= 1970 then
        local y = date_info.year
        while y > 1970 do
            y = y - 1
            date = date + year_len(y)
        end
        local m = date_info.month
        while m > 1 do
            m = m - 1
            date = date + month_len(m, date_info.year)
        end
        date = date + date_info.day - 1
    else
        date = date + (1 + month_len(date_info.month, date_info.year) - date_info.day)
        local m = date_info.month + 1
        local y = date_info.year
        while m <= 12 do
            date = date + month_len(m, y)
            m = m + 1
        end
        y = y + 1
        while y < 1970 do
            date = date + year_len(y)
            y = y + 1
        end
        date = -date
    end
    return date
end

calendar.to = function (datestamp)
    local dow = weekdays[datestamp % 7]
    local y, m, d = 1970, 1, 1
    if datestamp > 0 then
        while datestamp > year_len(y) do datestamp = datestamp - year_len(y); y = y + 1 end
        while datestamp > month_len(m, y) do datestamp = datestamp - month_len(m, y); m = m + 1 end
        d = d + datestamp
    else
        datestamp = -(datestamp + 1)
        y, m, d = 1969, 12, 31
        while datestamp >= year_len(y) do datestamp = datestamp - year_len(y); y = y - 1 end
        while datestamp >= month_len(m, y) do
            datestamp = datestamp - month_len(m, y); m = m - 1
            d = month_len(m, y)
        end
        d = d - datestamp
    end
    return {year = y, month = m, day = d, weekday = dow }
end

calendar.to_formatted = function (datestamp, opts)
    opts = opts or {style = "en-intl"}
    local date = calendar.to(datestamp)
    if opts.style == "en-intl" then
        return
            day_names.en[date.weekday]
            .. " " .. tostring(date.day)
            .. " " .. month_names.en[date.month]
            .. " " .. tostring(date.year)
    elseif opts.style == "en-us" then
        return
            day_names.en[date.weekday]
            .. " " .. month_names.en[date.month]
            .. " " .. ordinal.en(date.day)
            .. ", " .. tostring(date.year)
    elseif opts.style == "oc" then
        return
            day_names.oc[date.weekday]
            .. " " .. tostring(date.day)
            .. " de " .. month_names.oc[date.month]
            .. " de " .. tostring(date.year)
    elseif opts.style == "iso" then
        return string.format("%d-%02d-%02d", date.year, date.month, date.day)
    end
end

return calendar