跳转到内容

模組:Date Convert/sandbox

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

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('#time', '', '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)
	if input then
		local success, value = pcall(function ()
			return langObj:formatDate(format, input)
		end)
		if success then
			return value
		end
	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 addSuffix(args, suffix)
	if suffix and (yesno(args.suf) or yesno(args.suffix)) then
		return suffix
	end
	return ''
end

local function dateFunctionWrap(template, formatFunction, postFormatFunction)
	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)

		local result = date and formatFunction(format, date) or nil

		if result then
			if postFormatFunction then
				return postFormatFunction(result) .. addSuffix(args, suffix)
			end
			return result .. addSuffix(args, suffix)
		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', --[=[ formatFunction ]=] function(format, date)
	if format == 'Y-m-d' then
		return formatTime('Y年n月j日', date)
	elseif format == 'Y-m' then
		return formatTime('Y年n月', date)
	elseif format == 'Y' then
		return formatTime('Y年', date)
	elseif format == 'm-d' then
		return formatTime('n月j日', date)
	end
	error('Internal error: invalid format "' .. format .. '".')
end, --[=[ postFormatFunction ]=] function(value)
	value = value:gsub("^0+","")
	return value
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