Setting default timezone ENV['TZ']='UTC' not working on wind

Hi,

I’ve been trying to do timezone conversion, and have some trouble
getting it to work on my Windows machine. Searching the web, I found

http://wiki.rubyonrails.com/rails/pages/HowtoSetDefaultTimeZone

…which explains how to set the default timezone. I’m using an
environment.rb that include the lines:

ActiveRecord::Base.default_timezone = :utc
ENV[‘TZ’] = ‘US/Eastern’

This works fine on the Unix server running the application (Site5),
where Time.now outputs a UTC time, but on the windows machine the
ENV[‘TZ’]=‘UTC’ line is either ignored or doesn’t work, because I get
a Time.now such as ‘Wed Jun 07 23:10:39 Romance Daylight Time 2006’ no
matter what.

The Windows box is running Ruby 1.8.2 (2004-12-25) and the unix box is
running ruby 1.8.4 (2005-12-24). The application is running on Rails
1.1.2 on both boxes.

/Erik

Erik L. Underbjerg wrote:

This works fine on the Unix server running the application (Site5),
where Time.now outputs a UTC time, but on the windows machine the
ENV[‘TZ’]=‘UTC’ line is either ignored or doesn’t work, because I get
a Time.now such as ‘Wed Jun 07 23:10:39 Romance Daylight Time 2006’ no
matter what.

This article on MSDN describes the recognized values for TZ on Windows
(_tzset in the Visual C++ Run-Time Library reference):

I find that if the TZ environment variable is set before Ruby is loaded,
it is recognized and used. Setting it with ENV whilst Ruby is running
doesn’t seem to do anything though:

C:>irb
irb(main):001:0> ENV[‘TZ’]
=> nil
irb(main):002:0> Time.now.to_s
=> “Thu Jun 08 20:19:39 GMT Daylight Time 2006”
irb(main):003:0> Time.now.utc.to_s
=> “Thu Jun 08 19:19:43 UTC 2006”
irb(main):004:0> ENV[‘TZ’]=‘EST5EDT’
=> “EST5EDT”
irb(main):005:0> Time.now.to_s
=> “Thu Jun 08 20:20:02 GMT Daylight Time 2006”
irb(main):006:0> Time.now.utc.to_s
=> “Thu Jun 08 19:20:05 UTC 2006”
irb(main):007:0>
C:>set TZ=EST5EDT
C:>irb
irb(main):001:0> ENV[‘TZ’]
=> “EST5EDT”
irb(main):002:0> Time.now.to_s
=> “Thu Jun 08 20:20:32 EDT 2006”
irb(main):003:0> Time.now.utc.to_s
=> “Fri Jun 09 00:20:36 UTC 2006”

Note also that changing TZ doesn’t actually affect the reported local
time on Windows. Because the clock is set to local time, all that
changes is the offset that will be used when calculating the UTC time
(as shown above).

If you want to set the default timezone on Windows, I think you’ll have
to either set TZ and change the time, or change the system timezone.

If you are looking to perform timezone conversions from UTC to various
timezones, you might like to take a look at my TZInfo library
(http://tzinfo.rubyforge.org). With this, you’ll be able to do things
like:

TZInfo::Timezone.get(‘US/Eastern’).utc_to_local(Time.now.utc)
=> Thu Jun 08 15:26:54 UTC 2006


Philip R.
http://tzinfo.rubyforge.org/ – DST-aware timezone library for Ruby

Hi Philip,

Thank you very much for your reply. How lucky to get a reply from the
Timezone expert :slight_smile:

What I really wanted was consistent behaviour of Time.now across
timezones and platforms: Developers and users are in one timezone, but
the server is in another, and I want consistent results for things
such as unit tests.

I was trying to achieve this by setting the default timezone, but as
you have demonstrated, that doesn’t work on Windows.

I wasn’t aware of the Time.now.utc call, and that actually solves my
immidiate problem - I’ll just replace calls to Time.now with calls to
Time.now.utc. Thanks for the pointer.

The next step is to use your TZInfo library for converting from server
(utc) to user time. One question though: I have seen comments that the
TZInfo library is significantly slower than the built-in Rails
TimeZone class. Do you know how significant the performance-hit is? It
doesn’t appear to be major in the contexts I’ve tested, but maybe you
have some insight on this?

Kind regards,

Erik L. Underbjerg

Erik L. Underbjerg wrote:

The next step is to use your TZInfo library for converting from server
(utc) to user time. One question though: I have seen comments that the
TZInfo library is significantly slower than the built-in Rails
TimeZone class. Do you know how significant the performance-hit is? It
doesn’t appear to be major in the contexts I’ve tested, but maybe you
have some insight on this?

The built-in Rails TimeZone class is faster than the current version
(0.2.2) of TZInfo. I’ve just run some benchmarks:

Benchmark.bm do |b|
b.report(‘TimeZone:’) do
100000.times do
TimeZone.new(‘Eastern Time (US & Canada)’).adjust(Time.now.utc)
end
end
b.report(‘TZInfo:’) do
100000.times do
TZInfo::Timezone.get(‘US/Eastern’).utc_to_local(Time.now.utc)
end
end
end
user system total real
TimeZone: 3.703000 0.016000 3.719000 ( 3.766000)
TZInfo: 8.344000 0.015000 8.359000 ( 8.547000)

Previous versions used to be significantly slower. Some major
performance improvements were made in 0.2.0 and 0.2.1.

The main reason TZInfo is slower than the TimeZone class is that
TimeZone is just adding a constant offset for each zone. TZInfo is
applying daylight savings rules which differ from year to year - note
that TimeZone currently gets the wrong answer for Eastern Daylight Time:

t = Time.now.utc
=> Sat Jun 10 00:12:43 UTC 2006
TimeZone.new(‘Eastern Time (US & Canada)’).adjust(t)
=> Fri Jun 09 19:12:43 UTC 2006
TZInfo::Timezone.get(‘US/Eastern’).utc_to_local(t)
=> Fri Jun 09 20:12:43 UTC 2006


Philip R.
http://tzinfo.rubyforge.org/ – DST-aware timezone library for Ruby

On 6/10/06, Philip R. [email protected] wrote:

that TimeZone currently gets the wrong answer for Eastern Daylight Time:

Thanks again for your thorough answer - the increased times you have
demonstrated are in no way significant compared to the other things
our application is doing, and the correct handling of daylight saving
is just what we need.

We’ll start using your library immidiately :slight_smile:

/Erik

Side note: I must say, I am surprised with the quality and the speed
at which my first posting on this list has been answered. My Ruby on
Rails experience has been continually improving since I started out 2
months ago. Thanks!