Lua - 从指定时区提供的时间戳、时区的 UTC 时差,转换为对应当前本地 UTC 时差后的时间
封装使用先看看封装后的使用注意输出:Source date time data :USA_datetime_str :2020-11-20 15:30:10USA_UTC_offset_hours :-5Tranform to :CHINA_BeiJing_datetime_str :2020-11-21 4:30:10CHINA_BeiJing_UTC_offset_hours :8Source
·
封装使用
先看看封装后的使用
注意输出:
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
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献5条内容
所有评论(0)