28

I have pretty common issue but for some reason i have tried all the suggestions on the web and none seem to work.

I have set the Timezone in config to 'EST'

config.time_zone = 'Eastern Time (US & Canada)'

But when the time is shown on the the screen, it continues to show the UTC time that is stored in the DB. I tried the debugger and here is the output

(rdb:1) Time.zone 
#<ActiveSupport::TimeZone:0x1061f4760 @utc_offset=nil, @current_period=nil, @name="Eastern Time (US & Canada)", @tzinfo=#<TZInfo::TimezoneProxy: America/New_York>>
(rdb:1) Order.first.placed_at
Fri Jan 01 15:00:00 UTC 2010

Update: Here is another user who has the same question Rails timezone is wrong when shown

Community
  • 1
  • 1
Addy
  • 1,817
  • 2
  • 18
  • 23

4 Answers4

37

Try in_time_zone. For example

>> Time.now
=> Sun Dec 05 21:34:45 -0500 2010
>> Time.zone
=> #<ActiveSupport::TimeZone:0x1033d97b8 @name="Pacific Time (US & Canada)", @tzinfo=#<TZInfo::DataTimezone: America/Los_Angeles>, @utc_offset=-28800, @current_period=nil>
>> Time.now.in_time_zone
=> Sun, 05 Dec 2010 18:34:54 PST -08:00

In your case, you want Order.first.placed_at.in_time_zone.

Paul Schreiber
  • 12,531
  • 4
  • 41
  • 63
  • 4
    But I thought setting the timezone in the config would automatically instruct activerecord to retrieve in local timezone.. http://ryandaigle.com/articles/2008/1/25/what-s-new-in-edge-rails-easier-timezones – Addy Dec 06 '10 at 02:39
  • In my experience, I had to explicitly tell the view to use the local timezone (instead of UTC). Perhaps a better way exists. – Paul Schreiber Dec 06 '10 at 02:42
  • This was driving me crazy. Thanks a ton! :-) – Tim Sullivan Feb 11 '11 at 20:29
  • 3
    or even `Time.zone.now` this seems to return the same for me (rails 3.1) and reads slightly better I think – nocache Sep 13 '11 at 08:36
  • 7
    negative. The correct way to call it would be Time.current. I went through the same problem you had, use #current instead of #now to to get the time for the given time zone. – Mike Sep 26 '11 at 17:42
11

If you want to set a different time zone for different users of your app, make sure you use an around_filter as opposed to a before filter to change Time.zone. Something to do with how Time.zone leaks over to other threads and thus other users may inheret a time zone that they shouldn't. From this blog post: http://ilikestuffblog.com/2011/02/03/how-to-set-a-time-zone-for-each-request-in-rails/

in application_controller.rb:

around_filter :set_time_zone

private

def set_time_zone
  old_time_zone = Time.zone
  Time.zone = current_user.time_zone if logged_in?
  yield
ensure
  Time.zone = old_time_zone
end

I also found it helpful to use the time_zone_select form helper method when allowing users to change their time zone. If you called your field :time_zone, you would use it like:

f.time_zone_select(:time_zone)

And lastly, this looks pretty awesome. Auto detect and set time zone via javascript. Here's the rails gem to add to the asset pipeline: https://github.com/scottwater/detect_timezone_rails and accompanying blog post: http://www.scottw.com/automated-timezone-detection

Danny
  • 3,982
  • 1
  • 34
  • 42
2

Check that your ActiveRecord::Base.time_zone_aware_attributes is true.

Beryllium
  • 12,808
  • 10
  • 56
  • 86
Duke
  • 7,070
  • 3
  • 38
  • 28
0

I think what you're describing is this bug - https://github.com/rails/rails/issues/6816

joshnabbott
  • 137
  • 1
  • 6