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.