If I want to present a list of time zones to a user, how might I get a list of supported ones? There’s Time::Location.load, which lets us get timezone info when we already know the name of a timezone, but how do I find the list of strings to give that method?
I think what I’m looking for is something like a Time::Location.each. Before I go implementing my own, is there another way to do this?
Normally there is no programmatic access to the complete list of valid IANA time zone names, and you have to glob the directories in Crystal::System::Time::ZONE_SOURCES manually; a valid tzdb file starts with a TZif magic number, and the time zone name is the file’s path relative to that source root. The list depends on the version of tzdata that is available on the system, and also how it was built (not all systems define compatibility aliases, for example). Android uses a different format altogether.
The authoritative source is GitHub - eggert/tz: Time zone database and code, you might want to parse the definition files themselves if you really need to.
On Windows we embed all names in Crystal::System::Time.iana_to_windows, derived from the Unicode CLDR, since there is no tzdata and we merely translate those names to their equivalent Windows Registry keys.
Other libraries like ICU provide their own enumeration methods, but they usually embed their own databases as well and differ from the Crystal standard library’s database.
3 Likes