tz.lua 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. -- tz -- A simple timezone module for interpreting zone files
  2. local M = {}
  3. local tstart = 0
  4. local tend = 0
  5. local toffset = 0
  6. local thezone = "eastern"
  7. function M.setzone(zone)
  8. thezone = zone
  9. return M.exists(thezone)
  10. end
  11. function M.exists(zone)
  12. return file.exists(zone .. ".zone")
  13. end
  14. function M.getzones()
  15. local result = {}
  16. for fn, _ in pairs(file.list()) do
  17. local _, _, prefix = string.find(fn, "(.*).zone")
  18. if prefix then
  19. table.insert(result, prefix)
  20. end
  21. end
  22. return result
  23. end
  24. local function load(t)
  25. local z = file.open(thezone .. ".zone", "r")
  26. local hdr = z:read(20)
  27. local magic = struct.unpack("c4 B", hdr)
  28. if magic == "TZif" then
  29. local lens = z:read(24)
  30. local ttisgmt_count, ttisdstcnt, leapcnt, timecnt, typecnt, charcnt -- luacheck: no unused
  31. = struct.unpack("> LLLLLL", lens)
  32. local times = z:read(4 * timecnt)
  33. local typeindex = z:read(timecnt)
  34. local ttinfos = z:read(6 * typecnt)
  35. z:close()
  36. local offset = 1
  37. local tt
  38. for i = 1, timecnt do
  39. tt = struct.unpack(">l", times, (i - 1) * 4 + 1)
  40. if t < tt then
  41. offset = (i - 2)
  42. tend = tt
  43. break
  44. end
  45. tstart = tt
  46. end
  47. local tindex = struct.unpack("B", typeindex, offset + 1)
  48. toffset = struct.unpack(">l", ttinfos, tindex * 6 + 1)
  49. else
  50. tend = 0x7fffffff
  51. tstart = 0
  52. end
  53. end
  54. function M.getoffset(t)
  55. if t < tstart or t >= tend then
  56. -- Ignore errors
  57. local ok, msg = pcall(function ()
  58. load(t)
  59. end)
  60. if not ok then
  61. print (msg)
  62. end
  63. end
  64. return toffset, tstart, tend
  65. end
  66. return M