ashweta
ashweta

Reputation: 1487

ruby get Time in given timezone

In ruby, how can I get current time in a given timezone? I know the offset from UTC, and want to get the current time in the timezone with that offset.

Upvotes: 40

Views: 45718

Answers (8)

Jim Meyer
Jim Meyer

Reputation: 1376

A simpler, more lightweight solution:

Time.now.getlocal('-08:00')
Time.now.getlocal(-28800)

Well documented here.

Update 2021.12.23: If you've got a tzdata timezone name like 'US/Pacific' instead of an offset and you're willing to pull in the tzinfo gem, you could also do this (with thanks to both @chadoh and @kevin from below):

require 'tzinfo'

TZInfo::Timezone.get('US/Pacific').now

Not really the problem as posed, but maybe helpful to folks in the future.

If you want to do this for moments other than #now, you should study up on the Ruby Time class, particularly Time#gm and Time#local, and the Ruby TZInfo classes, particularly TZInfo::Timezone.get and TZInfo::Timezone#period_for_local

Upvotes: 55

jpw
jpw

Reputation: 19247

now = Time.now
now.in_time_zone('Eastern Time (US & Canada)') 
or 
now.in_time_zone('Asia/Manila') 

Upvotes: 6

chadoh
chadoh

Reputation: 4432

gem install tzinfo

Then

require 'tzinfo'

tz = TZInfo::Timezone.get('US/Pacific')
Time.now.getlocal(tz.current_period.offset.utc_total_offset)

Upvotes: 8

Kem Mason
Kem Mason

Reputation: 1670

I tried a gem install active_support, it installed activesupport-3.00, which gave me an error:

"You don't have tzinfo installed in your application. Please add it to your Gemfile and run bundle install"

tzinfo is a gem that ActiveSupport uses -- it was a little cleaner for my purposes, doesn't have any external dependencies -- the downside is that it appears to leave everything looking like it is UTC, so if you want your timezones to look correct, gem install activerecord will install everything you need. I'm including this answer mostly for reference for others that run into the same issue / googlability.

(use gem install tzinfo) to install the gem

require 'tzinfo'
zone = TZInfo::Timezone.get('US/Eastern')
puts zone.now

there are a number of different ways to get the timezones, but you can see a list using

TZInfo::Timezone.all

Upvotes: 2

glenn jackman
glenn jackman

Reputation: 246817

I'd use the ActiveSupport gem:

require 'active_support/time'
my_offset = 3600 * -8  # US Pacific

# find the zone with that offset
zone_name = ActiveSupport::TimeZone::MAPPING.keys.find do |name|
  ActiveSupport::TimeZone[name].utc_offset == my_offset
end
zone = ActiveSupport::TimeZone[zone_name]

time_locally = Time.now
time_in_zone = zone.at(time_locally)

p time_locally.rfc822   # => "Fri, 28 May 2010 09:51:10 -0400"
p time_in_zone.rfc822   # => "Fri, 28 May 2010 06:51:10 -0700"

Upvotes: 17

0x4a6f4672
0x4a6f4672

Reputation: 28245

For an UTC offset of x hours, the current time can be calculated with the help of ActiveSupport in Rails, as the others said:

utc_offset = -7
zone = ActiveSupport::TimeZone[utc_offset].name
Time.zone = zone 
Time.zone.now

or instead of the two lines

DateTime.now.in_time_zone(zone)

Or, if you do not have Rails, one can also use new_offset to convert a locate DateTime to another time zone

utc_offset = -7
local = DateTime.now
local.new_offset(Rational(utc_offset,24))

Upvotes: 14

NudeCanalTroll
NudeCanalTroll

Reputation: 2286

An easier way to do it is to simply pass the offset (in integer form) to the ActiveSupport::TimeZone hash:

ActiveSupport::TimeZone[-8]
=> #<ActiveSupport::TimeZone:0x7f6a955acf10 @name="Pacific Time (US & Canada)", @tzinfo=#<TZInfo::TimezoneProxy: America/Los_Angeles>, @utc_offset=nil, @current_period=#<TZInfo::TimezonePeriod: #<TZInfo::TimezoneTransitionInfo: #<TZInfo::TimeOrDateTime: 1320570000>,#<TZInfo::TimezoneOffsetInfo: -28800,0,PST>>,#<TZInfo::TimezoneTransitionInfo: #<TZInfo::TimeOrDateTime: 1331460000>,#<TZInfo::TimezoneOffsetInfo: -28800,3600,PDT>>>>

Upvotes: 3

stephenr
stephenr

Reputation: 1173

Just add or subtract the appropriate number of seconds:

>> utc = Time.utc(2009,5,28,10,1)           # given a utc time
=> Thu May 28 10:01:00 UTC 2009
>> bst_offset_in_mins = 60                  # and an offset to another timezone
=> 60
>> bst = t + (bst_offset_in_mins * 60)      # just add the offset in seconds
=> Thu May 28 11:01:00 UTC 2009             # to get the time in the new timezone

Upvotes: -4

Related Questions