tz.lua 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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. 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 = struct.unpack("> LLLLLL", lens)
  31. local times = z:read(4 * timecnt)
  32. local typeindex = z:read(timecnt)
  33. local ttinfos = z:read(6 * typecnt)
  34. z:close()
  35. local offset = 1
  36. local tt
  37. for i = 1, timecnt do
  38. tt = struct.unpack(">l", times, (i - 1) * 4 + 1)
  39. if t < tt then
  40. offset = (i - 2)
  41. tend = tt
  42. break
  43. end
  44. tstart = tt
  45. end
  46. local tindex = struct.unpack("B", typeindex, offset + 1)
  47. toffset = struct.unpack(">l", ttinfos, tindex * 6 + 1)
  48. else
  49. tend = 0x7fffffff
  50. tstart = 0
  51. end
  52. end
  53. function M.getoffset(t)
  54. if t < tstart or t >= tend then
  55. -- Ignore errors
  56. local ok, msg = pcall(function ()
  57. load(t)
  58. end)
  59. if not ok then
  60. print (msg)
  61. end
  62. end
  63. return toffset, tstart, tend
  64. end
  65. return M