如何通过Lua的os.date一次性获取完整日期时间信息表?
Lua一次性获取完整时间信息的解决方案
Lua标准库里,os.date("*t")(本地时间)或os.date("!*t")(UTC时间)只会返回固定结构的时间表,没法直接返回包含所有格式化标签对应字段的完整表。如果要避免多次从系统读取时间(或者严格只调用一次os.date),可以用以下两种方法实现:
方法1:一次生成格式化字符串再解析
把所有需要的时间字段用分隔符拼接成一个格式化模板,调用一次os.date生成字符串后,自行拆分解析成带键名的表:
-- 用|作为分隔符,把所有需要的标签拼进去 local format_template = "%Y|%m|%d|%H|%M|%S|%w|%a|%A|%b|%B|%I|%p|%z|%c|%x|%X|%y" local time_str = os.date(format_template) local field_list = {} -- 拆分字符串 for val in string.gmatch(time_str, "[^|]+") do table.insert(field_list, val) end -- 映射为结构化表 local full_time = { year = tonumber(field_list[1]), month = tonumber(field_list[2]), day = tonumber(field_list[3]), hour = tonumber(field_list[4]), min = tonumber(field_list[5]), sec = tonumber(field_list[6]), weekday_num = tonumber(field_list[7]), -- 0=周日,6=周六 abbr_weekday = field_list[8], full_weekday = field_list[9], abbr_month = field_list[10], full_month = field_list[11], hour_12h = tonumber(field_list[12]), am_pm = field_list[13], timezone = field_list[14], datetime_full = field_list[15], date_str = field_list[16], time_str = field_list[17], year_2digit = tonumber(field_list[18]), isdst = os.date("*t").isdst -- 若不想额外调用,可先存时间戳再用ts调用 }
如果要彻底避免多次系统时间读取,先存当前时间戳,所有操作都基于这个戳:
local current_ts = os.time() local format_template = "%Y|%m|%d|%H|%M|%S|%w|%a|%A|%b|%B|%I|%p|%z|%c|%x|%X|%y" local time_str = os.date(format_template, current_ts) local field_list = {} for val in string.gmatch(time_str, "[^|]+") do table.insert(field_list, val) end local full_time = { year = tonumber(field_list[1]), month = tonumber(field_list[2]), day = tonumber(field_list[3]), hour = tonumber(field_list[4]), min = tonumber(field_list[5]), sec = tonumber(field_list[6]), weekday_num = tonumber(field_list[7]), abbr_weekday = field_list[8], full_weekday = field_list[9], abbr_month = field_list[10], full_month = field_list[11], hour_12h = tonumber(field_list[12]), am_pm = field_list[13], timezone = field_list[14], datetime_full = field_list[15], date_str = field_list[16], time_str = field_list[17], year_2digit = tonumber(field_list[18]), isdst = os.date("*t", current_ts).isdst -- 基于同一时间戳,仅一次系统读取 }
方法2:基础表+补充字段
先调用一次os.date("*t")拿到基础时间表,再基于同一个时间戳生成缺失的格式化字段,补充到表里:
local current_ts = os.time() local base_time = os.date("*t", current_ts) -- 补充所有需要的额外字段 base_time.abbr_weekday = os.date("%a", current_ts) base_time.full_weekday = os.date("%A", current_ts) base_time.abbr_month = os.date("%b", current_ts) base_time.full_month = os.date("%B", current_ts) base_time.hour_12h = tonumber(os.date("%I", current_ts)) base_time.am_pm = os.date("%p", current_ts) base_time.timezone = os.date("%z", current_ts) base_time.datetime_full = os.date("%c", current_ts) base_time.date_str = os.date("%x", current_ts) base_time.time_str = os.date("%X", current_ts) base_time.year_2digit = tonumber(os.date("%y", current_ts))
这种方式虽然多次调用os.date,但所有调用都基于同一个时间戳,本质上只从系统获取了一次时间,不会有时间偏差,代码也更易读,不需要处理字符串解析。
注意事项
os.date("%z")返回时区偏移字符串(比如+0800代表东八区),UTC时间对应的偏移是+0000。- 夏令时标识
isdst只有本地时间的os.date("*t")会返回,UTC时间的isdst始终为nil。
内容的提问来源于stack exchange,提问作者JACK
相关产品推荐
相关产品推荐

