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