Lua ISO 8601 parsing date and time

I am trying to parse the full date and time of ISO8601 from JSON data in Lua. I have problems with the matching pattern.

So far this is what I have:

-- 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}) 

I am stuck on how to deal with the time zone on the template, because there is no logic or will handle it - either + or nothing. Although I know that lua does not support the time zone in the os.time function, at least I would know how to adjust it.

I decided to film everything after the "." (milliseconds and time zone), but then I really would not have a valid date-time. Milliseconds are not so important, and I would not mind losing it, but the time zone changes the situation.

Note. Someone may have much better code for this, and I'm not married to it, I just need to get something useful from the datetime string :)

+8
date datetime lua parsing
source share
2 answers

The full ISO 8601 format cannot be performed with a single pattern match. Too many changes.

Some examples from the wikipedia page :

  • There is a “compressed” format that does not separate numbers: YYYYMMDD vs YYYY-MM-DD
  • Day can be omitted: YYYY-MM-DD and YYYY-MM are valid dates
  • The ordinal date is also valid: YYYY-DDD , where DDD is the day of the year (1-365 / 6)
  • When presenting time, you can count minutes and seconds: hh:mm:ss , hh:mm and hh are all valid time intervals
  • In addition, time also has a compressed version: hhmmss , hhmm
  • In addition, time takes fractions, using both a period and a comma, to indicate the fraction of the lower time element in the time section. 14:30,5 , 1430,5 , 14:30.5 or 1430.5 all represent 14 hours, 30 seconds and a half.
  • Finally, the time zone section is optional. If available, it can be either the letter Z, ±hh:mm , ±hh , or ±hhmm .

Thus, there are many possible exceptions to consider if you intend to disassemble in accordance with the full specification. In this case, your source code might look like this:

 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 

And then you will need to create parseDate , parseTime and parseOffset . Later, they should return time offsets from UTC, while the first two will have to take into account such things as compressed formats, time fractions, comma delimiters or periods, etc.

parseDate will most likely use the "^" character at the beginning of pattern matches, since the date must be at the beginning of the line. parseTime patterns most likely begin with a "T" . And parseOffset will end with "$" since the time offsets, when they exist, are at the end.

The full ISO parseOffset might look something like this:

 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 

By the way, I assume that your computer is running in UTC. If this is not the case, you will need to add an additional offset to your hours / minutes to account for this.

 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 

To get the local offset, you can look at http://lua-users.org/wiki/TimeZone .

Hope this helps. Hello!

+10
source share

There is also a luadate package that supports iso8601. (Maybe you need a fixed version )

+1
source share

All Articles