Lua ISO 8601日期时间解析模式
2011-10-27 3:8:3
收藏:0
阅读:284
评论:3
我正在尝试从 Lua 中的 JSON 数据中解析完整的 ISO8601 日期时间。 我对匹配模式感到困惑。
到目前为止,这是我拥有的:
-- 示例日期时间字符串 2011-10-25T00: 29: 55.503-04: 00
local datetime = "2011-10-25T00:29:55.503-04:00"
local pattern = "(%d+)%-(%d+)%-(%d+)T(%d+):(%d+):(%d+)%.(%d+)"
local xyear, xmonth, xday, xhour, xminute,
xseconds, xmillies, xoffset = datetime:match(pattern)
local convertedTimestamp = os.time({year = xyear, month = xmonth,
day = xday, hour = xhour, min = xminute, sec = xseconds})
我卡在了如何处理模式上的时区,因为没有逻辑或可以处理 - 或 + 或 无。 虽然我知道Lua不支持 os.time函数中的时区,但至少我会知道它需要如何进行调整。
我考虑剥离“.”(毫秒和时区)后的所有内容,但那么我就真的没有一个有效的日期时间了。毫秒并不那么重要,我不介意失去它,但时区改变了事情。
注:有人可能有更好的代码来完成这项任务,而我并没有固定的代码,我只需要从日期时间字符串中得到一些有用的东西 :)
原文链接 https://stackoverflow.com/questions/7911322
点赞
stackoverflow用户333296
这里是一个用于解析 ISO 日期的简单的 parseDate
函数。请注意,我把 "now" 作为备用选项。这可能适用于您,也可能不适用。你最好自己试试。
--[[
解析给定的日期格式。
注意!对于无法识别的格式,将返回当前时间。
@param str ISO 日期格式。可选的格式如下:
Y-m-d
Y-m -- 这将假定为 1 月
Y -- 这将假定为 1 月 1 日
]]
function parseDate(str)
local y, m, d = str:match("(%d%d%d%d)-?(%d?%d?)-?(%d?%d?)$")
-- 如果没有匹配到日期,就使用当前时间
if y == nil then
return os.time()
end
-- 默认值
if m == '' then
m = 1
end
if d == '' then
d = 1
end
-- 创建时间
return os.time{year=y, month=m, day=d, hour=0}
end
--[[
--测试代码:
print( os.date( "%Y-%m-%d", parseDate("2019-12-28") ) )
print( os.date( "%Y-%m-%d", parseDate("2019-12") ) )
print( os.date( "%Y-%m-%d", parseDate("2019") ) )
]]
2019-11-25 22:37:45
评论区的留言会收到邮件通知哦~
推荐文章
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
完整的 ISO 8601 格式不能通过一个模式匹配来完成,因为其中变化太多了。
一些例子(来自维基百科):
YYYYMMDD
与YYYY-MM-DD
YYYY-MM-DD
与YYYY-MM
都是合法的日期YYYY-DDD
,其中DDD
是一年中的日期(1-365/6)hh:mm:ss
,hh:mm
和hh
都是合法的时间hhmmss
,hhmm
14:30,5
,1430,5
,14:30.5
或1430.5
都表示 14 小时、30 分钟和一半。因此,如果你要根据完整规范解析日期时间,就需要考虑大量的可能性。在这种情况下,你的初始代码可能是这样的:
function parseDateTime(str) local Y,M,D = parseDate(str) local h,m,s = parseTime(str) local oh,om = parseOffset(str) return os.time({year=Y, month=M, day=D, hour=(h+oh), min=(m+om), sec=s}) end
然后你需要创建
parseDate
、parseTime
和parseOffset
。后者应该返回对于 UTC 的时间偏移量,而前两个则必须考虑到这样的事情,如压缩格式、时间小数、逗号或点分隔符等等。parseDate
可能会在其模式匹配的开头使用"^"
字符,因为日期必须在字符串开头。parseTime
的模式可能会以"T"
开头。而parseOffset
的模式会以"$"
结尾,因为时间偏移量在存在时,它们在结尾处。一个“完整 ISO”
parseOffset
函数可能看起来像这样:function parseOffset(str) if str:sub(-1)=="Z" then return 0,0 end -- 以 Z 结尾,表示 Zulu 时间 -- 匹配 ±hh:mm、±hhmm 或 ±hh;否则返回 nils local sign, oh, om = str:match("([-+])(%d%d):?(%d?%d?)$") sign, oh, om = sign or "+", oh or "00", om or "00" return tonumber(sign .. oh), tonumber(sign .. om) end
顺便说一句,我假设你的计算机正在使用 UTC 时间。如果不是这样的话,你将不得不包括一个额外的偏移量来计算它。
function parseDateTime(str) local Y,M,D = parseDate(str) local h,m,s = parseTime(str) local oh,om = parseOffset(str) local loh,lom = getLocalUTCOffset() return os.time({year=Y, month=M, day=D, hour=(h+oh-loh), min=(m+om-lom), sec=s}) end
获取你的本地偏移量,你可能需要查看 http://lua-users.org/wiki/TimeZone。
希望这能有所帮助。敬礼!