ruby 获取给定时区的时间

Posted

技术标签:

【中文标题】ruby 获取给定时区的时间【英文标题】:ruby get Time in given timezone 【发布时间】:2011-02-25 00:11:14 【问题描述】:

在 ruby​​ 中,如何获取给定时区的当前时间?我知道与 UTC 的偏移量,并希望获得具有该偏移量的时区的当前时间。

【问题讨论】:

请参考我发的***.com/questions/24577449/… 【参考方案1】:

只需加上或减去适当的秒数:

>> utc = Time.utc(2009,5,28,10,1) # 给定一个 utc 时间 => 2009 年 5 月 28 日星期四 10:01:00 UTC >> bst_offset_in_mins = 60 # 和另一个时区的偏移量 => 60 >> bst = t + (bst_offset_in_mins * 60) # 只需以秒为单位添加偏移量 => Thu May 28 11:01:00 UTC 2009 # 获取新时区的时间

【讨论】:

注意:您仍然返回 UTC 时间,它只是被偏移了,如果您尝试比较时间,这将导致各种奇怪。对此的一个很好的测试是两者是否仍然相等。 太棒了,基本上是 Time.now += number_of_seconds,谢谢!【参考方案2】:

我会使用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"

【讨论】:

当我安装 active_support gem 时,我需要 'active_support/time' 以使您的示例正常工作。【参考方案3】:

一种更简单的方法是简单地将偏移量(以整数形式)传递给 ActiveSupport::TimeZone 哈希:

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>>>>

【讨论】:

【参考方案4】:

对于 x 小时的 UTC 偏移量,可以在 Rails 中的 ActiveSupport 的帮助下计算当前时间,正如其他人所说:

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

或者不是两行

DateTime.now.in_time_zone(zone)

或者,如果您没有 Rails,也可以使用new_offset 将定位日期时间转换为另一个时区

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

【讨论】:

这应该被视为实际答案,因为它包含一个纯粹基于 ruby​​ 的解决方案。 为什么我没有早点找到这个!? DateTime.now.in_time_zone(zone)这么简单就这么美【参考方案5】:

我尝试了gem install active_support,它安装了activesupport-3.00,这给了我一个错误:

“您的应用程序中没有安装 tzinfo。请将其添加到您的 Gemfile 并运行 bundle install”

tzinfo 是 ActiveSupport 使用的一个 gem——它对我的目的来说更干净一些,没有任何外部依赖——缺点是它似乎让一切看起来都是 UTC,所以如果你希望您的时区看起来正确,gem install activerecord 将安装您需要的一切。我将这个答案包括在内,主要是供遇到相同问题/可搜索性的其他人参考。

(使用gem install tzinfo)安装gem

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

获取时区的方法有很多种,但您可以使用查看列表

TZInfo::Timezone.all

【讨论】:

【参考方案6】:

更简单、更轻量级的解决方案:

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

有据可查的here。

2021.12.23 更新:如果你有一个 tzdata timezone name 像 'US/Pacific' 而不是偏移量,并且你愿意加入 tzinfo gem,你可以也这样做(感谢@chadoh 和@kevin from below):

require 'tzinfo'

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

并不是真正提出的问题,但将来可能对人们有所帮助。

如果你想在#now 以外的时刻这样做,你应该研究Ruby Time class,特别是Time#gmTime#local,以及Ruby TZInfo classes,特别是TZInfo::Timezone.getTZInfo::Timezone#period_for_local

【讨论】:

最佳、最简单的答案。不需要也不需要宝石。应作为解决方案进行检查。顺便说一句,我正在检查文档如何获取日光转换区域。例如美国太平洋时间:有时是“-08:00”,有时是“-07:00”。 夏令时会中断。 最初的提问者询问了偏移量并指定了 Ruby,而不是 Rails。正是由于 DST 遵守问题,偏移量比时区简单得多。例如,这就是为什么印第安纳州有一个单独的时区。如果您想在 Ruby 中处理时区,请先阅读 this blog post 以了解如何处理它们。也就是说,这是一个糟糕的单线,可以将 tz 转换为包括 DST 在内的偏移量:'%+.2d:00' % (TZInfo::Timezone.get('US/Pacific').current_period.utc_total_offset / 3600) 当我按照这里的代码示例进行操作时,我发现'US/Pacific' 的偏移量是-1。那是……不正确。 chadoh 下面的回答更好。这里的问题是没有考虑夏令时。【参考方案7】:
gem install tzinfo

然后

require 'tzinfo'

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

【讨论】:

您也可以直接调用“tz.now”,仅供参考。【参考方案8】:
now = Time.now
now.in_time_zone('Eastern Time (US & Canada)') 
or 
now.in_time_zone('Asia/Manila') 

【讨论】:

in_time_zone 需要 ActiveSupport 的 DateAndTime::Zones 扩展。

以上是关于ruby 获取给定时区的时间的主要内容,如果未能解决你的问题,请参考以下文章

给定 UTC 时间,获取特定时区是午夜

如何获取给定时区的“午夜”UTC 时间?

在python中获取给定时区的DST边界

给定 UTC 时间戳和 UTC 偏移量,是不是可以在 Python 中获取时区?

如何在给定时间和状态信息的情况下获取当地时区

使用 Joda-Time 获取给定日期和时区的 UTC 偏移量