如何在Ruby中将UTC时间转换为EST(不使用Rails)?

时间:2014-07-30 17:54:52

标签: ruby time

我正在捕捉当前时间:

Time.now

我的服务器在UTC上运行。如何在不使用任何Rails库的情况下将时间转换为EST?我猜是某种偏移,但不确定它是如何运作的。

4 个答案:

答案 0 :(得分:4)

在纯Ruby中,您可以使用Time.zone_offset方法:

require 'time'

t = Time.now                # 2014-07-30 18:30:00 UTC
t + Time.zone_offset('EST') # 2014-07-30 13:30:00 UTC

答案 1 :(得分:3)

在普通红宝石中,时区由“TZ”和“TZ”决定。环境变量。你可以这样做:

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

答案 2 :(得分:3)

fbonetti的答案导致适当的UTC到东部时间的转换,而接受David Unric的回答将在2017年给出8个月的错误时间(当DST生效时)。

让我们看看下面的例子:

首先,我们需要弄清楚DST在2017年开始/结束的时间:

enter image description here

正如我们在2017年3月12日深夜(凌晨2点)看到的,他们通过增加+1小时来改变时间,所以他们"跳跃"从上午1:59:59到凌晨3:00:00!这意味着2017年3月12日凌晨2:30不可能。

让我们选择两个UTC时间戳 - 一个在开关之前和之后一个,然后我们将尝试将这两个时间戳从UTC转换回东部。

第一个时间戳距离切换时刻足够远:

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

第二个时间戳距离第一个时间戳+24小时:

t2 = Time.parse("2017-03-12 15:00:00 +0000")
=> 2017-03-12 15:00:00 +0000
t2_epoch_s = t2.to_i
=> 1489330800

现在让我们将t1_epoch_s和t2_epoch_s转换为Eastern:

方法-1:添加Time.zone_offset(' EST')
错了,结果不好:两天上午10点:( 和偏移部分显示为" + 0000"这也是误导性的,并且指的是人们阅读我们的输出时完全错误的时间点:((

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

方法-2:通过更改时区
好!!正确地在第二天产生上午10点和上午11点! - )

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

基本上手动添加Time.zone_offset(' E S T')就像添加常量一样,它会在一年中给出正确的结果约4个月(共12个) ,但是其他时候你必须手动添加Time.zone_offset(' E D T'),这是另一个常数。它和#34; a broken clock is right twice a day" :))令人讨厌!

只是为了笑声,让我们看看"慢动作"正确的方法如何处理实际的+1小时魔术跳跃:

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

魔魔!

答案 3 :(得分:0)

如果您不介意使用宝石,

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

信用:https://stackoverflow.com/a/42702906/2441263