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 Ajax之$.get()方法和$.post()方法
Oct 12 Javascript
javascript 实现简单的table排序及table操作练习
Dec 28 Javascript
js实现杯子倒水问题自动求解程序
Mar 25 Javascript
JavaScript实现在数组中查找不同顺序排列的字符串
Sep 26 Javascript
js显示当前日期时间和星期几
Oct 22 Javascript
Ajax的概述与实现过程
Nov 18 Javascript
javascript判断firebug是否开启的方法
Nov 23 Javascript
webpack配置之后端渲染详解
Oct 26 Javascript
react redux入门示例
Apr 19 Javascript
微信小程序methods中定义的方法互相调用的实例代码
Aug 07 Javascript
Vue移动端实现图片上传及超过1M压缩上传
Dec 23 Javascript
Vue和React有哪些区别
Sep 12 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
双料怀旧--SHARP GF515的维护、修理和简单调试
2021/03/02 无线电
PHP中计算字符串相似度的函数代码
2012/12/29 PHP
php calender(日历)二个版本代码示例(解决2038问题)
2013/12/24 PHP
PHP中file_exists()判断中文文件名无效的解决方法
2014/11/12 PHP
Yii使用ajax验证显示错误messagebox的解决方法
2014/12/03 PHP
PHP实时统计中文字数和区别
2019/02/28 PHP
laravel 中某一字段自增、自减的例子
2019/10/11 PHP
js的event详解。
2006/09/06 Javascript
使用户点击后退按钮使效三行代码
2007/07/07 Javascript
jquery动态加载js/css文件方法(自写小函数)
2014/10/11 Javascript
JSON相关知识汇总
2015/07/03 Javascript
vuejs2.0实现一个简单的分页示例
2017/02/22 Javascript
利用js的闭包原理做对象封装及调用方法
2017/04/07 Javascript
浅谈angularJS的$watch失效问题的解决方案
2017/08/11 Javascript
JavaScript对象的浅拷贝与深拷贝实例分析
2018/07/25 Javascript
在vue项目中优雅的使用SVG的方法实例详解
2018/12/03 Javascript
Vue2.0 实现页面缓存和不缓存的方式
2019/11/12 Javascript
vue全屏事件开发详解
2020/06/17 Javascript
jquery实现简单拖拽效果
2020/07/20 jQuery
python self,cls,decorator的理解
2009/07/13 Python
Python实现获取域名所用服务器的真实IP
2015/10/25 Python
python实现下载整个ftp目录的方法
2017/01/17 Python
python实现各进制转换的总结大全
2017/06/18 Python
python 动态生成变量名以及动态获取变量的变量名方法
2019/01/20 Python
新西兰最大的品牌运动鞋购物网站:Platypus NZ
2017/10/27 全球购物
Vilebrequin欧洲官网:法国豪华泳装品牌(男士沙滩裤)
2018/04/14 全球购物
巴西女装购物网站:Eclectic
2018/04/24 全球购物
Sarenza德国:法国最大的时尚鞋和包包网上商店
2019/06/08 全球购物
银行学习十八大感想
2014/01/11 职场文书
红旗方阵解说词
2014/02/12 职场文书
函授生自我鉴定
2014/03/25 职场文书
投资合作协议书
2014/04/17 职场文书
我爱我校演讲稿
2014/05/21 职场文书
2015年春节标语口号
2014/12/09 职场文书
2014会计年终工作总结
2014/12/20 职场文书
Apache压力测试工具的安装使用
2021/03/31 Servers