Sample code for timezone handling (#1853)
This commit is contained in:
parent
f562ef8fc1
commit
c0848ec66f
|
@ -0,0 +1,56 @@
|
||||||
|
# tz module
|
||||||
|
|
||||||
|
This is a simple module that parses timezone files as found on unix systems. It is oriented around converting the current time. It can convert other times, but it is
|
||||||
|
rather less efficient as it maintains only a single cached entry in memory.
|
||||||
|
|
||||||
|
On my linux system, these files can be found in `/usr/share/zoneinfo`.
|
||||||
|
|
||||||
|
|
||||||
|
## tz.setzone()
|
||||||
|
|
||||||
|
This sets the timezone to be used in subsequent conversions
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
`tz.setzone(timezone)`
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
- `timezone` this is the timezone string. It must correspond to a file in the file system which is named timezone.zone.
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
true if the zone exists in the file system.
|
||||||
|
|
||||||
|
## tz.getoffset()
|
||||||
|
|
||||||
|
This gets the offset (in seconds) of the time passed as the argument.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
`tz.getoffset(time)`
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
- `time` the number of seconds since the epoch. This is the same value as used by the `sntp` module.
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
|
||||||
|
- The number of seconds of offset. West of Greenwich is negative.
|
||||||
|
- The start time (in epoch seconds) of this offset.
|
||||||
|
- The end time (in epoch seconds) of this offset.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
```
|
||||||
|
tz = require('tz')
|
||||||
|
tz.setzone('eastern')
|
||||||
|
sntp.sync(nil, function(now)
|
||||||
|
local tm = rtctime.epoch2cal(now + tz.getoffset(now))
|
||||||
|
print(string.format("%04d/%02d/%02d %02d:%02d:%02d", tm["year"], tm["mon"], tm["day"], tm["hour"], tm["min"], tm["sec"]))
|
||||||
|
end)
|
||||||
|
```
|
||||||
|
|
||||||
|
## tz.getzones()
|
||||||
|
|
||||||
|
This returns a list of the available timezones in the file system.
|
||||||
|
|
||||||
|
#### Syntax
|
||||||
|
`tz.getzones()`
|
||||||
|
|
||||||
|
#### Returns
|
||||||
|
A list of timezones.
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,81 @@
|
||||||
|
-- tz -- A simple timezone module for interpreting zone files
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
local tstart = 0
|
||||||
|
local tend = 0
|
||||||
|
local toffset = 0
|
||||||
|
local thezone = "eastern"
|
||||||
|
|
||||||
|
function M.setzone(zone)
|
||||||
|
thezone = zone
|
||||||
|
return M.exists(thezone)
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.exists(zone)
|
||||||
|
return file.exists(zone .. ".zone")
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.getzones()
|
||||||
|
local result = {}
|
||||||
|
for fn, _ in pairs(file.list()) do
|
||||||
|
local _, _, prefix = string.find(fn, "(.*).zone")
|
||||||
|
if prefix then
|
||||||
|
table.insert(result, prefix)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function load(t)
|
||||||
|
local z = file.open(thezone .. ".zone", "r")
|
||||||
|
|
||||||
|
local hdr = z:read(20)
|
||||||
|
local magic = struct.unpack("c4 B", hdr)
|
||||||
|
|
||||||
|
if magic == "TZif" then
|
||||||
|
local lens = z:read(24)
|
||||||
|
local ttisgmt_count, ttisdstcnt, leapcnt, timecnt, typecnt, charcnt = struct.unpack("> LLLLLL", lens)
|
||||||
|
|
||||||
|
local times = z:read(4 * timecnt)
|
||||||
|
local typeindex = z:read(timecnt)
|
||||||
|
local ttinfos = z:read(6 * typecnt)
|
||||||
|
|
||||||
|
z:close()
|
||||||
|
|
||||||
|
local offset = 1
|
||||||
|
local tt
|
||||||
|
for i = 1, timecnt do
|
||||||
|
tt = struct.unpack(">l", times, (i - 1) * 4 + 1)
|
||||||
|
if t < tt then
|
||||||
|
offset = (i - 2)
|
||||||
|
tend = tt
|
||||||
|
break
|
||||||
|
end
|
||||||
|
tstart = tt
|
||||||
|
end
|
||||||
|
|
||||||
|
local tindex = struct.unpack("B", typeindex, offset + 1)
|
||||||
|
toffset = struct.unpack(">l", ttinfos, tindex * 6 + 1)
|
||||||
|
else
|
||||||
|
tend = 0x7fffffff
|
||||||
|
tstart = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function M.getoffset(t)
|
||||||
|
if t < tstart or t >= tend then
|
||||||
|
-- Ignore errors
|
||||||
|
local ok, msg = pcall(function ()
|
||||||
|
load(t)
|
||||||
|
end)
|
||||||
|
if not ok then
|
||||||
|
print (msg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return toffset, tstart, tend
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
Loading…
Reference in New Issue