Module:ISOdate explained

--

local p =

--

--

Dependencies

--

local D = require('Module:DateI18n') -- the enwp version of c:Module:Date

--ISOyear|target_string}} Parameters 1: The date string Error Handling: If the string does not look like it contain the year than the function will not return anything. That is the preferred treatment for the template:Creator which is the main (only?) template calling it.function p.ISOyear(frame) return p._ISOyear(frame.args[1])end

function p._ISOyear(input) if not input then return end input = mw.text.trim(input) -- if empty string then return it if input

"" then return input end -- if number then return it if tonumber(input) then return mw.ustring.format('%04i', input) end -- otherwise use regular expression match input = mw.ustring.match(input, '^+?(-?%d%d?%d?%d?)-') if input and tonumber(input) then return mw.ustring.format('%04i', input) else return endend

--ISOdate|target_string|lang=}} Parameters: 1: The date string lang: The language to display it in form: Language format (genitive, etc.) for some languages class: CSS class for the

Error Handling: If the string does not look like it contain the proper ISO date than the function will return the original string. That is the preferred treatment for the template:Information (and similar templates) which calling it.

function p.ISOdate(frame) local datestr, succeded local args = frame.args if not (args.lang and mw.language.isSupportedLanguage(args.lang)) then args.lang = frame:callParserFunction("int", "lang") -- get user's chosen language end datestr, succeded = p._ISOdate(mw.text.trim(args[1]), args.lang, -- language args.case or , -- allows to specify grammatical case for the month for languages that use them args.class or 'dtstart', -- allows to set the html class of the time node where the date is included. args.trim_year or '100-999' -- by default pad one and 2 digit years to be 4 digit long, while keeping 3 digit years as is ) return datestrend

function p._ISOdate(datestr, lang, case, class, trim_year)

-- pattern: regexp - regular expresion to test; dlen - number of date elements; tail = which element is a "tail" if any -- regexp hints: -- 1) Strings starting with "^" and ending with "$" indicate whole string match -- 2) optional tail part copied as-is and following the main parsed part of the date have to be separated from the date by a whitespace, so "(\s.+)?" local patterns = -- create datevec based on which variables are provided local datevec, tail, formatNum datevec, tail, formatNum = p.test_date_formats(datestr or , patterns) if datevec[1]

or datevec[1]

nil then -- quickly return if datestr does not look like date (it could be a template) return datestr, false end

-- call p._Date function to format date string local succeded, datestr2 succeded, datestr2 = pcall(D._Date, datevec, lang, case, class, trim_year) if succeded and datestr2~= then return mw.text.trim(datestr2 .. tail), true else -- in case of errors return the original string return datestr, false end end

function p.ISOdate_extended(frame) -- pattern: regexp - regular expresion to test; dlen - number of date elements; tail = which element is a "tail" if any -- regexp hints: -- 1) Strings starting with "^" and ending with "$" indicate whole string match -- 2) optional tail part copied as-is and following the main parsed part of the date have to be separated from the date by a whitespace, so "(\s.+)?"

local datestr, succeded local args = frame.args if not (args.lang and mw.language.isSupportedLanguage(args.lang)) then args.lang = frame:callParserFunction("int", "lang") -- get user's chosen language end datestr, succeded = p._ISOdate(mw.text.trim(args[1]), args.lang, -- language args.case or , -- allows to specify grammatical case for the month for languages that use them args.class or 'dtstart', -- allows to set the html class of the time node where the date is included. args.trim_year or '100-999' -- by default pad one and 2 digit years to be 4 digit long, while keeping 3 digit years as is ) if succeded then return datestr end

local patterns = local datevec, tail, formatNum, category = datevec, tail, formatNum = p.test_date_formats(frame.args[1], patterns) if formatNum

1 or formatNum

2 then vec = datevec; if tonumber(datevec[1])>12 then frame.args[1] = string.format('%04i-%02i-%02i', datevec[3], datevec[2], datevec[1]) category = '' return mw.text.trim(p.ISOdate(frame) .. tail); elseif tonumber(datevec[2])>12 then frame.args[1] = string.format('%04i-%02i-%02i', datevec[3], datevec[1], datevec[2]) category = '' return mw.text.trim(p.ISOdate(frame) .. tail); end elseif (formatNum

3 or formatNum

4) and (datevec[3]

or datevec[3]~=nil) then local str = mw.getCurrentFrame:callParserFunction("#time",) local vec = if vec and vec[1]~=nil then frame.args[1] = string.format('%04i-%02i-%02i', vec[1], vec[2], vec[3]) category = '' return p.ISOdate(frame); end end return datestrend

function p.test_date_formats(datestr, patterns) -- pattern: regexp - regular expresion to test; dlen - number of date elements; tail = which element is a "tail" if any

local datevec = local tail = local vec, pat local formatNum = 0 for i, pat in ipairs(patterns) do vec = if vec and vec[1]~=nil then for j=1,pat.dlen do datevec[j] = vec[j] end if pat.tail>0 and vec[pat.tail]~=nil then tail = mw.ustring.gsub(' ' .. vec[pat.tail], ' +', ' ') end formatNum = i break end end return datevec, tail, formatNumend

return p