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 相关文章推荐
jQuery下的动画处理总结
Oct 10 Javascript
Js获取下拉框选定项的值和文本的实现代码
Feb 26 Javascript
Javascript限制网页只能在微信内置浏览器中访问
Nov 09 Javascript
wap手机端解决返回上一页的js实例
Dec 08 Javascript
HTML5+Canvas调用手机拍照功能实现图片上传(下)
Apr 21 Javascript
JavaScript 巧学巧用
May 23 Javascript
JS中LocalStorage与SessionStorage五种循序渐进的使用方法
Jul 12 Javascript
JS实现table表格固定表头且表头随横向滚动而滚动
Oct 26 Javascript
element-ui中的select下拉列表设置默认值方法
Aug 24 Javascript
如何在微信小程序中实现Mixins方案
Jun 20 Javascript
ES2020系列之空值合并运算符 '??'
Jul 22 Javascript
浅谈JS的原型和原型链
Jun 04 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系统类函数
2015/10/21 PHP
WordPress中缩略图的使用以及相关技巧
2015/11/24 PHP
获取JavaScript用户自定义类的类名称的代码
2007/03/08 Javascript
javascript cookie操作类的实现代码小结附使用方法
2010/06/02 Javascript
Javascript算符的优先级介绍
2013/03/20 Javascript
jQuery的$.proxy()应用示例介绍
2014/04/03 Javascript
js实现带缓冲效果的仿QQ面板折叠菜单代码
2015/09/06 Javascript
jQuery实现的自适应焦点图效果完整实例
2016/08/24 Javascript
jQuery实现的自定义滚动条实例详解
2016/09/20 Javascript
weebox弹出窗口不居中显示的解决方法
2017/11/27 Javascript
ES6 对象的新功能与解构赋值介绍
2019/02/05 Javascript
Webpack中loader打包各种文件的方法实例
2019/09/03 Javascript
JS随机密码生成算法
2019/09/23 Javascript
JavaScript变量基本使用方法实例分析
2019/11/15 Javascript
Node登录权限验证token验证实现的方法示例
2020/05/25 Javascript
[04:36]DOTA2国际邀请赛 ti3精彩集锦
2013/08/19 DOTA
tensorflow saver 保存和恢复指定 tensor的实例讲解
2018/07/26 Python
利用anaconda作为python的依赖库管理方法
2019/08/13 Python
对Django中的权限和分组管理实例讲解
2019/08/16 Python
在Python中实现函数重载的示例代码
2019/12/12 Python
安装PyInstaller失败问题解决
2019/12/14 Python
Pytorch.nn.conv2d 过程验证方式(单,多通道卷积过程)
2020/01/03 Python
Django 构建模板form表单的两种方法
2020/06/14 Python
Python列表的深复制和浅复制示例详解
2021/02/12 Python
Omio西班牙:全欧洲低价大巴、火车和航班搜索和比价
2017/02/11 全球购物
Gucci法国官方网站:意大利奢侈品牌
2018/07/25 全球购物
逻辑链路控制协议
2016/10/01 面试题
幼师求职自荐信范文
2014/01/26 职场文书
数控个人求职信范文
2014/02/03 职场文书
技校学生个人职业生涯规划范文
2014/03/03 职场文书
新学期决心书
2014/03/11 职场文书
教师自我剖析材料(四风问题)
2014/09/30 职场文书
军训通讯稿范文
2015/07/18 职场文书
广告策划的实习心得体会总结!
2019/07/22 职场文书
Python3.10的一些新特性原理分析
2021/09/15 Python
排查MySQL生产环境索引没有效果
2022/04/11 MySQL