最近做海外游戏,遇到夏令时切换的问题, 需求是夏令时切换的时候要刷新界面上的时间。
测试调用1000次,耗时20毫秒,直接上代码。
注意:要判断1月1号和6月1号的时区是否一样, 不一样的才有夏令时,不是所有机器都有夏令时。
function table.clone(object, isArray)
local pi
if isArray then
pi = ipairs
else
pi = pairs
end
local newTab = {}
for i,v in pi(object) do
local t = type(v)
if t == "table" then
newTab[i] = table.clone(v, isArray)
elseif t == "string" or t == "number" then
newTab[i] = v
end
end
return newTab
end
time = {}
--获取时差
function time.timeZone()
local now = os.time() --当前时间戳
local utcTab = os.date("!*t", now)
local nowTab = os.date("*t", now)
return now - os.time(utcTab) + (nowTab.isdst and 3600 or 0)
end
function time.time2tab(unixTime)
return os.date("*t", unixTime)
end
function time.tab2time(tab)
tab.isdst = nil
return os.time(tab)
end
function time.nextDstTime()
local timeNow = os.time()
local timeTab = time.time2tab(timeNow)
local isdst = timeTab.isdst
local function _nextZeroTime(timeTab, _month, _addYear, needDST)
timeTab.year = timeTab.year + _addYear
timeTab.month = _month
timeTab.day = 1
timeTab.hour = 0
timeTab.min = 0
timeTab.sec = 0
local wday = time.time2tab(time.tab2time(timeTab)).wday
timeTab.day = timeTab.day + (8-wday) + (_month == 3 and 7 or 0) --3月的第2个星期日~11月的第1个星期日
local startTime = time.tab2time(timeTab)
for i=1,100 do
if time.time2tab(startTime).isdst == needDST then
return startTime
end
startTime = startTime + 3600
end
ERROR("_nextZeroTime fail.")
end
--今年夏令时开始
local startTime = _nextZeroTime(table.clone(timeTab), 3, 0, true)
if timeNow < startTime then
return startTime
end
--今年夏令时结束
startTime = _nextZeroTime(table.clone(timeTab), 11, 0, false)
if timeNow<=startTime then
return startTime
end
--明年夏令时开始
startTime = _nextZeroTime(table.clone(timeTab), 3, 1, true)
if timeNow<=startTime then
return startTime
else
ERROR("nextDstTime fail.")
end
end