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
相关产品推荐
相关产品推荐

