From: daurnimator Date: Tue, 22 Oct 2013 19:02:39 +0000 (-0400) Subject: Add a `parse` module X-Git-Url: https://git.madduck.net/etc/awesome.git/commitdiff_plain/30d7af10d208006ea09f32bd006c2cb2556a36ac Add a `parse` module --- diff --git a/luatz-scm-0.rockspec b/luatz-scm-0.rockspec index 96709c7..167745a 100644 --- a/luatz-scm-0.rockspec +++ b/luatz-scm-0.rockspec @@ -24,6 +24,7 @@ build = { modules = { ["luatz.init"] = "luatz/init.lua" ; ["luatz.gettime"] = "luatz/gettime.lua" ; + ["luatz.parse"] = "luatz/parse.lua" ; ["luatz.timetable"] = "luatz/timetable.lua" ; ["luatz.tzcache"] = "luatz/tzcache.lua" ; ["luatz.tzfile"] = "luatz/tzfile.lua" ; diff --git a/luatz/init.lua b/luatz/init.lua index 1f223d1..2ad2ae8 100644 --- a/luatz/init.lua +++ b/luatz/init.lua @@ -8,5 +8,6 @@ return { get_tz = get_tz ; gettime = require "luatz.gettime".gettime ; gettimein = gettimein ; + parse = require "luatz.parse" ; timetable = require "luatz.timetable" ; } diff --git a/luatz/parse.lua b/luatz/parse.lua new file mode 100644 index 0000000..2c5f8d3 --- /dev/null +++ b/luatz/parse.lua @@ -0,0 +1,40 @@ +local new_timetable = require "luatz.timetable".new + +--- Parse an RFC 3339 datetime at the given position +-- Returns a time table and the `tz_offset` +-- Return value is not normalised (this preserves a leap second) +-- If the timestamp is only partial (i.e. missing "Z" or time offset) then `tz_offset` will be nil +-- TODO: Validate components are within their boundarys (e.g. 1 <= month <= 12) +local function rfc_3339 ( str , init ) + local year , month , day , hour , min , sec , patt_end = str:match ( "^(%d%d%d%d)%-(%d%d)%-(%d%d)[Tt](%d%d%.?%d*):(%d%d):(%d%d)()" , init ) + if not year then + error ( "Invalid RFC 3339 timestamp" ) + end + year = tonumber ( year ) + month = tonumber ( month ) + day = tonumber ( day ) + hour = tonumber ( hour ) + min = tonumber ( min ) + sec = tonumber ( sec ) + + local tt = new_timetable ( year , month , day , hour , min , sec ) + + local tz_offset + if str:match ("^[Zz]" , patt_end ) then + tz_offset = 0 + else + local hour_offset , min_offset = str:match ( "^([+-]%d%d):(%d%d)" , patt_end ) + if hour_offset then + tz_offset = tonumber ( hour_offset )*60 + tonumber ( min_offset ) + else + -- Invalid RFC 3339 timestamp offset (should be Z or (+/-)hour:min + -- tz_offset will be nil + end + end + + return tt , tz_offset +end + +return { + rfc_3339 = rfc_3339 ; +} diff --git a/spec/parse_spec.lua b/spec/parse_spec.lua new file mode 100644 index 0000000..f66015a --- /dev/null +++ b/spec/parse_spec.lua @@ -0,0 +1,14 @@ +describe ( "Time parsing library" , function ( ) + local timetable = require "luatz.timetable" + local parse = require "luatz.parse" + + it ( "RFC 3339 Parsing" , function ( ) + assert.same ( timetable.new(2013,10,22,14,17,02) , (parse.rfc_3339 "2013-10-22T14:17:02Z") ) + + -- Numeric offsets accepted + assert.same ( { timetable.new(2013,10,22,14,17,02) , 10*60 } , { parse.rfc_3339 "2013-10-22T14:17:02+10:00" } ) + + -- Missing offsets parse + assert.same ( timetable.new(2013,10,22,14,17,02) , (parse.rfc_3339 "2013-10-22T14:17:02") ) + end ) +end )