Chr*_*bek 1 ruby timezone datetime tzinfo timezone-offset
对于任何了解tzinfo
API的人来说,这可能都是微不足道的:
给定Timezone
来自的对象tzinfo
,我如何获得给定时间点的UTC偏移量(以时区或UTC的本地时间给出)?
小智 5
您可以使用period_for_local
方法。对于这些示例,我使用的时区是(America/Sao_Paulo
),偏移时间是-03:00
冬季(3月至10月)和-02:00
夏季(夏令时):
# Sao Paulo timezone
zone = TZInfo::Timezone.new('America/Sao_Paulo')
# date in January (Brazilia Summer Time - DST)
d = DateTime.new(2017, 1, 1, 10, 0)
period = zone.period_for_local(d)
puts period.offset.utc_total_offset / 3600.0
# date in July (Brazilia Standard Time - not in DST)
d = DateTime.new(2017, 7, 1, 10, 0)
period = zone.period_for_local(d)
puts period.offset.utc_total_offset / 3600.0
Run Code Online (Sandbox Code Playgroud)
输出为:
-2.0
-3.0
该utc_total_offset
方法以秒为单位返回偏移量,因此我将其除以3600得到以小时为单位的值。
请注意,我还曾经3600.0
强制将结果设置为浮点型。如果我仅使用3600
,结果将被舍入,并且类似的时区Asia/Kolkata
(具有的偏移量+05:30
)将给出错误的结果(5
而不是5.5
)。
请注意,您必须注意DST的更改,因为您可能会有间隙或重叠。
在圣保罗时区,DST从2017年10月15日开始:在午夜,时钟向前移动至凌晨1点(偏移从更改-03:00
为-02:00
),因此所有00:00到01:00之间的本地时间均无效。在这种情况下,如果您尝试获取偏移量,则会得到一个PeriodNotFound
错误:
# DST starts at October 15th, clocks shift from midnight to 1 AM
d = DateTime.new(2017, 10, 15, 0, 30)
period = zone.period_for_local(d) # error: TZInfo::PeriodNotFound
Run Code Online (Sandbox Code Playgroud)
DST结束时,即2018年2月18日午夜时钟移回到17日的晚上11点(偏移量从更改-02:00
为-03:00
),因此11 PM和午夜之间的本地时间存在两次(两个偏移量)。
在这种情况下,您必须指定所需的值(通过设置的第二个参数period_for_local
),以指示是否要使用DST的偏移量:
# DST ends at February 18th, clocks shift from midnight to 11 PM of 17th
d = DateTime.new(2018, 2, 17, 23, 30)
period = zone.period_for_local(d, true) # get DST offset
puts period.offset.utc_total_offset / 3600.0 # -2.0
period = zone.period_for_local(d, false) # get non-DST offset
puts period.offset.utc_total_offset / 3600.0 # -3.0
Run Code Online (Sandbox Code Playgroud)
如果不指定第二个参数,则会出现TZInfo::AmbiguousTime
错误:
# error: TZInfo::AmbiguousTime (local time exists twice due do DST overlap)
period = zone.period_for_local(d)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
562 次 |
最近记录: |