Problems with new Time.zone updates in edge. Please help.

Yo Core...on Rick's prompting last night I dropped tztime plugins and updated to edge.

One of my tests is failing regarding Time.zone now, and I believe it's a bug with the new code. The time that comes back from the result seems proper, but the zone is not set. Help?

# Editing time entries doesn't return proper time as saved.

Also, I believe this is a bug with the code. If zone is set, Time.now should return the proper time in the right zone.

Time.zone = "Eastern Time (US & Canada)"

=> "Eastern Time (US & Canada)"

Time.now

=> Tue Mar 11 23:21:15 PDT 2008

Also, I believe this is a bug with the code. If zone is set, Time.now should return the proper time in the right zone.

>> Time.zone = "Eastern Time (US & Canada)" => "Eastern Time (US & Canada)" >> Time.now => Tue Mar 11 23:21:15 PDT 2008

Messing with Time.now is pretty dangerous, we had discussed it earlier but there's a large number of non-rails-app cases where we could cause strange results. The most common example being the Timestamps used in log messages.

That's how the old TzTime plugin works, you set the zone, call TzTime.now. I'd expect this to act in the same manner.

Barring that, I notice that there's some methods in zones.rb that allow you to get time in another zone. Specifically in_current_time_zone. Is this the recommended method now?

Time.zone = "Eastern Time (US & Canada)"

=> "Eastern Time (US & Canada)"

Time.zone

=> #<TimeZone:0x23d1000 @utc_offset=-18000, @name="Eastern Time (US & Canada)">

Time.in_current_time_zone

NoMethodError: undefined method `in_current_time_zone' for Time:Class         from (irb):3

Time.now.in_current_time_zone

=> Wed, 12 Mar 2008 04:56:48 EDT -04:00

Also - any idea on my first message in the thread regarding the failing test?

That's how the old TzTime plugin works, you set the zone, call TzTime.now. I'd expect this to act in the same manner.

You just need to replace calls to TzTime.now with Time.zone.now.

Barring that, I notice that there's some methods in zones.rb that allow you to get time in another zone. Specifically in_current_time_zone. Is this the recommended method now?

You can call #in_current_time_zone on any time instance, and it will return the simultaneous time in Time.zone. So, Time.now.in_current_time_zone would return the same result as Time.zone.now.

Also - any idea on my first message in the thread regarding the failing test?

Looks like you haven't set config.time_zone in environment.rb, which sets

ActiveRecord::Base.time_zone_aware_attributes = true

...without that, you'll just get times back in ActiveRecord::Base.default_timezone.

Geoff thanks for the pointers.

Pardon my ignorance, but what exactly do I set config.time_zone to? What are the values it _can_ be set to?

The article... http://weblog.techno-weenie.net/2008/2/6/timezone-awareness-in-rails ...has no mention of that anywhere.

All I have set in environment.rb is: # Make Active Record use UTC-base instead of local time config.active_record.default_timezone = :utc

PS: I tried setting config.time_zone = 'UTC' and :utc, and my test still fails.

Just for clarification - here's the failing test, and it's message...

# Editing time entries doesn't return proper time as saved.   # (PS, My computer is in Pacific time...)   def test_bug_time_entry_save     zones = [       "Eastern Time (US & Canada)",       "Pacific Time (US & Canada)"     ]     zones.each do |z|       Time.zone = z       assert !Time.zone.nil?       time = Time.zone.now       te = TimeEntry.new(         :account_id => accounts(:paid).id,         :line_item_id => line_items(:not_on_estimate).id,         :person_id => people(:paying_admin).id,         :created_on => time       )       assert te.save       te.reload       assert_equal te.created_on, time, "Time not equal for zone: #{z}"     end   end

1) Failure: test_bug_time_entry_save(TimeEntryTest) [./test/unit/time_entry_test.rb:124:in `test_bug_time_entry_save' ./test/unit/time_entry_test.rb:112:in `test_bug_time_entry_save' /Work/cashboard/site/trunk/vendor/rails/activerecord/lib/../../ activesupport/lib/active_support/testing/setup_and_teardown.rb:59:in `run']: Time not equal for zone: Eastern Time (US & Canada). [no difference--suspect ==]

Ah, right, and the rdoc doesn't yet have anything about setting the config option either. You set time zone config in the Rails initializer block in environment.rb, like so:

Rails::Initializer.run do |config|   ...   config.time_zone = "Pacific Time (US & Canada)"   ... end

You can set it to the name of any time zone defined by the ActiveSupport TimeZone class -- see lines 267-314 of: http://dev.rubyonrails.org/browser/trunk/activesupport/lib/active_support/values/time_zone.rb . This zone is used as the default value for Time.zone.

You can remove config.active_record.default_timezone = :utc from your Rails initializer block, since config.time_zone takes care of that for you.

Is the problem here that you're trying to set a column named :created_on, which AR will overwrite with its own timestamp value?

If so, then the timestamp will be a few milliseconds later than Time.zone.now, and they won't be equal.

Ok, ignore the previous about the :created_on comment, you can overwrite that...

But I think the problem is, Time.zone.now will have a milliseconds value, which is trimmed by #to_s(:db). So, the attribute value and Time.zone.now won't be equal.

Geoff, thanks for the help - this line seems to work fine:

assert_equal te.created_on.to_s(:db), time.to_s(:db)

Seems accurate enough for my tests as well.