Ruby通过经纬度获取指定日期不含夏令时的时区偏移问题咨询
问题原因
你之前的写法出错核心是两个误区:
- 不带参数调用
tz.utc_offset、tz.dst?时,返回的是系统当前时间对应时区的偏移和夏令时状态,不是你指定的历史时间的结果 - 用
Time.new创建的时间默认携带本地时区属性,传入tz.time方法时会先转成UTC再转换为目标时区时间,最终得到的时间和你预期的「目标时区当地指定时间」不一致,导致夏令时判断错误
正确判断指定时区指定时间的夏令时状态
直接将你要查询的UTC时间作为参数传给tz.dst?方法即可,不需要手动做时区转换:
# 示例:查询墨尔本时区,UTC时间2009-12-31 14:00(对应墨尔本当地2010-01-01 01:00)是否处于夏令时 tz = Timezone.lookup(-37.814, 145) target_utc_time = Time.utc(2009,12,31,14,0,0) tz.dst?(target_utc_time) # 返回结果为true,和实际情况一致
如果你只知道目标时区的当地时间,不知道对应的UTC时间,可以直接用tz.parse解析当地时间字符串,再调用dst?:
local_time = tz.parse("2010-01-01 01:00:00") local_time.dst? # 同样返回true
正确获取不含夏令时的标准时区偏移
通过指定时间的偏移和夏令时状态计算即可,通用方法如下:
def get_standard_utc_offset(tz, target_utc_time = Time.now.utc) current_offset = tz.utc_offset(target_utc_time) # 夏令时开启时偏移多了3600秒,减掉即为标准偏移 tz.dst?(target_utc_time) ? current_offset - 3600 : current_offset end
验证示例
- 英国伦敦2021-10-12 12:37 UTC时间的标准偏移:
tz = Timezone.lookup(51.51, 0.1) utc_time = Time.utc(2021,10,12,12,37) get_standard_utc_offset(tz, utc_time) # 返回0,符合要求
- 澳大利亚墨尔本2021-10-12 12:37 UTC时间的标准偏移:
tz = Timezone.lookup(-37.814, 145) utc_time = Time.utc(2021,10,12,12,37) get_standard_utc_offset(tz, utc_time) # 返回36000,即10小时,符合要求
内容的提问来源于stack exchange,提问作者Rojj
相关产品推荐
相关产品推荐

