How do you convert UTC time to EST in ruby (not using Rails)?
In plain Ruby you may use Time.zone_offset method:
require 'time'
t = Time.now # 2014-07-30 18:30:00 UTC
t + Time.zone_offset('EST') # 2014-07-30 13:30:00 UTC
The fbonetti's answer leads to the proper UTC to Eastern time conversion while accepted David Unric's answer would give wrong time for 8 months in 2017 (while DST is in effect).
Let's look at the following example:
First we'll need to figure out when DST starts/ends in 2017:
As we can see on March 12th, 2017 deep in the night (2:00am) they change time by adding +1 hour, so they "jump" from 1:59:59am up to 3:00:00am instantaneously! Which means there can not be 2:30am on March 12th, 2017.
Let's choose two UTC timestamps - one before and one after that switch, then we will try to convert those two timestamps from UTC back to Eastern.
First timestamp will be safely far enough from the switch moment:
require 'time'
t1 = Time.parse("2017-03-11 15:00:00 +0000")
=> 2017-03-11 15:00:00 +0000
t1_epoch_s = t1.to_i
=> 1489244400
Second timestamp is just +24 hours from the first one:
t2 = Time.parse("2017-03-12 15:00:00 +0000")
=> 2017-03-12 15:00:00 +0000
t2_epoch_s = t2.to_i
=> 1489330800
Now let us convert t1_epoch_s and t2_epoch_s to Eastern:
method-1: by adding Time.zone_offset('EST')
wrong, gives bad result: 10am for both days :(
and offset portion is shown as "+0000" which is also misleading and would refer to completely wrong point in time for people reading our output : ((
Time.at(t1_epoch_s) + Time.zone_offset('EST')
=> 2017-03-11 10:00:00 +0000
Time.at(t2_epoch_s) + Time.zone_offset('EST')
=> 2017-03-12 10:00:00 +0000
method-2: by changing timezone
Good!! Correctly yields 10am and 11am on next day!-)
ENV['TZ'] = 'America/New_York'
Time.at(t1_epoch_s)
=> 2017-03-11 10:00:00 -0500
Time.at(t2_epoch_s)
=> 2017-03-12 11:00:00 -0400
# resetting timezone back
ENV['TZ'] = nil
Basically manually adding Time.zone_offset('EST') is like adding constant and it will give right result for about 4 months (of 12 total) during the year, but then other time you'd have to manually add Time.zone_offset('EDT'), which is another constant. It pretty much same as "a broken clock is right twice a day": )) nasty!
And just for laughter let's see the "slow mo" how proper method handles the actual +1 hour magic jump in time:
ENV['TZ'] = "America/New_York"
Time.at(1489301999 + 0)
=> 2017-03-12 01:59:59 -0500
Time.at(1489301999 + 1)
=> 2017-03-12 03:00:00 -0400
ENV['TZ'] = nil
magic-magic!
In plain ruby, the timezone is determined by the 'TZ' environment variable. You could do something like this:
ENV['TZ'] = 'America/New_York' # set the TZ to Eastern Daylight Time
time = Time.now
time.zone
# => "EDT"
# do stuff
ENV['TZ'] = nil # reset the TZ back to UTC