更改纯红宝石的时区(不是铁轨)

时间:2014-08-14 21:58:07

标签: ruby time timezone sinatra

我正在建立一个混合了UTC / PST数据源的Sinatra网站,但将在PST中查看。所以我需要一种方法来轻松地将时间对象从UTC转换为PST。 如果没有Rails,我无权访问Time.zonein_time_zone等。

我只需要更改Time对象的时区,例如。 2014-08-14 21:44:17 +0000 => 2014-08-14 14:44:17 -0700.

首先我尝试了这个:

class Time
  def to_pst
    self.utc + Time.zone_offset('PDT')
  end
end

但是这会改变实际的时间戳而不是区域。我需要time.to_itime.strftime才能工作;所以我不能改变时间戳的绝对值。

> t = Time.now
=> 2014-08-14 21:46:20 +0000
> t.to_pst
=> 2014-08-14 14:46:20 UTC
> t.to_i
=> 1408052780
> t.to_pst.to_i
=> 1408027580

gem 'timezone'提出了类似的问题。

This解决方案有效但改变了全局变量,并且不是线程安全的。

操作系统时区需要保持UTC。

我只需要一种方法来改变单个Time对象的时区。这是一个简单的问题,它似乎应该有一个简单的解决方案!有没有人找到一个?提前谢谢!

5 个答案:

答案 0 :(得分:9)

纯粹的红宝石

Time.now.utc.localtime("+05:30")

其中+05:30(IST)是特定区域的偏移量

答案 1 :(得分:7)

您可以使用Rails之外的Active Support中的Time扩展名:

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

现在你可以做到

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!

此外,您可能还需要NumericDate上的时间延长:

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

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

答案 2 :(得分:3)

如果你不想加载大量的图书馆,如果你不介意做那个穷人的方式,你知道你的偏移是-8,例如,你可以减去8 * 3600秒来获得新的时间。例如,

offset=-8
t = Time.now + offset * 3600

你需要自己调整一天的节约时间,这也不会改变时区,所以%z不会是正确的。

答案 3 :(得分:0)

我最近对iron.io worker做了同样的事情,默认时间是UTC

# For generality/testing, only require what you need. 
require 'active_support/all'  

# Set the Timezone 
Time.zone = "Asia/Hong_Kong" 

t = Time.zone.now
#=> 2015-01-20 16:44:58 +0800

有关支持的时区的信息,请查看ActiveSupport http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html

答案 4 :(得分:0)

获取utc中的当前时间,然后添加偏移量:

Time.now.utc + Time.zone_offset('PDT')
#=> 2015-12-01 18:10:07 UTC

此处的问题是PDT固定为-8PST固定为-7和太平洋地区(根据一年中的时间调整两者之间)由于您可能需要ActiveSupport,因此不存在夏令时。