Moment的feature导致线上bug解决分析


Posted in Javascript onSeptember 23, 2022

bug的出现

这一天,本来是平平淡淡的一天,我正准备一如既往的到点下班,结果qa说线上出了个匪夷所思的bug。

表象为:用户在日期选择器选择了1964-01-01之后,自动变成了1963-12-31

我心里想:这是什么神奇bug,于是我又尝试了一下选择1964-01-02、1963-12-31、1965-01-01、1963-01-01,结果都正常,那么到底是为什么会引发这个bug呢?

bug排查

由于后端把时间、日期类的字段都定义为了时间戳,因此前端是有进行一些处理的,可以看下面这个图

Moment的feature导致线上bug解决分析

从接口中拿到时间戳后,会先存到内存中,格式化后传入antd日期选择器中。每当用户选择日期之后,我会截取日期中的年月日,然后使用moment-timezone去获取到雅加达(印尼首都)当天零点的时间戳,存储到内存中,当用户点击提交的时候,这个时间戳就会被提交到后端去

再来看一下用户选择日期后进行处理的代码

import momentTimeZone from 'moment-timezone';
import moment from 'moment';
import type { Moment } from 'moment';
convert = (value?: Moment | null) => {
        if (value) {
          const valueString = momentTimezone.tz(value.format('YYYY-MM-DD'), 'Asia/Jakarta').format();
          return (moment(valueString).valueOf() / 1000).toFixed();
        }
        return value;
      }

bug的根因

乍一看,没什么问题呀,于是我开始断点,脑溢血的一幕出现了,大家可以去momentjs.com/timezone/do… 这个页面上试一试,百分百复现

Moment的feature导致线上bug解决分析

// 让人大吃一惊的等式
moment.tz('1961-01-01', 'Asia/Jakarta').format() === '1963-12-31T23:30:00+07:00';

这怎么转换之后,日期还给我整错了呢?我的第一反应就是给moment-timezone提issue,结果没想到有人赶在了我的前面 github.com/moment/mome…

官方也解释的很清楚了:由于当地历史原因,雅加达在1964年之前都是按东七半区来计算时区的,1964年开始才按照东七区来计算,总的来说,这个匪夷所思的等式居然是个feature,只是我使用之前没有了解清楚,所以出了bug,这锅是甩不掉了

解决方案

经过一系列的讨论,我们认为其实日期类型的字段用时间戳表达是不准确的,比如元旦这个节日,在全世界任何一个地区都应该是1月1日,可是如果用时间戳表达的话,可能在某些地区的确是1月1日,但是在其他地区却可能是1月2日了,因此正确的设计应该是用日期字符串来进行存储和传输,比如"2022-01-01",这样才能避免类似的bug,于是前端、app和be都进行了对应的修改,并且发布了hotfix

虽然影响范围比较小,但是众所周知虾皮对于质量是看的很重的,特别是线上的质量。。。只是可惜了我的绩效。。

好了以上就是Moment的feature导致线上bug解决分析的详细内容,更多关于Moment feature线上bug的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
分享别人写的一个小型js框架
Aug 13 Javascript
js获取url参数的使用扩展实例
Dec 29 Javascript
Javascript 中的 && 和 || 使用小结
Apr 25 Javascript
js解析与序列化json数据(二)序列化探讨
Feb 01 Javascript
IE的fireEvent方法概述及应用
Feb 22 Javascript
jQuery中eq()方法用法实例
Jan 05 Javascript
基于JavaScript实现智能右键菜单
Mar 02 Javascript
如何解决hover在ie6中的兼容性问题
Dec 15 Javascript
修改vue+webpack run build的路径方法
Sep 01 Javascript
基于Vue 服务端Cookies删除的问题
Sep 21 Javascript
javascript设计模式 ? 享元模式原理与用法实例分析
Apr 15 Javascript
js面试题之异步问题的深入理解
Sep 20 Javascript
js 实现Material UI点击涟漪效果示例
Sep 23 #Javascript
js 实现验证码输入框示例详解
Sep 23 #Javascript
TypeScript 内置高级类型编程示例
Sep 23 #Javascript
详解Anyscript开发指南绕过typescript类型检查
Sep 23 #Javascript
js基于div丝滑实现贝塞尔曲线
Sep 23 #Javascript
TS 类型兼容教程示例详解
Sep 23 #Javascript
TS 类型收窄教程示例详解
Sep 23 #Javascript
You might like
PHP与MySQL交互使用详解
2006/10/09 PHP
PHP和JAVA中的重载(overload)和覆盖(override) 介绍
2012/03/01 PHP
php比较相似字符串的方法
2015/06/05 PHP
php实现不通过扩展名准确判断文件类型的方法【finfo_file方法与二进制流】
2017/04/18 PHP
Laravel Reponse响应客户端示例详解
2020/09/03 PHP
nginx 设置多个站跨域
2021/03/09 Servers
关于js类的定义
2011/06/28 Javascript
js获取客户端网卡的IP地址、MAC地址
2014/03/26 Javascript
jQuery取id有.的值的方法
2014/05/21 Javascript
JavaScript-html标题滚动效果的简单实现
2016/09/08 Javascript
RGB和YUV 多媒体编程基础详细介绍
2016/11/04 Javascript
详解js中Number()、parseInt()和parseFloat()的区别
2016/12/20 Javascript
javascript 开发之百度地图使用到的js函数整理
2017/05/19 Javascript
浅谈Angular路由复用策略
2017/10/04 Javascript
浅谈webpack下的AOP式无侵入注入
2017/11/12 Javascript
Bootstrap实现翻页效果
2017/11/27 Javascript
详解ES6 系列之异步处理实战
2018/10/26 Javascript
vue 使用vue-i18n做全局中英文切换的方法
2018/10/29 Javascript
[32:26]EG vs IG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
[46:38]完美世界DOTA2联赛PWL S2 Magma vs PXG 第三场 11.28
2020/12/02 DOTA
python实现根据用户输入从电影网站获取影片信息的方法
2015/04/07 Python
Python模拟鼠标点击实现方法(将通过实例自动化模拟在360浏览器中自动搜索python)
2017/08/23 Python
Pycharm取消py脚本中SQL识别的方法
2018/11/29 Python
对Python 除法负数取商的取整方式详解
2018/12/12 Python
Python3中的bytes和str类型详解
2019/05/02 Python
python使用paramiko模块通过ssh2协议对交换机进行配置的方法
2019/07/25 Python
Python连接字符串过程详解
2020/01/06 Python
HTML5对手机页面长按会粘贴复制禁用的解决方法
2016/07/19 HTML / CSS
自我鉴定模板
2013/10/29 职场文书
DIY蛋糕店的创业计划书范文
2013/12/26 职场文书
小学二年级学生评语
2014/04/21 职场文书
保护野生动物倡议书
2014/05/16 职场文书
安全生产知识竞赛活动总结
2014/07/07 职场文书
幼师自荐信范文(2016推荐篇)
2016/01/28 职场文书
SpringCloud Alibaba项目实战之nacos-server服务搭建过程
2021/06/21 Java/Android
Ubuntu18.04下QT开发Android无法连接设备问题解决实现
2022/06/01 Java/Android