local tz_info_mt = require "luatz.tzinfo".tz_info_mt
local tt_info_mt = require "luatz.tzinfo".tt_info_mt
+local read_int32be, read_int64be
-local function read_int32be ( fd )
- local data , err = fd:read ( 4 )
- if data == nil then return nil , err end
- local o1 , o2 , o3 , o4 = data:byte ( 1 , 4 )
+if string.unpack then -- Only available in Lua 5.3+
+ function read_int32be(fd)
+ local data, err = fd:read(4)
+ if data == nil then return nil, err end
+ return string.unpack(">i4", data)
+ end
- local unsigned = o4 + o3*2^8 + o2*2^16 + o1*2^24
- if unsigned >= 2^31 then
- return unsigned - 2^32
- else
- return unsigned
+ function read_int64be(fd)
+ local data, err = fd:read(8)
+ if data == nil then return nil, err end
+ return string.unpack(">i8", data)
+ end
+else
+ function read_int32be(fd)
+ local data, err = fd:read(4)
+ if data == nil then return nil, err end
+ local o1, o2, o3, o4 = data:byte(1, 4)
+
+ local unsigned = o4 + o3*2^8 + o2*2^16 + o1*2^24
+ if unsigned >= 2^31 then
+ return unsigned - 2^32
+ else
+ return unsigned
+ end
end
-end
-local function read_int64be ( fd )
- local data , err = fd:read ( 8 )
- if data == nil then return nil , err end
- local o1 , o2 , o3 , o4 , o5 , o6 , o7 , o8 = data:byte ( 1 , 8 )
+ function read_int64be(fd)
+ local data, err = fd:read(8)
+ if data == nil then return nil, err end
+ local o1, o2, o3, o4, o5, o6, o7, o8 = data:byte(1, 8)
- local unsigned = o8 + o7*2^8 + o6*2^16 + o5*2^24 + o4*2^32 + o3*2^40 + o2*2^48 + o1*2^56
- if unsigned >= 2^63 then
- return unsigned - 2^64
- else
- return unsigned
+ local unsigned = o8 + o7*2^8 + o6*2^16 + o5*2^24 + o4*2^32 + o3*2^40 + o2*2^48 + o1*2^56
+ if unsigned >= 2^63 then
+ return unsigned - 2^64
+ else
+ return unsigned
+ end
end
end
local TZ
- if version == "2" then
+ if version == "2" or version == "3" then
--[[
For version-2-format timezone files, the above header and data is followed by a second header and data,
identical in format except that eight bytes are used for each transition time or leap-second time.
for use in handling instants after the last transition time stored in the file
(with nothing between the newlines if there is no POSIX representation for such instants).
]]
+
+ --[[
+ For version-3-format time zone files, the POSIX-TZ-style string may
+ use two minor extensions to the POSIX TZ format, as described in newtzset (3).
+ First, the hours part of its transition times may be signed and range from
+ -167 through 167 instead of the POSIX-required unsigned values
+ from 0 through 24. Second, DST is in effect all year if it starts
+ January 1 at 00:00 and ends December 31 at 24:00 plus the difference
+ between daylight saving and standard time.
+ ]]
+
assert ( assert ( fd:read ( 1 ) ) == "\n" , "Expected newline at end of version 2 header" )
TZ = assert ( fd:read ( "*l" ) )