跳转到内容

模組:Date Convert/sandbox

本页使用了标题或全文手工转换
维基百科,自由的百科全书

这是本页的一个历史版本,由SunAfterRain留言 | 贡献2023年8月15日 (二) 08:39编辑。这可能和当前版本存在着巨大的差异。

require('Module:No globals')

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

local timeErrorMessage
local function getTimeErrorMessage()
	if not timeErrorMessage then
		timeErrorMessage = mw.getCurrentFrame():callParserFunction('#formatTime', '', 'error')
	end
	return timeErrorMessage
end

local function makeError(message)
	if not mError then
		mError = require('Module:Error')
	end
	return mError.error({'[[Module:Date Convert]]錯誤:' .. message})
end

local langObj = mw.language.getContentLanguage

local function formatTime(format, input)
	local success, value = pcall(function ()
		return langObj:formatDate(format, input)
	end)
	if success then
		return value
	end
	return nil
end

-- @args input (string)
-- @returns
-- - format ('Y-m-d'/'Y-m'/'Y'/'m-d'/nil)
-- - val (string/nil)
-- - suf (string/nil)
local function convert(input)
	input = input
		:gsub(" "," ")
		:gsub("%s+"," ")
		
		:gsub('(%a+)[ ,]*(%d+)', '%1 %2');
		
	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 '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 '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 'Y', y, suf
	end
	
	m, d, suf = string.match(input, '^(%d%d?)月(%d%d?)日(.*)$');
	if m and tonumber(m) then
		return 'm-d', m .. '-' .. d, suf
	end

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

	return nil, nil, nil
end

function p._converttime(input, showsuf)
	local format, date, suf = convert(input)
	local result = formatTime(format, date) or getTimeErrorMessage()
	if (yesno(showsuf)) then
		return result .. suf
	else
		return result
	end
end

local function dateFunctionWrap(template, formatFunction)
	if not formatFunction then
		formatFunction = formatTime
	end

	return function (args)
		local input = args[1]
		if not input or input == '' then
			return makeError('輸入為空。')
		end

		local format, date, suffix = convert(input)
		suffix = (args.suf and suffix) or ''

		local result = formatFunction(format, date)

		if result then
			return result
		elseif args.error == 'ignore' then
			return input
		else
			return getTimeErrorMessage() .. '[[Category:Template:' .. template .. '使用錯誤]]'
		end
	end
end

function p.ChineseDate(frame)
	local args = getArgs(frame)
	return p._ChineseDate(args)
end

p._ChineseDate = dateFunctionWrap('Chinese date', function (format, date)
	if format == 'Y-m-d' then
		return formatTime('Y年n月j日', date):gsub("^0+","")
	elseif format == 'Y-m' then
		return formatTime('Y年n月', date):gsub("^0+","")
	elseif format == 'Y' then
		return formatTime('Y年', date):gsub("^0+","")
	elseif format == 'm-d' then
		return formatTime('n月j日', date):gsub("^0+","")
	else
		error('Internal error: invalid format "' .. format .. '".')
	end
end)
p._ISODate = dateFunctionWrap('ISODate')

local function invokeWarp(func)
	return function (frame)
		local args = getArgs(frame)
		return p[func](args)
	end
end

p.ChineseDate = invokeWarp('_ChineseDate')
p.ISODate = invokeWarp('_ISODate')

return p