封装使用

先看看封装后的使用
在这里插入图片描述

注意输出:

Source date time data :
  USA_datetime_str : 
    2020-11-20 15:30:10
  USA_UTC_offset_hours : 
    -5
Tranform to :
  CHINA_BeiJing_datetime_str : 
    2020-11-21 4:30:10
  CHINA_BeiJing_UTC_offset_hours : 
    8

Source Code

Const = {}
LuaUtil = {}

Const.EnableTimeZoneSummer = true
Const.EnableTimeZoneFall = false

--[[
    @desc: 可替换包含{xxx}的内容
    author: jave.lin
    time:2020-12-09 14:30:58
    --@format_str: 带占位格式的字符串 "{year}-{month}-{day} {hour}:{min}:{sec}"
	--@tbl: 包含{xxx}的内容:{ year = 2020, month = 12, day = 9, hour = 14, min = 30, sec = 58}
	--@p: nil or "{(%w+)}
    @return: 替换了 {xxx} 的内容
]]
table.format = function(format_str, tbl, p)
	p = p or "{(%w+)}"
	return tostring(string.gsub(format_str, p, tbl))
end

--[[
    @desc: 获取 timestamp 时间戳对应的时间日期的表现方式
    author: jave.lin
    time:2020-12-09 15:32:31
	--@timestamp: 时间戳,单位:秒
    --@format_str: 带占位格式的字符串 "{year}-{month}-{day} {hour}:{min}:{sec}"
	--@p: nil or "{(%w+)}
    @return: 返回 timestamp 对应的日期时间的表示字符串
]]
function LuaUtil.getDateTimeStr(timestamp, format_str, p)
    format_str = format_str or "{year}-{month}-{day} {hour}:{min}:{sec}"
    return table.format(format_str, os.date("*t", timestamp), p)
end
function LuaUtil.getDateTimeStrByTbl(datetime_tbl, format_str, p)
    format_str = format_str or "{year}-{month}-{day} {hour}:{min}:{sec}"
    return table.format(format_str, datetime_tbl, p)
end

--[[
    @desc: 获取本地时区相对 UTC 的时差值,单位:秒,如:北京时差 +8,那么返回:8 * 3600 秒
    author: jave.lin
    time:2020-12-24 09:44:02
    @return: 返回相对 UTC 时区的时差值:秒
]]
function LuaUtil.getLocalUtcOffsetSeconds()
    if LuaUtil.__localUtcOffsetSeconds == nil then
        local now_tick = os.time()
        local date_local = os.date("*t", now_tick) -- local
        local date_utc = os.date("!*t", now_tick) -- utc
        local local_utc_offset = os.time(date_local) - os.time(date_utc)
        LuaUtil.__localUtcOffsetSeconds = local_utc_offset
    end
    return LuaUtil.__localUtcOffsetSeconds
end

--[[
    @desc: 获取本地时区相对 UTC 的时差值,单位:小时,如:北京时差 +8,那么返回:8 小时
    author: jave.lin
    time:2020-12-24 09:44:02
    @return: 返回相对 UTC 时区的时差值:小时
]]
function LuaUtil.getLocalUtcOffsetHours()
    if LuaUtil.__localUtcOffsetHours == nil then
        LuaUtil.__localUtcOffsetHours = LuaUtil.getLocalUtcOffsetSeconds() / 3600
    end
    return LuaUtil.__localUtcOffsetHours
end

-- src_zone_timestamp src zone 的时间戳
-- src_zone_offset_hour src zone 的相对 utc 的时间戳
-- return 相对当前 local(本地)的时间戳
--[[
    @desc: 将 src 指定的时间戳(秒)、时区值(小时),转为相对本地相对 utc 的偏差后的时间戳
    author: jave.lin
    time:2020-12-24 09:48:07
    --@src_zone_timestamp: src 指定的时间戳(秒)
	--@src_zone_offset_hour: src 时区值(小时)
    @return: 返回相对本地相对 utc 的偏差后的时间戳
]]
function LuaUtil.srcToLocalUtcOffsetTimestamp(src_zone_timestamp, src_zone_offset_hour)
    local src_utc_timestamp = (src_zone_timestamp - (src_zone_offset_hour * 3600))
    local to_local_utc_timestamp = src_utc_timestamp + LuaUtil.getLocalUtcOffsetSeconds()
    -- 3-5月就是春季,6-8就是夏季,如果是9-11就是秋季,如果是12-2就是冬季
    -- local date_time_tbl = os.date("*t", to_local_utc_timestamp)
    -- 夏令时、冬令时我们不需要额外处理,lua 底层有处理
    -- 冬令时:就是标准时间,按理不需要调整,所以下面的 - 3600 操作是有问题的
    -- os.date 返回的 table 数据中 date_time_tbl.isdst 就是是否夏令时的一个标记,内部有处理,但是显示的话,要是按标准的时间来显示,所以不需要处理
    -- if 
    -- Const.EnableTimeZoneSummer and 
    -- date_time_tbl.month >= 3 and 
    -- date_time_tbl.month <= 5 then
    --     -- 夏令时,在春季调整
    --     to_local_utc_timestamp  = to_local_utc_timestamp + 3600
    -- elseif 
    -- Const.EnableTimeZoneFall and
    -- date_time_tbl.month >= 9 and
    -- date_time_tbl.month <= 11 then
    --     -- 冬令时,在秋季调整
    --     to_local_utc_timestamp  = to_local_utc_timestamp - 3600
    -- end
	return to_local_utc_timestamp
end

--[[
    @desc: 获取 timestamp 时间戳、utc_zone_offset UTC 时差对应的时间日期的表现方式
    author: jave.lin
    time:2020-12-09 15:32:31
    --@timestamp: 目标时区的时间戳,单位:秒
    --@utc_zone_ofset: 目标时区时差,单位:小时,如:美国纽约:-5,中国北京:+8
    --@format_str: 带占位格式的字符串 "{year}-{month}-{day} {hour}:{min}:{sec}"
	--@p: nil or "{(%w+)}
    @return: 返回 timestamp 对应的日期时间的表示字符串
]]
function LuaUtil.getUtcOffsetDateTimeStr(timestamp, utc_zone_ofset, format_str, p)
    local ts = LuaUtil.srcToLocalUtcOffsetTimestamp(timestamp, utc_zone_ofset)
	return LuaUtil.getDateTimeStr(ts, format_str, p)
end


-- USA 时间
local USA_datetime_tbl = { hour=15, min=30, sec=10, year=2020, month=11, day=20 }
-- USA 相对的时间戳
local USA_timestamp = os.time(USA_datetime_tbl)
-- USA 相对 UTC 的时区时差值:小时
local USA_UTC_offset_hours = -5

-- 将 USA 时间戳、USA 相对 UTC 是差值,转换为中国北京的时间戳
local CHINA_BeiJing_timestamp = LuaUtil.srcToLocalUtcOffsetTimestamp(USA_timestamp, USA_UTC_offset_hours)
-- 将时间戳格式化显示字符
local CHINA_BeiJing_datetime_str = LuaUtil.getDateTimeStr(CHINA_BeiJing_timestamp)
-- 也可以使用另一个 API 直接转为格式化的时间日期
-- local CHINA_BeiJing_datetime_str = LuaUtil.getUtcOffsetDateTimeStr(USA_timestamp, USA_UTC_offset_hours)

-- 打印相关信息
print("Source date time data :")
print("  USA_datetime_str : ")
print("    " .. LuaUtil.getDateTimeStrByTbl(USA_datetime_tbl))
print("  USA_UTC_offset_hours : ")
print("    " .. USA_UTC_offset_hours)

print("Tranform to :")
print("  CHINA_BeiJing_datetime_str : ")
print("    " .. CHINA_BeiJing_datetime_str)
print("  CHINA_BeiJing_UTC_offset_hours : ")
print("    " .. LuaUtil.getLocalUtcOffsetHours())

夏令时、冬令时

可以参考:
在这里插入图片描述


注意!


前面封装一堆代码

其实 lua 的 api 已经帮我们处理了

如果是有一个固定的时间戳,如服务器发的一个时间戳:

fixed_timestamp = xxx

那么我们客户端直接用来显示相对我们本地时区对应的时间日期

可以这么使用:

local date_local = os.date("*t", now_tick) -- local
local date_utc = os.date("!*t", now_tick) -- utc

date_local、date_utc 都是 table ,一般我们常用的有:
year、month、day、hour、min、sec,分别对应:年月日时分秒

date_local 就是相对带有 utc 时差后的时间
date_utc 就是时差为 0 的 utc 时间


References

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐