开发者

How to get Rails to interpret a time as being in a specific time zone?

In Ruby 1.8.7, how to set the time zone of a time?

In the following examples, my system time zone is PST (-8:00 hours from UTC)

Given a time (21 Feb 2011, 20:45), presume that the time is in EST:

#this interprets the time as system time zone, i.e. PST
Time.local(2011,02,21,20,45) 
  #=> Mon Feb 21 20:45:00 -0800 2011

#this **converts** the time into EST, which is wrong!
Time.local(2011,02,21,20,45).in_time_zone "Eastern Time (US & Canada)" 
  #=> Mon, 21 Feb 2011 23:45:00 EST -05:00

But, the output I want is: Mon Feb 21 20:45:00 -0500 2011 (Note the -0500 (EST) as opposed to -0800 (PST) and the hour is same, i.e. 20, not 23)

UPDATE (see the better version of this below)

I managed to get this to work, but I don't like it:

DateTime.new(2011,02,21,20,45).change :offset => -(300.0 / 1440.0)
  # => Mon, 21 Feb 2011 20:45:00 +0500

Where
  300 = 5 hrs x 60 minutes
  1440 = number of minutes in a day

or the "right" way:

DateTime.civil(2011,02,21,20,45,0,Rational(-5, 24))

Question: Now, is there a way to determine the accurate(i.e. catering for daylight saving time etc) UTC offset from Time.zone so that I can pass it to开发者_开发技巧 the change method?

Reference: DateTime::change method

UPDATE (better version)

Thanks to @ctcherry for all the help!

Determine the accurate time zone info from Time.zone:

DateTime.civil(2011,02,21,20,45,0,Rational((Time.zone.tzinfo.current_period.utc_offset / 3600), 24))


In ruby 1.8.7 it doesn't appear to be very easy to do what are asking for according to the documentation:

http://www.ruby-doc.org/core-1.8.7/classes/Time.html

However in 1.9 it looks a lot easier by passing the timezone offset to the localtime() method on a Time object:

http://www.ruby-doc.org/core/classes/Time.html#M000346

UPDATE

The offset for Time.zone is easy since its an object on its own: (This is in a Rails console)

ruby-1.8.7-p248 :001 > Time.zone
 => #<ActiveSupport::TimeZone:0x103150190 @current_period=nil, @name="Central Time (US & Canada)", @tzinfo=#<TZInfo::TimezoneProxy: America/Chicago>, @utc_offset=nil> 
ruby-1.8.7-p248 :002 > Time.zone.utc_offset
 => -21600 
ruby-1.8.7-p248 :003 > Time.zone.formatted_offset
 => "-06:00" 


So I think this will (almost) accomplish what you want:

require 'time'
t = "21 Feb 2011, 20:45"
Time.parse(t)           # => Mon Feb 21 20:45:00 -0700 2011
t += " -05:00"          # this is the trick
Time.parse(t)           # => Mon Feb 21 18:45:00 -0700 2011

It still returns the time based on your system time zone, but the actual time is the correct time that you are seeking.

By the way, this is tested on 1.8.7-p334.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜