如何计算红宝石中给定时区与 UTC 的偏移量(以小时为单位)?
Posted
技术标签:
【中文标题】如何计算红宝石中给定时区与 UTC 的偏移量(以小时为单位)?【英文标题】:How do I calculate the offset, in hours, of a given timezone from UTC in ruby? 【发布时间】:2012-04-15 06:20:02 【问题描述】:我需要在 Ruby 中计算给定时区与 UTC 的偏移量(以小时为单位)。这行代码一直在为我工作,或者我认为:
offset_in_hours = (TZInfo::Timezone.get(self.timezone).current_period.offset.utc_offset).to_f / 3600.0
但是,事实证明这是返回给我的标准偏移量,而不是 DST 偏移量。例如,假设
self.timezone = "America/New_York"
如果我运行上面的行,offset_in_hours = -5,而不是应该的 -4,因为今天的日期是 2012 年 4 月 1 日。
任何人都可以告诉我如何根据 UTC 计算 offset_in_hours 给定一个有效的 Ruby 字符串 TimeZone,它同时考虑了标准时间和夏令时?
谢谢!
更新
这是 IRB 的一些输出。请注意,由于夏令时,纽约比 UTC 晚 4 小时,而不是 5 小时:
>> require 'tzinfo'
=> false
>> timezone = "America/New_York"
=> "America/New_York"
>> offset_in_hours = TZInfo::Timezone.get(timezone).current_period.utc_offset / (60*60)
=> -5
>>
这表明 TZInfo 中存在错误或者它不支持 dst
更新 2
根据 joelparkerhender 的 cmets,上述代码中的错误是我使用的是 utc_offset,而不是 utc_total_offset。
因此,根据我最初的问题,正确的代码行是:
offset_in_hours = (TZInfo::Timezone.get(self.timezone).current_period.offset.utc_total_offset).to_f / 3600.0
【问题讨论】:
【参考方案1】:是的,像这样使用 TZInfo:
require 'tzinfo'
tz = TZInfo::Timezone.get('America/Los_Angeles')
获取当前周期:
current = tz.current_period
要了解夏令时是否有效:
current.dst?
#=> true
从 UTC 获取时区的基本偏移量(以秒为单位):
current.utc_offset
#=> -28800 which is -8 hours; this does NOT include daylight savings
从标准时间获取夏令时偏移:
current.std_offset
#=> 3600 which is 1 hour; this is because right now we're in daylight savings
要获得与 UTC 的总偏移量:
current.utc_total_offset
#=> -25200 which is -7 hours
与 UTC 的总偏移量等于 utc_offset + std_offset。
这是与夏令时生效的本地时间的偏移量,以秒为单位。
【讨论】:
帮助我理解——如果 current_period 是通过 dst 知道的?夏令时是活跃还是不活跃,那么为什么 current_period.offset 没有考虑到这一点?这是一个错误吗?最终,我知道 TimeZone 中的所有这些方法,我的目标是为变量 offset_in_hours 分配正确的值 请查看我上面运行 irb 的输出 - 这表明 tzinfo 实际上不支持 dst,或者存在错误? 不是错误——你只需要考虑 dst。我已经在答案中添加了关于另外两种方法的信息来说明如何做到这一点。 是否可以轻松地将结果(以秒为单位)转换为“-0200”之类的字符串,以便在某些 DateTime 方法中使用?还是我需要为这种情况实现自己的转换器和格式化程序?谢谢 这应该在 tzinfo 的 README 中以上是关于如何计算红宝石中给定时区与 UTC 的偏移量(以小时为单位)?的主要内容,如果未能解决你的问题,请参考以下文章
Python 中给定 TimeZone 的标准 UTC 偏移量(无 DST)