local p = local bool_to_number=local getArgs = require('Module:Arguments').getArgslocal snippet = require('Module:Sandbox/Carn/TextSnippets')local err = "-"
-- utility functionslocal function purif(str) if str
nil then return nil elseif type(tonumber(str))
local function inbord(val, down, up) -- is val in border from down to up? return not (type(up) ~= "number" or type(down) ~= "number" or type(val) ~= "number" or up < down or val < down or val > up)end
local inlist = function (var, list) local n = #list local inlist = false for i=1,n do if var
-- calendar functionslocal function unwarp(date) if not date then return "" elseif type(date) ~= "table" then return date end return (date.year or "?").."-"..(date.month or "?").."-"..(date.day or "?")end
local mnlang = --"ru_G", "ru_N",
-- ["ru_G"] =,-- ["ru_N"] =,local month_lang = local monthd = -- old table of days in mounth
-- , -- mm yyyy-- , -- yyyy mmlocal pattern =
-- Will be filled automatically from above tablelocal reverse_month_lang =
local reverse_table = function (strait_table) local reversed_table = for k,v in pairs(strait_table) do reversed_table[v] = k end return reversed_tableend
local filling_months = function (mnlang, month_lang) for i=1, #mnlang do reverse_month_lang[mnlang[i]] = reverse_table(month_lang[mnlang[i]]) endend
filling_months(mnlang, month_lang)
local function leap_year(y,jul) if (not y) or (type(y) ~= "number") then return false elseif (y % 4) ~= 0 then return false elseif not jul and (y % 100
local function isdate (chain, jul) -- можно использовать для проверки таблиц с полями day, month, year if not chain then return false elseif (not type(chain)
0 then return false elseif chain.month
29 and not leap_year(chain.year,jul) then return false else return true end-- check for other calendars needed?end
-- функция для нормализации значений дат и перевода месяцев в числаlocal function numerize(str) if type(str)
"" or str
"number" then return math.floor(tonumber(str)) else for i=1, #mnlang do if inlist(mw.ustring.lower(str),month_lang[mnlang[i]]) then mnlang.curr = mnlang[i] return reverse_month_lang[mnlang[i]][mw.ustring.lower(str)] end end endend
local function parse_date(status, date_string) status = status or if type(date_string) ~= "string" or date_string
-- OLD FUNCTIONlocal function numstr2date(datein) local nums = local dateout = for num in string.gmatch(datein,"(%d+)") do table.insert(nums,purif(num)) end if #nums ~= 3 then error("Wrong format: 3 numbers expected") elseif not inbord(nums[2],1,12) then error("Wrong month") elseif not inbord(nums[3],1,31) then dateout = elseif not inbord(nums[1],1,31) then dateout = else-- local lang = mw.getContentLanguage-- implement lang:formatDate(format,datein,true) here return error("Unable to recognize date") end return dateoutend
local function date2str(datein) if not isdate(datein) then return error("Wrong date") end local dateout = os.date("%Y-%m-%d", os.time(datein)) return dateoutend
local function gri2jd(datein) if not isdate(datein) then return error("Wrong date") end local year = datein.year local month = datein.month local day = datein.day -- jd calculation local a = math.floor((14 - month)/12) local y = year + 4800 - a local m = month + 12*a - 3 local offset = math.floor(y/4) - math.floor(y/100) + math.floor(y/400) - 32045 local jd = day + math.floor((153*m + 2)/5) + 365*y + offset -- jd validation local low, high = -1931076.5, 5373557.49999 if not (low <= jd and jd <= high) then return error("Wrong date") end return jdend
local function jd2jul(jd) if type(jd) ~= "number" then return error("Wrong jd") end -- calendar date calculation local c = jd + 32082 local d = math.floor((4*c + 3)/1461) local e = c - math.floor(1461*d/4) local m = math.floor((5*e + 2)/153) local year_out = d - 4800 + math.floor(m/10) local month_out = m + 3 - 12*math.floor(m/10) local day_out = e - math.floor((153*m + 2)/5) + 1 -- output local dateout = return dateoutend
local function jul2jd(datein) if not isdate(datein) then return error("Wrong date") end local year = datein.year local month = datein.month local day = datein.day -- jd calculation local a = math.floor((14 - month)/12) local y = year + 4800 - a local m = month + 12*a - 3 local offset = math.floor(y/4) - 32083 local jd = day + math.floor((153*m + 2)/5) + 365*y + offset -- jd validation local low, high = -1930999.5, 5373484.49999 if not (low <= jd and jd <= high) then return error("Wrong date") end return jdend
local function jd2gri(jd) -- calendar date calculation local a = jd + 32044 local b = math.floor((4*a + 3) / 146097) local c = a - math.floor(146097*b/4) local d = math.floor((4*c+3)/1461) local e = c - math.floor(1461*d/4) local m = math.floor((5*e+2)/153) local day_out = e - math.floor((153*m+2)/5)+1 local month_out = m + 3 - 12*math.floor(m/10) local year_out = 100*b + d - 4800 + math.floor(m/10) -- output local dateout = return dateoutend
-- =p.NthDay(mw.getCurrentFrame:newChild)
function p.NthDay(frame) local args = getArgs(frame,) local num, wday, mont, yea, format = purif(args[1]), purif(args[2]), purif(args[3]), purif(args[4]), args[5] if not format then format = "%Y-%m-%d" end if not inbord(num,-5,5) then return error("The number must be between -5 and 5") elseif num
mont then return (os.date(format, tim)) else return (err) end elseif inbord(num,-5,-1) then local m_end = os.time - 24 * 60 * 60 local m_wde = tonumber(os.date("%w", m_end)) local end_shift = ((math.abs(num + 1) + bool_to_number[wday > m_wde]) * 7 + (m_wde - wday)) * 24 * 60 * 60 local tim = m_end - end_shift if tonumber(os.date("%m", tim))
local function exam(smth,name) name = name and mw.log(name) or "" if type(smth)
ns_date.year then co_year = ns_year ns_year = empty os_year = empty end if in_order[1] > in_order[2] then return ns_month + ns_day + ns_year + left + os_mark + os_month + os_day + os_year + right + co_year else return ns_day + ns_month + ns_year + left + os_mark + os_day + os_month + os_year + right + co_year endend
return p