模块:TimeZone
此模块的文档可以在模块:TimeZone/doc创建
local module = {}
function module.getTimeZone(frame)
local hour, minute = normalize(frame.args[1])
local timezone = timeZoneToString(hour, minute)
local output = frame.args["output"]
if output == "number" then
return timezone
elseif output == "utc" then
return "UTC"..timezone
elseif output == "text" then
if timezone == "+00:00" then
return "零时区"
else
local left, middle
--当时间差超过±12小时,在计算时区是必须调整至±12小时的范围内。
local hour = math.fmod(hour, 24)
local abs_hour = math.abs(hour)
local sign = hour / abs_hour
if abs_hour > 12 or (abs_hour == 12 and minute > 0) then
hour = 24 - abs_hour
if minute ~= 0 then
hour = hour - 1
minute = 60 - minute
end
hour = -sign * hour
end
if hour < 0 then
left = "西"
else
left = "东"
end
local texts = {"一","二","三","四","五","六","七","八","九","十","十一","十二"}
middle = texts[math.abs(tonumber(hour))]
return left..middle.."区"
end
end
end
function module.convert(frame)
local args = frame.args
local year = tonumber(args["year"])
local month = tonumber(args["month"])
local day = tonumber(args["day"])
local hour = tonumber(args["hour"]) or 12
local minute = tonumber(args["minute"]) or 0
local second = tonumber(args["second"]) or 0
local o_hour, o_minute = normalize(args["o_timezone"])
local c_hour, c_minute = normalize(args["c_timezone"])
local o_sign, c_sign
if o_hour >= 0 then o_sign = 1 else o_sign = -1 end
if c_hour >= 0 then c_sign = 1 else c_sign = -1 end
local difftime = (c_hour * 3600 + o_sign * c_minute * 60) -
(o_hour * 3600 + c_sign * o_minute * 60)
local o_time = { year = year, month = month, day = day, hour = hour, min = minute, sec = second }
local c_time = os.date("*t", os.time(o_time) + difftime)
local text = args[1] or ""
--剥离nowiki标签。
text = mw.text.unstripNoWiki(text)
text = mw.text.decode(text)
--格式化日期
c_time['timezone'] = {c_hour, c_minute}
text = formatDate(text, c_time)
--生成能解析wiki文本的字符串。
text = frame:preprocess(text)
return text
end
function module.formatList(frame)
local var_array = require("Module:Var-array")
local formatList = {}
for i, item in ipairs(getFormat()) do
table.insert(formatList, { item.format, item.description })
end
var_array.new("timezone.convert.formatlist", formatList)
end
function getFormat()
return {
{
format = "%(y)",
description = "不包含纪元的年份。如果不包含纪元的年份小于10,则显示不具有前导零的年份。",
callback = function(matched_times, time) return tostring(tonumber(string.sub(tostring(time.year), -2))) end
},
{
format = "%y",
description = "不包含纪元的年份。如果不包含纪元的年份小于10,则显示不具有前导零的年份。<code>%(y)</code>的简略写法。",
callback = function(matched_times, time) return tostring(tonumber(string.sub(tostring(time.year), -2))) end
},
{
format = "%(yy)",
description = "不包含纪元的年份。如果不包含纪元的年份小于10,则显示具有前导零的年份。",
callback = function(matched_times, time) return string.format("%02d", tonumber(string.sub(tostring(time.year), -2))) end
},
{
format = "%(yyyy)",
description = "包括纪元的四位数的年份。",
callback = function(matched_times, time) return tostring(time.year) end
},
{
format = "%(gg)",
description = "时期或纪元。如果要设置格式的日期不具有关联的时期或纪元字符串,则忽略该模式。",
callback = function(matched_times, time) return tostring((tonumber(time.year) - tonumber(string.sub(tostring(time.year), -2))) / 100) end
},
{
format = "%(M)",
description = "月份数字。一位数的月份没有前导零。",
callback = function(matched_times, time) return tostring(tonumber(time.month)) end
},
{
format = "%M",
description = "月份数字。一位数的月份没有前导零。<code>%(M)</code>的简略写法。",
callback = function(matched_times, time) return tostring(tonumber(time.month)) end
},
{
format = "%(MM)",
description = "月份数字。一位数的月份有一个前导零。",
callback = function(matched_times, time) return string.format("%02d", (tonumber(time.month))) end
},
{
format = "%(MMM)",
description = "月份的缩写名称。",
callback = function(matched_times, time)
local AbbreviatedMonthNames = { "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二" }
return AbbreviatedMonthNames[tonumber(time.month)]
end
},
{
format = "%(MMMM)",
description = "月份的缩写名称。",
callback = function(matched_times, time)
local AbbreviatedMonthNames = { "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二" }
return AbbreviatedMonthNames[tonumber(time.month)].."月"
end
},
{
format = "%(D)",
description = "年中的某一天。",
callback = function(matched_times, time)
t1 = { year = time.year, month = time.month, day = time.day, hour = 0, min = 0, sec = 0 }
t2 = { year = time.year, month = 1, day = 1, hour = 0, min = 0, sec = 0 }
return tostring(math.floor(os.difftime(os.time(t1), os.time(t2)) / 86400))
end
},
{
format = "%D",
description = "年中的某一天。<code>%(D)</code>的简略写法。",
callback = function(matched_times, time)
t1 = { year = time.year, month = time.month, day = time.day, hour = 0, min = 0, sec = 0 }
t2 = { year = time.year, month = 1, day = 1, hour = 0, min = 0, sec = 0 }
return tostring(math.floor(os.difftime(os.time(t1), os.time(t2)) / 86400))
end
},
{
format = "%(DD)",
description = "这一年共有多少天。",
callback = function(matched_times, time)
t1 = { year = time.year + 1, month = 1, day = 1, hour = 0, min = 0, sec = 0 }
t2 = { year = time.year, month = 1, day = 1, hour = 0, min = 0, sec = 0 }
return tostring(math.floor(os.difftime(os.time(t1), os.time(t2)) / 86400))
end
},
{
format = "%(d)",
description = "月中的某一天。一位数的日期没有前导零。",
callback = function(matched_times, time) return tostring(tonumber(time.day)) end
},
{
format = "%d",
description = "月中的某一天。一位数的日期没有前导零。<code>%(d)</code>的简略写法。",
callback = function(matched_times, time) return tostring(tonumber(time.day)) end
},
{
format = "%(dd)",
description = "月中的某一天。一位数的日期有一个前导零。",
callback = function(matched_times, time) return string.format("%02d", tonumber(time.day)) end
},
{
format = "%(w)",
description = "周中的某一天。",
callback = function(matched_times, time) return tostring(tonumber(time.wday)) end
},
{
format = "%w",
description = "周中的某一天。<code>%(w)</code>的简略写法。",
callback = function(matched_times, time) return tostring(tonumber(time.wday)) end
},
{
format = "%(ww)",
description = "周中某天的缩写名称。",
callback = function(matched_times, time)
local wday = tonumber(time.wday)
return mw.ustring.sub("日一二三四五六", wday, wday)
end
},
{
format = "%(www)",
description = "周中某天的缩写名称。",
callback = function(matched_times, time)
local wday = tonumber(time.wday)
return "星期"..mw.ustring.sub("日一二三四五六", wday, wday)
end
},
{
format = "%(h)",
description = "12 小时制的小时。一位数的小时数没有前导零。",
callback = function(matched_times, time) return tostring(math.fmod(tonumber(time.hour), 12)) end
},
{
format = "%h",
description = "12 小时制的小时。一位数的小时数没有前导零。<code>%(h)</code>的简略写法。",
callback = function(matched_times, time) return tostring(math.fmod(tonumber(time.hour), 12)) end
},
{
format = "%(hh)",
description = "12 小时制的小时。一位数的小时数有一个前导零。",
callback = function(matched_times, time) return string.format("%02d", math.fmod(tonumber(time.hour), 12)) end
},
{
format = "%(H)",
description = "24 小时制的小时。一位数的小时数没有前导零。",
callback = function(matched_times, time) return tostring(tonumber(time.hour)) end
},
{
format = "%H",
description = "24 小时制的小时。一位数的小时数没有前导零。<code>%(H)</code>的简略写法。",
callback = function(matched_times, time) return tostring(tonumber(time.hour)) end
},
{
format = "%(HH)",
description = "24 小时制的小时。一位数的小时数有一个前导零。",
callback = function(matched_times, time) return string.format("%02d", tonumber(time.hour)) end
},
{
format = "%(m)",
description = "分钟。一位数的分钟数没有前导零。",
callback = function(matched_times, time) return tostring(tonumber(time.min)) end
},
{
format = "%m",
description = "分钟。一位数的分钟数没有前导零。<code>%(m)</code>的简略写法。",
callback = function(matched_times, time) return tostring(tonumber(time.min)) end
},
{
format = "%(mm)",
description = "分钟。一位数的分钟数有一个前导零。",
callback = function(matched_times, time) return string.format("%02d", tonumber(time.min)) end
},
{
format = "%(s)",
description = "秒。一位数的秒数没有前导零。",
callback = function(matched_times, time) return tostring(tonumber(time.sec)) end
},
{
format = "%s",
description = "秒。一位数的秒数没有前导零。<code>%(s)</code>的简略写法。",
callback = function(matched_times, time) return tostring(tonumber(time.sec)) end
},
{
format = "%(ss)",
description = "秒。一位数的秒数有一个前导零。",
callback = function(matched_times, time) return string.format("%02d", tonumber(time.sec)) end
},
{
format = "%(sss)",
description = "Unix时间戳(Unix timestamp)。从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。",
callback = function(matched_times, time) return tostring(os.time(time)) end
},
{
format = "%(t)",
description = "一天中时间段的更加详细的提示信息。",
callback = function(matched_times, time)
local hour = tonumber(time.hour)
if hour < 12 then return "上午"
else return "下午"
end
end
},
{
format = "%t",
description = "一天中时间段的更加详细的提示信息。<code>%(t)</code>的简略写法。",
callback = function(matched_times, time)
local hour = tonumber(time.hour)
if hour < 12 then return "上午"
else return "下午"
end
end
},
{
format = "%(tt)",
description = "一天中时间段的更加详细的提示信息。",
callback = function(matched_times, time)
local hour = tonumber(time.hour)
if hour < 7 then return "凌晨"
elseif hour < 11 then return "上午"
elseif hour < 13 then return "中午"
elseif hour < 17 then return "下午"
elseif hour < 20 then return "傍晚"
elseif hour < 22 then return "晚上"
else return "深夜"
end
end
},
{
format = "%(z)",
description = "时区偏移量(“+”或“-”后面仅跟小时)。一位数的小时数没有前导零。例如,太平洋标准时间是“-8”。",
callback = function(subStr, time)
local hour, minute = time.timezone[1], time.timezone[2]
if hour >= 0 then return "+"..hour
else return tostring(hour)
end
end
},
{
format = "%z",
description = "时区偏移量(“+”或“-”后面仅跟小时)。一位数的小时数没有前导零。例如,太平洋标准时间是“-8”。<code>%(z)</code>的简略写法。",
callback = function(subStr, time)
local hour, minute = time.timezone[1], time.timezone[2]
if hour >= 0 then return "+"..hour
else return tostring(hour)
end
end
},
{
format = "%(zz)",
description = "时区偏移量(“+”或“-”后面仅跟小时)。一位数的小时数有前导零。例如,太平洋标准时间是“-08”。",
callback = function(subStr, time)
local hour, minute = time.timezone[1], time.timezone[2]
if hour >= 0 then return string.format("+%02d", hour)
else return string.format("-%02d", -hour)
end
end
},
{
format = "%(zzz)",
description = "完整时区偏移量(“+”或“-”后面跟有小时和分钟)。一位数的小时数和分钟数有前导零。例如,太平洋标准时间是“-08:00”。",
callback = function(subStr, time)
mw.log('zzzzz')
return timeZoneToString(time.timezone[1], time.timezone[2])
end
},
{
format = "%(%)",
description = "表示字符“%”。",
callback = function(matched_times, time) return "%" end
},
{
format = "%%",
description = "表示字符“%”。<code>%(%)</code>的简略写法。",
callback = function(matched_times, time) return "%" end
}
}
end
function formatDate(text, timeInfo)
local FormatString = require("Module:FormatString")
local tree = FormatString.buildTrie(getFormat())
text = FormatString.replaceStr(text, tree, timeInfo)
return text
end
function normalize(timezone)
if timezone == nil or #timezone == 0 then
return currentTimeZone() --用户当前时区
else
local hour, minute = mw.ustring.match(mw.text.trim(timezone), "^([-%+]?%d+):?(%d*)$")
if hour == nil then
error("时区参数格式不正确。")
end
return tonumber(hour), tonumber(minute) or 0
end
end
function currentTimeZone()
-- 2020.12.19: 由于服务端未知改动,本函数功能已失效,将默认返回表示东八区的时区信息。
if true then
return 8, 0
else
local a = os.date('!*t',os.time())--中时区的时间
local b = os.date('*t',os.time())
local seconds = os.difftime(os.time(b), os.time(a))
local hour = math.floor(math.abs(seconds) / 3600)
local minute = math.floor((math.abs(seconds) - hour * 3600) / 60)
if seconds < 0 then
hour = -hour
if minute ~= 0 then
minute = 60 - minute
end
end
return hour, minute
end
end
function timeZoneToString(hour, minute)
if minute == nil then minute = 0 end
if hour >= 0 then
return mw.ustring.format("+%02d:%02d", hour, minute)
else
return mw.ustring.format("-%02d:%02d", math.abs(hour), minute)
end
end
return module