在美国西雅图时区问题导致的订单库存悲剧!!!

一、 背景  

  国内的developers在互联网应用开发过程中大多不会考虑时区问题,毕竟我们的业务大多数是面向国内的,大家统一使用北京时区,基本没有问题,但是如果你的app没有限制只能在国内访问,那么就很有可能出现问题,我们近期的一个问题case就暴露了这一问题,接下来我会详细说明这一问题的过程。

这里买个关子:你知道美国西雅图时间2025-10-13 00:00:00在中国的时间是什么吗?

 

二、悲剧过程

业务规则是:当天下的订单只能锁定最早明天的库存,否则就会异常。

默认情况下,前端显示给用户看到的订单开始时间是当前时间(用户当前所在地的时区)的次日零点,一美国西雅图用户在2025-10-12 17:05:34下单,那么此时用户看到的订单开始时间是2025-10-13 00:00:00(夏令时期间)。

由于美国西雅图夏令时期间使用UTC-7时区,而北京时间使用UTC+8时区,两地时差为15小时(北京时间 = 西雅图时间 + 15小时),所以此时是中国的2025-10-13 15:00:00。

订单系统一看:大胆!!!怎么能下当天的库存?随即扔出一记Exception,库存异常。

 

三、时间戳

细节过程涉及到一个时间戳的概念:

时间戳是以毫秒为单位表示的时间戳,通常是一个13位整数。它表示从1970年1月1日00:00:00 UTC(Unix纪元)开始经过的毫秒数。这个特定时间点被称为"Unix纪元",是计算机系统中广泛使用的时间基准。

 

这里有个隐含的知识盲区,那就是,同一个时刻地球上获取到的时间戳是相同的,但是由于时区不同显示的本地时间也是不同的。

回到刚才的case,前端传给后端的时间戳是:1760338800000(对应美国西雅图2025-10-13 00:00:00),但是这个时间戳在中国就是2025-10-13 15:00:00

timezong

 

四、解决方案

解决方案有很多种,其中一种较为常见的方式是如下:

  • 1. 使用服务器时间、以北京时间为准。
  • 2. 添加服务时间check。
  • 3. 用户侧告知时间为北京时间。

需要注意的是,当使用服务器时间的时候,服务端传给前端的时间就不要给时间戳了,给个yyyy-MM-dd HH:mm:ss格式的字符串吧!

 

五、总结

最后厚着脸皮个自己上线的小游戏打个广告😂,肝了半年的小游戏终于上线了,微信、抖音都可以玩,欢迎大家试玩:

微信图片_20251119132312_305_41              微信图片_20251119132307_304_41

 

posted on 2025-11-19 13:26  wen2012  阅读(159)  评论(1)    收藏  举报

导航