模块:YMD to ISO
Module:YMD to ISO converts a date in YMD format (e.g. 2000 January 17) to ISO 8601 format (e.g. 2000-01-17). Any input which is not a valid DMY date is passed through unchanged. This template is designed to preprocess dates for use with the #time parser function, which is unable to convert YMD dates, and for use with templates such as {{Date}} or {{ISO date}} which are implemented using the #time parser function.
Usage
编辑{{#invoke:YMD to ISO | main | <date in YMD format> }}
or via template:
{{YMD to ISO | <date in YMD format> }}
Examples
编辑{{#invoke:YMD to ISO | main | 2000 January 17 }}
→ 2000-01-17
or via template:
{{YMD to ISO | 2000 January 17 }}
→ 2000-01-17
For more examples, see Template:YMD to ISO.
See also
编辑上述文档嵌入自Module:YMD to ISO/doc。 (编辑 | 历史) 编者可以在本模块的沙盒 (创建 | 镜像)和测试样例 (编辑)页面进行实验。 本模块的子页面。 |
local p = {}
local function month_number(month_name)
local months_full = {january=1, february=2, march=3, april=4, may=5, june=6, july=7, august=8, september=9, october=10, november=11, december=12}
local months_abbr = {jan=1, feb=2, mar=3, apr=4, may=5, jun=6, jul=7, aug=8, sep=9, sept=9, oct=10, nov=11, dec=12}
local month_lc, _ = string.gsub(string.lower(month_name),'%.','',1)
local month_num = months_full[month_lc] or months_abbr[month_lc] or 0
return month_num
end
local function days_in_month(month_num,year)
-- modified from code in Module:Citation/CS1/Date_validation
local days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
local month_length
if month_num == 2 then -- February: 28 days, unless leap year
month_length = 28
if year <= 1582 then -- Julian calendar before Oct 1582
if (year%4) == 0 then
month_length = 29 -- if leap year, then 29 days
end
else -- Gregorian calendar since Oct 1582
if ( (year%4)==0 and ((year%100)~=0 or (year%400)==0) ) then
month_length = 29 -- if leap year, then 29 days
end
end
else -- not February, get number of days for month
month_length = days[month_num]
end
return month_length
end
local function zero_pad(string)
if string.len(string) == 1 then
return '0' .. string
else
return string
end
end
function p.main(frame)
if frame.args[1] == nil then
return '' -- first argument is missing
end
local arg1, _ = string.gsub(mw.text.trim(frame.args[1]),'_',' ')
return p._main(arg1)
end
function p._main(arg1)
if arg1 == '' then
return '' -- first argument is empty
end
if not arg1:match('^%d%d%d%d %a%a%a%a?%.?%a?%a?%a?%a?%a?%a? *%d%d?$') then
return arg1 -- invalid date pattern
end
local year, month_name, day = string.match(arg1, '^(%d%d%d%d) *(%a%a%a%a?%.?%a?%a?%a?%a?%a?%a?) *(%d%d?)$')
if month_number(month_name) == 0 then
return arg1 -- invalid month name or abbreviation
end
if tonumber(day) < 1 or tonumber(day) > days_in_month(month_number(month_name),tonumber(year)) then
return arg1 -- invalid day number for given month
end
return year .. '-' .. zero_pad(tostring(month_number(month_name))) .. '-' .. zero_pad(day)
end
return p