Search code examples
crystal-lang

What's the proper way to get a local time when TZ=":/etc/localtime"?


My environment variable TZ is set to :/etc/localtime. File /etc/localtime is a symbolic link to file /usr/share/zoneinfo/America/Chicago. So far I am using this to get a local time object:

Time.local(
  Crystal::System::Time.load_localtime.not_nil!
) 
# 2019-07-16 20:46:50 -05:00

Because the following gives me a Time set to UTC:

Time.local   # 2019-07-17 01:46:50 UTC

Are the Crystal standard libs suppose to return a UTC location for TZ=":/etc/localtime" or am I suppose to manually set TZ to a timezone (eg "America/Chicago")?


Solution

  • Time::Location only supports values of TZ that are paths relative to the zoneinfo data base (for example: America/Chicago). It currently can't resolve absolute paths. This could be added as a feature request, though.

    Time.local gives you a time in UTC simply because Time::Location.load_local can't understand the value of ENV["TZ"] and defaults to UTC. If you simply unset TZ, it should work as expected.

    When TZ is not set, it defaults to the value referenced by /etc/localtime. So your custom effort should not be necessary at all. Especially Crystal::System::Time is not supposed to be called from user code directly.