最近做一个功能,有用到时间区间来判断功能是否开启。
[os. time] - gets the system time.
遇到玩家,在对应时间进不去功能的情况。
排查许久,发现是海外玩家时区导致。
于是,解决时区问题:
local now = os.time()
local timeZone = os.difftime(now, os.time(os.date("!*t", now))) / 3600 -- 获取系统时区
中国是东八区,即chinaTimeZone = 8
算出时区差:
local deltaTimeZone = 8 - timeZone
差一个时区,就是3600秒,所以换算成东八区的时间即为:
local chinaTime = os.time() + deltaTimeZone * 3600
以为问题解决,昨天又有反馈,有玩家在西班牙又出现进不去功能的情况。
又是一顿排查,竟然是他喵的夏令时——这个鬼东西。
于是,解决夏令时问题:
local isDst = os.date("*t").isdst -- 判断有无夏令时
如果有夏令时,那os.time()是+1小时的,因此最终校正后的时间为:
local chinaTime = os.time(serverTimeTable) + deltaTimeZone * 3600 - (isDst and 1 or 0) * 3600 --serverTimeTable是把服务器时间转换成当地时间格式的、形如{year = 2022, month = 9, day = 1, hour = 9, min = 17, sec = 50}的表
这玩意儿很容易绕,所以再举个例子验证:
Eg:西班牙(+1区)时间6:50(且当前存在夏令时),北京(+8区)时间12:50。
6:50+(8-1)h - 1 h = 12:50
本地windows系统修改时区为西班牙,然后调用os.time()获取的时间戳,竟然是北京时间下的??(因为这个是绝对时间戳)
而os.time({year = 2022, month = 9, day = 1, hour = 9, min = 17, sec = 50}), 这样得出的时间戳,是西班牙时区的
Why? 看这个:lua中os.time和os.date区别?