Zoneinfo is a TimeZoneDatabase library for Elixir that reads OS-supplied TZif files from /usr/share/zoneinfo
.
If you’re happy with Tzdata, Tz or TimeZoneInfo, then there’s no reason to change.
Zoneinfo addresses a need we had with Nerves to minimize code and data sizes on metered network connections. We found that the TZif files in /usr/share/zoneinfo
compress really well and were easily tunable using the zic(8) compiler to remove date ranges we’d never use. An added size benefit was only having one copy of the time zone database since /usr/share/zoneinfo
was already used by non-BEAM programs.
Zoneinfo works on Linux and OSX out of the box. The library has no dependencies. If you keep your OS patched, one hopes that your OS will also update these zoneinfo files from their IANA sources. Or, you could add something like apt install --only-upgrade tzdata -y
to a crontab.
Will it return the right answer?
We tested Zoneinfo by brute force comparing its output to Tz’s within the supported date ranges of the TZif files. There are caveats:
- TZif files contain time change records that go from about 100 years ago to 2038 or 2050. It’s possible to calculate time changes outside of this range, but Zoneinfo currently doesn’t attempt this.
- Calendar.TimeZoneDatabase splits the overall time offset to the amount that gets you to standard time and then the DST offset. TZif files only have the overall time offset so Zoneinfo uses a heuristic to split it up. The heuristic currently disagrees with the split for Monaco and Paris in 1945 and Morocco. Since most conversions only require the overall time offset, this is a non-issue, but it is a discrepancy nonetheless.
- We assume that Tz is correct. Having reviewed many discrepancies while debugging Zoneinfo, I believe that Tz very accurately reflects the IANA Time Zone database rules and the many unusual time zone decisions that people have made over the past century.
If you are using Nerves and need local time for a clock display or for scheduling events, check out NervesTimeZones. It provides a small data base, makes NaiveDateTime.local_now
return the expected time, and helps you pass the appropriate environment variables to non-BEAM apps so they use the right time zone.