当前位置 : 主页 > 网络编程 > lua >

Lua ISO 8601日期时间解析模式

来源:互联网 收集:自由互联 发布时间:2021-06-23
我正在尝试从Lua中的 JSON数据解析完整的ISO8601日期时间. 我遇到了匹配模式的问题. 到目前为止,这就是我所拥有的: -- Example datetime string 2011-10-25T00:29:55.503-04:00local datetime = "2011-10-25T00
我正在尝试从Lua中的 JSON数据解析完整的ISO8601日期时间.
我遇到了匹配模式的问题.

到目前为止,这就是我所拥有的:

-- Example datetime string 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函数中的时区,但至少我知道它需要如何调整.

我考虑在“.”之后剥掉一切. (毫秒和时区),但那时我真的没有有效的日期时间.毫秒不是那么重要,我不介意失去它,但时区改变了事情.

注意:有人可能有更好的代码来执行此操作而且我没有嫁给它,我只需要从日期时间字符串中获得有用的东西:)

单个模式匹配无法完成完整的ISO 8601格式.变化太多了.

一些例子from the wikipedia page:

>有一种“压缩”格式不能分隔数字: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秒半.
>最后,时区部分是可选的.当存在时,它可以是字母Z,±hh:mm,±hh或±hhmm.

因此,如果您要根据完整规范进行解析,则需要考虑很多可能的例外情况.在这种情况下,您的初始代码可能如下所示:

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 -- ends with Z, Zulu time

  -- matches ±hh:mm, ±hhmm or ±hh; else returns 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.

我希望这有帮助.问候!

网友评论