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 相关文章推荐
javascript同步Import,同步调用外部js的方法
Jul 08 Javascript
Javascript中的回调函数和匿名函数的回调示例介绍
May 12 Javascript
JS实现获取键盘按下的按键并显示在页面上的方法
Nov 04 Javascript
仅30行代码实现Javascript中的MVC
Feb 15 Javascript
jQuery 选择同时包含两个class的元素的实现方法
Jun 01 Javascript
javascript实现抽奖程序的简单实例
Jun 07 Javascript
解析JavaScript模仿块级作用域
Dec 29 Javascript
使用jquery的jsonp如何发起跨域请求及其原理详解
Aug 17 jQuery
AngularJS动态添加数据并删除的实例
Feb 27 Javascript
jQuery属性选择器用法实例分析
Jun 28 jQuery
element-ui 本地化使用教程详解
Oct 28 Javascript
文章或博客自动生成章节目录索引(支持三级)的实现代码
May 10 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
用来解析.htpasswd文件的PHP类
2012/09/05 PHP
PHP7匿名类用法分析
2016/09/26 PHP
jQuery EasyUI API 中文文档 - Form表单
2011/10/06 Javascript
jQuery EasyUI API 中文文档 - ComboBox组合框
2011/10/07 Javascript
jquery实现微博文字输入框 输入时显示输入字数 效果实现
2013/07/12 Javascript
简单常用的幻灯片播放实现代码
2013/09/25 Javascript
IE下双击checkbox反应延迟问题的解决方法
2014/03/27 Javascript
jQuery+ajax中getJSON() 用法实例
2014/12/22 Javascript
jQuery动态效果显示人物结构关系图的方法
2015/05/07 Javascript
JavaScript模版引擎的基本实现方法浅析
2016/02/15 Javascript
jQuery+CSS3+Html5实现弹出层效果实例代码(附源码下载)
2016/05/16 Javascript
老生常谈js动态添加事件--- 事件委托
2016/07/19 Javascript
微信小程序开发探究
2016/12/27 Javascript
微信小程序 实例开发总结
2017/04/26 Javascript
webpack配置文件和常用配置项介绍
2017/04/28 Javascript
jQuery length 和 size()区别总结
2018/04/26 jQuery
Nuxt升级2.0.0时出现的问题(小结)
2018/10/08 Javascript
vue.js层叠轮播效果的实例代码
2018/11/08 Javascript
JS数组属性去重并校验重复数据
2020/01/10 Javascript
[42:34]VP vs VG 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
python中while循环语句用法简单实例
2015/05/07 Python
python中reduce()函数的使用方法示例
2017/09/29 Python
django传值给模板, 再用JS接收并进行操作的实例
2018/05/28 Python
Python3中详解fabfile的编写
2018/06/24 Python
实例讲解Python中整数的最大值输出
2019/03/17 Python
Python中利用LSTM模型进行时间序列预测分析的实现
2019/07/26 Python
Python使用for生成列表实现过程解析
2020/09/22 Python
HTML5里autofocus自动聚焦属性使用介绍
2016/06/22 HTML / CSS
美国电视购物:QVC
2017/02/06 全球购物
Under Armour西班牙官网:美国知名的高端功能性运动品牌
2018/12/12 全球购物
String s = new String(“xyz”);创建了几个String Object?
2015/08/05 面试题
军训的自我鉴定
2013/12/10 职场文书
销售主管岗位职责范本
2014/02/14 职场文书
不错的求职信范文
2014/07/20 职场文书
冰雪公主观后感
2015/06/16 职场文书
Qt自定义Plot实现曲线绘制的详细过程
2021/11/02 Python