--\/ | ___ __| |_ _| | ___ _| _ \ __ _| |_ ___|_ _/ |(_) _ __ | |\/| |/ _ \ / _` | | | | |/ _ (_) | | |/ _` | __/ _ \| || |/ _ \| '_ \ | | | | (_) | (_| | |_| | | __/_| |_| | (_| | || __/| || | (_) | | | | |_| |_|\___/ \__,_|\__,_|_|\___(_)____/ \__,_|\__\___|___|_|\___/|_| |_| This module is intended for processing of date strings.
Please do not modify this code without applying the changes first at Module:Date/sandbox and testing at Module:Date/sandbox/testcases and Module talk:Date/sandbox/testcases.
Authors and maintainers:
--
--
-- Function allowing for consistent treatment of boolean-like wikitext input.-- It works similarly to Module:Yesnolocal function yesno(val, default) if type(val)
'number' then if val
0 then return false end elseif type(val)
'no' or val
'false' or tonumber(val)
'yes' or val
'true' or tonumber(val)
----------------------------------------------------------------------------------------- String replacement that ignores part of the string in "..."local function strReplace(String, old, new) if String:find('"') then local T= for i, str in ipairs(mw.text.split(String, '"', true)) do if i%2
----------------------------------------------------------------------------------------- process datevec-- INPUT:-- * datevec - Array of containing broken -- down date-time component strings or numbers-- OUTPUT:-- * datecode - a code specifying content of the array where Y' is year, 'M' is month, -- 'D' is day, 'H' is hour, 'M' minute, 'S' is second. output has to be one of YMDHMS, YMDHM, YMD, YM, MD, Y-- * datenum - same array but holding only numbers or nulslocal function parserDatevec(datevec) -- if month is not a number than check if it is a month name in project's language local month = datevec[2] if month and month~= and not tonumber(month) then datevec[2] = mw.getContentLanguage:formatDate("n", month) end
-- create datecode based on which variables are provided and check for out-of-bound values local maxval = -- max values for year, month, ... local minval = -- min values for year, month, ... local c = local datecode = -- a string signifying which combination of variables was provided local datenum = -- date-time encoded as a vector = [year, month, ..., second] for i = 1,8 do datenum[i] = tonumber(datevec[i]) if datenum[i] and (i
'YMDHMS' then timeStamp = string.format('%04i-%02i-%02i %02i:%02i:%02i', datenum[1], datenum[2], datenum[3], datenum[4], datenum[5], datenum[6]) elseif datecode
'YMD' then timeStamp = string.format('%04i-%02i-%02i', datenum[1], datenum[2], datenum[3]) datecode = 'YMD' -- 'YMD', 'YMDHMS' and 'YMDHM' are the only supported format starting with 'YMD'. All others will be converted to 'YMD' elseif datecode
'Y' then timeStamp = string.format('%04i', datenum[1]) datecode = 'Y' elseif datecode
'MD' then timeStamp = string.format('%04i-%02i-%02i', 2000, datenum[2], datenum[3]) else timeStamp = nil -- format not supported end return timeStamp, datecodeend
----------------------------------------------------------------------------------------- trim leading zeros in years prior to year 1000-- INPUT:-- * datestr - translated date string -- * lang - language of translation-- OUTPUT:-- * datestr - updated date string
local function trimYear(datestr, year, lang) local yearStr0, yearStr1, yearStr2, zeroStr yearStr0 = string.format('%04i', year) -- 4 digit year in standard form "0123" yearStr1 = mw.language.new(lang):formatDate('Y', yearStr0) -- same as calling parser function --yearStr1 = mw.getCurrentFrame:callParserFunction("#time",) -- translate to a language if yearStr0
zeroStr then yearStr2 = mw.ustring.sub(yearStr2, 2, 5-i) else break end end end return string.gsub(datestr, yearStr1, yearStr2) -- in datestr replace long year with trimmed oneend
----------------------------------------------------------------------------------------- Look up proper format string to be passed to parser function-- INPUTS:-- * datecode: YMDHMS, YMDHM, YMD, YM, MD, Y, or M-- * day : Number between 1 and 31 (not needed for most languages)-- * lang : language-- OUTPUT:-- * dFormat : input to functionlocal function getDateFormat(datecode, day, lang) local function parseFormat(dFormat, day) if dFormat:find('default') and #dFormat>10 then -- special (and messy) case of dFormat code depending on a day number -- then json contains a string with more json containing "default" field and 2 digit day keys -- if desired day is not in that json than use "default" case dFormat = dFormat:gsub('”','"') -- change fancy double quote to a straight one, used for json marking local D = mw.text.jsonDecode(dFormat) --com = mw.dumpObject(D) day = string.format('d%02i',day) -- create day key dFormat = D[day] or D.default dFormat = dFormat:gsub("'", '"') -- change single quote to a double quote, used for marking end return dFormat end local T = local tab = mw.ext.data.get('DateI18n.tab', lang) for _, row in pairs(tab.data) do -- convert the output into a dictionary table local id, _, msg = unpack(row) T[id] = msg end local dFormat = T[datecode] if dFormat
'YMDHMS' or datecode
'YMDHMS' then dFormat = dFormat .. ':s' end else dFormat = parseFormat(dFormat, day) end return dFormatend
----------------------------------------------------------------------------------------- Look up proper format string to be passed to parser function-- INPUTS:-- * month : month number-- * case : gramatic case abbriviation, like "ins", "loc"-- * lang : language-- OUTPUT:-- * dFormat : input to functionlocal function MonthCase(month, case, lang) local T = local tab = mw.ext.data.get('I18n/MonthCases.tab', lang) for _, row in pairs(tab.data) do local mth, cs, msg = unpack(row) T[mth][cs] = msg end return T[month][case]end
--
--
local p =
--function p._Date(datevec, lang, case, class, trim_year) -- make sure inputs are in the right format if not lang or not mw.language.isValidCode(lang) then lang = mw.getCurrentFrame:callParserFunction("int", "lang") -- get user's chosen language end if lang
-- By default the gramatical case is not specified (case
'qu' or lang
'nom') then -- Special case related to Quechua and Kichwa languages. The form in the I18n is -- Genitive case with suffix "pi" added to month names provided by } -- in Nominative case that "pi" should be removed -- see https://commons.wikimedia.org/wiki/Template_talk:Date#Quechua from 2014 dFormat = dFormat:gsub('F"pi"', 'F') elseif (case
'nom') then dFormat = strReplace(dFormat, "xg", "F") elseif (case ~= ) then -- see is page on Commons have name of the month -- in specific gramatic case in desired language. If we have it than replace -- "F" and xg" in dFormat local monthMsg = MonthCase(month, case, lang) if monthMsg and monthMsg ~= then -- make sure it exists dFormat = strReplace(dFormat, 'F', '"'..monthMsg..'"') -- replace default month with month name we already looked up dFormat = strReplace(dFormat, 'xg', '"'..monthMsg..'"') end end
-- Translate the date using specified format -- See https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#mw.language:formatDate and -- https://www.mediawiki.org/wiki/Help:Extension:ParserFunctions##time for explanation of the format local datestr = mw.language.new(lang):formatDate(dFormat, timeStamp) -- same as using parser function -- Special case related to Thai solar calendar: prior to 1940 new-year was at different -- time of year, so just year (datecode
'th' and datecode
'nil' then trim_year = '100-999' end local trim = yesno(trim_year,nil) -- convert to boolean if trim
'string' then -- if "trim_year" not a simple True/False than it is range of dates -- for example '100-999' means to pad one and 2 digit years to be 4 digit long, while keeping 3 digit years as is local YMin, YMax = trim_year:match('(%d+)-(%d+)') trim = (YMin~=nil and year>=tonumber(YMin) and year<=tonumber(YMax)) end if trim
-- append timezone if present if datenum[7] and (datecode
'YMDHM') then -- use parser function to create timezone string, so that we use correct character set local sign = (datenum[7]<0) and '−' or '+' timeStamp = string.format("2000-01-01 %02i:%02i:00", math.abs(datenum[7]), datenum[8] or 0) local timezone = mw.language.new(lang):formatDate('H:i', timeStamp) -- same as using parser function datestr = string.format("%s %s%s", datestr, sign, timezone) end
-- html formating and tagging of date string if class and class ~= and datecode~='M' and datecode~='MD'then local DateHtmlTags = '
' datestr = DateHtmlTags:format(class, timeStamp, datestr) end return datestrend--Date|year=|month=|day=|hour=|minute=|second=|tzhour=|tzmin=|lang=en}} Parameters: * year, month, day, hour, minute, second: broken down date-time component strings * tzhour, tzmin: timezone offset from UTC, hours and minutes * lang: The language to display it in * case: Language format (genitive, etc.) for some languages * class: CSS class for the
return p