Module:Expanded dates

From Geometry Dash Expanded Wiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:Expanded dates/doc

local p = {}
local months = {'January','February','March','April','May','June','July','August','September','October','November','December'}
local monthNames = {}
for i, name in ipairs(months) do
    monthNames[string.lower(name)] = i
    monthNames[string.lower(string.sub(name, 1, 3))] = i
end
monthNames.sept = 9
local function args(frame)
    local a = {}
    if frame:getParent() then
        for k, v in pairs(frame:getParent().args) do a[k] = mw.text.trim(v) end
    end
    for k, v in pairs(frame.args) do a[k] = mw.text.trim(v) end
    return a
end
local function pick(a, index, named)
    local v = a[index]
    if v == nil or v == '' then v = a[named] end
    return v
end
local function integer(value)
    local n = tonumber(value)
    if n and n == math.floor(n) then return n end
end
local function month(value)
    local n = integer(value)
    if n then
        if n >= 1 and n <= 12 then return n end
        return nil
    end
    return monthNames[string.lower(value or '')]
end
local function date(y, m, d)
    y, m, d = integer(y), month(m), integer(d)
    if not y or y < 1 or y > 9999 or not m or not d then return nil end
    local leap = y % 4 == 0 and (y % 100 ~= 0 or y % 400 == 0)
    local days = {31, leap and 29 or 28, 31,30,31,30,31,31,30,31,30,31}
    if d < 1 or d > days[m] then return nil end
    return {year=y, month=m, day=d}
end
local function errorMessage(message)
    return tostring(mw.html.create('span'):addClass('error'):wikitext(message))
end
local function today(frame)
    return date(frame:preprocess('{{CURRENTYEAR}}'), frame:preprocess('{{CURRENTMONTH}}'), frame:preprocess('{{CURRENTDAY}}'))
end
local function ageAt(birth, reference)
    local age = reference.year - birth.year
    if reference.month < birth.month or (reference.month == birth.month and reference.day < birth.day) then age = age - 1 end
    if age < 0 then return nil end
    return age
end
function p.monthnumber(frame)
    local a = args(frame)
    local n = month(pick(a, 1, 'month'))
    if not n then return errorMessage('MONTHNUMBER: enter a month from 1 to 12 or an English month name.') end
    return tostring(n)
end
function p.monthname(frame)
    local a = args(frame)
    local n = month(pick(a, 1, 'month'))
    if not n then return errorMessage('MONTHNAME: enter a month from 1 to 12 or an English month name.') end
    return months[n]
end
function p.age(frame)
    local a = args(frame)
    local birth = date(pick(a,1,'year'), pick(a,2,'month'), pick(a,3,'day'))
    if not birth then return errorMessage('Age: enter a valid birth date as year, month, day.') end
    local current = today(frame)
    local reference = date(pick(a,4,'endyear') or current.year, pick(a,5,'endmonth') or current.month, pick(a,6,'endday') or current.day)
    if not reference then return errorMessage('Age: enter a valid reference date.') end
    local value = ageAt(birth,reference)
    if not value then return errorMessage('Age: the reference date is before the birth date.') end
    return tostring(value)
end
function p.birthdate(frame)
    local a = args(frame)
    local birth = date(pick(a,1,'year'), pick(a,2,'month'), pick(a,3,'day'))
    if not birth then return errorMessage('Birth date and age: enter a valid birth date as year, month, day.') end
    local value = ageAt(birth,today(frame))
    if not value then return errorMessage('Birth date and age: the birth date is in the future.') end
    return string.format('%d %s %d (age %d)',birth.day,months[birth.month],birth.year,value)
end
return p