開啟主選單

求真百科

本模塊用於將各類日期轉換為ISO 8601格式,以方便{{#time}}函數和其他模板調用。

用法

輸入完整日期,只輸入年月、只輸入年份皆可:

  • {{#invoke:ISODate|dates|1994年10月26日}} → 1994-10-26
  • {{#invoke:ISODate|dates|1994年10月}} → 1994-10
  • {{#invoke:ISODate|dates|1994年}} → 1994

當月和日是個位數時,十位加「0」或不加「0」皆可,模塊會自動補「0」,

  • {{#invoke:ISODate|dates|1994年8月1日}} → 1994-08-01
  • {{#invoke:ISODate|dates|1994年08月01日}} → 1994-08-01

可以轉換英文和不規範的ISO 8601日期:

  • {{#invoke:ISODate|dates|October 26, 1994}} → 1994-10-26
  • {{#invoke:ISODate|dates|26 Oct 1994}} → 1994-10-26
  • {{#invoke:ISODate|dates|Sept 1994}} → 1994-09
  • {{#invoke:ISODate|dates|1994-8-1}} → 1994-08-01
  • {{#invoke:ISODate|dates|1994-8}} → 1994-08

如果字符串以正確的日期開頭,則會轉換並忽視後綴文字:

  • {{#invoke:ISODate|dates|1994年10月26日,武汉}} → 1994-10-26
  • {{#invoke:ISODate|dates|1994年10月26日,武汉|suffix=yes}} → 1994-10-26,武漢(將suffix字段設為yes展示後綴)

以不合法日期開頭則報錯:

  • {{#invoke:ISODate|dates|一九九四年十月二十六日}}錯誤:無效時間。
  • {{#invoke:ISODate|dates|1994年13月32日}}錯誤:無效時間。
  • {{#invoke:ISODate|dates|一九九四年十月二十六日|error=ignore}} → 一九九四年十月二十六日(將error字段設為ignore返回輸入值)

ISO 8601標準只規定了1583年之後的日期標準,請勿用本模塊表示這之前的日期,否則可能會得到不期待的結果:

  • {{#invoke:ISODate|dates|25年8月5日(东汉建立)|suffix=yes}} → 0023-08-05(東漢建立)

require('Module:No globals')

local getArgs = require('Module:Arguments').getArgs
local p = {}

local function toISO(format, string)
	return mw.getCurrentFrame():callParserFunction('#time', format, string)
end

local function convert(input)
	input = input:gsub(" "," ");
	input = input:gsub("%s+"," ");
	local y, m, d, suf
	local datePatternList = {
		-- English date format
		{'%d%d? ?%a+[ ,]*%d+', 'Y-m-d'},	-- 26 Oct 1994
		{'%a+ ?%d%d?[ ,]+%d+', 'Y-m-d'},	-- Oct 26, 1994
		{'%a+[ ,]*%d%d%d%d+', 'Y-m'},		-- Oct 1994
		{'%a+ ?%d%d?', 'Y-m-d'},			-- Oct 26
		{'%d%d? *%a+', 'Y-m-d'},			-- 26 Oct
		-- Slash or hyphen date format
		{'%d+/%d%d?/%d+', 'Y-m-d'},			-- 1994/10/26 or 10/26/1994
		{'%d+%.%d%d?%.%d+', 'Y-m-d'},			-- 1994.10.26 or 26.10.1994
		{'%d%d?/%d%d?', 'Y-m-d'},			-- 10/26
		{'%d+%-%d%d?%-%d+', 'Y-m-d'},		-- 1994-10-26 or 26-10-94
		{'%d%d%d%d+%-%d%d?', 'Y-m'},		-- 1994-10
		{'%d%d%d%d', 'Y'},					-- 1994
	}

	y, m, d, suf = string.match(input, '^(%d+)年(%d%d?)月(%d%d?)日(.*)$');
	if y then
		if #y < 4 then
			y = string.rep(0, 4 - #y) .. y
		end
		return toISO('Y-m-d', y .. '-' .. m .. '-' .. d) , suf
	end

	y, m, suf = string.match(input, '^(%d+)年(%d%d?)月(.*)$');
	if y then
		if #y < 4 then
			y = string.rep(0, 4 - #y) .. y
		end
		return toISO('Y-m', y .. '-' .. m) , suf
	end

	y, suf = string.match(input, '^(%d+)年(.*)$');
	if y then
		if #y < 4 then
			y = string.rep(0, 4 - #y) .. y
		end
		return toISO('Y', y) , suf
	end

	for _, value in ipairs(datePatternList) do
		local str, suf = string.match(input, '^(' .. value[1] .. ')(.*)$');
		if str then
			return toISO(value[2], str), suf
		end
	end

	return toISO('Y-m-d', 'error')
end

function p.dates(frame)
	local args = getArgs(frame)
	return p._dates(args)
end

function p._dates(args)
	local returnval, suf = convert(args[1])
	local errorMessage = toISO('Y-m-d', 'error')

	if returnval == errorMessage and args.error == 'ignore' then
		return args[1]
	end

	return returnval .. (args.suffix and suf or '')
end

function p.dateAndSuffix(string)
	return convert(string)
end

return p