jmettraux/rufus-scheduler

Setting the Time Zone Dynamically

adeeb1 opened this issue · 10 comments

I ran into the "Cannot determine timezone from nil" error and wanted to post my solution. It involves setting the ENV['TZ'] variable, as you suggested, but I don't like to hardcode values like this, especially if your time zone changes from development to production environments. You can let Ruby get the time zone more explicitly.

ENV['TZ'] = Time.zone.name
scheduler = Rufus::Scheduler.new
scheduler.every '2s' do
  puts "#{Time.now} Hello #{ENV['TZ']}!"
end

Good morning,

$ ruby -v
ruby 2.2.5p319 (2016-04-26 revision 54774) [x86_64-darwin14]
$ ruby -e "Time.zone.name"
-e:1:in `<main>': undefined method `zone' for Time:Class (NoMethodError)

Thanks for the quick reply! It looks like Time.zone is specific to ActiveSupport: http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html. I think my approach would work for Rails, but without Rails you'd need to manually specify the time zone as you have described in your FAQ.

What kind of zone string does your Time.zone.name returns?

If it's something like "CST" it is very ambiguous and leads to problems like #228

Beware of not shooting yourself in the foot.

Good point. Mine returns "UTC" and seems to be working fine. ActiveSupport::TimeZone is a wrapper over TZInfo. What may be even safer is to use the tzinfo identifier instead:

ENV['TZ'] = Time.zone.tzinfo.identifier # "Etc/UTC"

Could you please try something in your system for me?

Please set your system zone to Shangai then tell me what Time.zone.tzinfo.identifier returns.

Thanks in advance.

It doesn't look like it uses your local time; mine returns "UTC." The docs say you have to set the time zone in Rails' application.rb; otherwise it will default to UTC. Shanghai isn't listed as a time zone:

> rake time:zones:all
...

* UTC +08:00 *
Beijing
Chongqing
Hong Kong
Irkutsk
Kuala Lumpur
Perth
Singapore
Taipei
Ulaanbaatar
...

I set the time zone to "Beijing," and it returned the Shanghai identifier, which makes sense since it says "Beijing Time" next to it on Wikipedia.

> rails c
> Time.zone = "Beijing"
=> "Beijing"
> Time.zone.tzinfo.identifier
=> "Asia/Shanghai"

OK, how about changing the operating system zone?

The same as above. I changed the time zone of my OS, and it still returned "UTC" because Rails defaults to UTC if you don't explicitly specify a time zone in your Rails app.

OK. Thank you very much!

(removed the [FAQ] prefix as it might confuse people)