You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails应用夏令时(DST)变更后营业时间显示异常的排查与修复

开罗夏令时(DST)切换后营业时间显示异常排查与修复

开罗地区夏令时变更后,用户端显示的营业时间比实际晚了一小时,以下是我们的问题排查过程及解决方案,供遇到同类问题的开发者参考。

调试难点

此次调试耗时较长,核心原因是moment库在浏览器与ReactNative环境中的表现存在差异(可能也与版本不同有关)。

根因分析

问题的核心是代码设计缺陷:我们使用时间戳而非单纯的小时数来存储营业时间。通用时间戳会附带UTC+DST偏移量,这正是问题的根源。

举例来说:我们存储的营业时间为9:00+002,本意是代表本地时间11:00,但当夏令时切换为+3偏移量后,这个固定偏移量就不再适用了。服务器传递给客户端的是门店营业时间09:00+2,但夏令时恢复后,客户端会将其解析为UTC时间09:00,再加上当前夏令时的+3偏移量,最终导致原本冬季9:00开门的门店,现在显示为10:00开门。

临时修复方案

在Rails应用中,正确的做法是不要将通用时间存储为时间戳。若已存在该问题,可采用以下临时解决方法:

offset = Time.current.strftime("%:z")   # 获取当前时区偏移量

json.opening_hours branch.opening_hours.select { |o| o.day == DateTime.current.wday }.map { |o|
  { 
    opens_at: o.opens_at.iso8601.to_s.gsub(/\+\d\d:\d\d/,offset)
    # 其他营业时间字段同理处理
  }
}

优化方案(补充说明)

除上述临时方案外,若需处理时间计算,可将偏移量修改为系统当前配置的偏移量,使用change_to_current_tz这类辅助函数也能解决问题。更优的方案是重构应用,将小时数存储为整数并基于此处理,正如Les Nightingail指出的:

def change_to_current_tz(time)
    offset = Time.current.strftime("%:z")   # 获取当前时区偏移量
    now = DateTime.current
    # 确保基于当日时间处理,丢弃原日期部分替换为当日日期
    # 若不需要此逻辑,请根据业务需求修改
    Time.new(
      now.year, now.month, now.day,
      time.hour, time.min, time.sec,
      offset
    ) 
end

欢迎大家提出关于营业时间处理的最佳方案及建议。

内容的提问来源于stack exchange,提问作者Dimo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 20:12:50