How to Alter the Timezone of a Datetime in Ruby

How do I alter the timezone of a DateTime in Ruby?

Using Rails 3, you're looking for DateTime.change()

dt = DateTime.now
=> Mon, 20 Dec 2010 18:59:43 +0100
dt = dt.change(:offset => "+0000")
=> Mon, 20 Dec 2010 18:59:43 +0000

Changing the time zone for DateTime in Ruby

utc method converts Time to UTC.

created = date.utc.strftime("%FT%T%:z")

This method is available in 1.8.7, 1.9.3, 2.0.0 and 2.1.0.

If you don't want to affect the time when changing time zone you can add the difference before converting:

time = Time.now         # => 2014-01-08 21:45:41 +0100
time += time.gmt_offset # => 2014-01-08 22:45:41 +0100
time.utc # => 2014-01-08 21:45:41 UTC

Rails: convert UTC DateTime to another time zone

time.in_time_zone(time_zone)

Example:

zone = ActiveSupport::TimeZone.new("Central Time (US & Canada)")
Time.now.in_time_zone(zone)

or just

Time.now.in_time_zone("Central Time (US & Canada)")

You can find the names of the ActiveSupport time zones by doing:

ActiveSupport::TimeZone.all.map(&:name)
# or for just US
ActiveSupport::TimeZone.us_zones.map(&:name)

How to create a Ruby DateTime from existing Time.zone for Rails?

You can use Time.zone.local if you set Time.zone previously:

user_time = Time.zone.local(params[:year].to_i, params[:month].to_i, params[:day].to_i, params[:hour].to_i, params[:minute].to_i, 0)

Have a look at the ActiveSupport::TimeWithZone documentation.

Ruby / Rails - Change the timezone of a Time, without changing the value

Sounds like you want something along the lines of

ActiveSupport::TimeZone.new('America/New_York').local_to_utc(t)

This says convert this local time (using the zone) to utc. If you have Time.zone set then you can of course to

Time.zone.local_to_utc(t)

This won't use the timezone attached to t - it assumes that it's local to the time zone you are converting from.

One edge case to guard against here is DST transitions: the local time you specify may not exist or may be ambiguous.

Change Time zone in pure ruby (not rails)

You can use the Time extensions from Active Support outside of Rails:

require 'active_support/core_ext/time'

t = Time.now
#=> 2014-08-15 15:38:56 +0200

t.in_time_zone('Pacific Time (US & Canada)')
#=> Fri, 15 Aug 2014 06:38:56 PDT -07:00

Now you can do

class Time
def to_pst
in_time_zone('Pacific Time (US & Canada)')
end
end

t = Time.now
#=> 2014-08-15 15:42:39 +0200

t.to_i
#=> 1408110159

t.to_pst
#=> Fri, 15 Aug 2014 06:42:39 PDT -07:00

t.to_pst.to_i
#=> 1408110159

# timestamp does not change!

Additionally you might also want the time extensions on Numeric and Date:

require 'active_support/core_ext/date'
require 'active_support/core_ext/numeric/time'

2.days.from_now
#=> 2014-08-17 15:42:39 +0200


Related Topics



Leave a reply



Submit