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 相关文章推荐
fromCharCode和charCodeAt 方法
Dec 27 Javascript
非常漂亮的JS代码经典广告
Oct 21 Javascript
fckeditor 获取文本框值的实现代码
Feb 09 Javascript
js querySelector和getElementById通过id获取元素的区别
Apr 20 Javascript
jQuery学习笔记(2)--用jquery实现各种模态提示框代码及项目构架
Apr 08 Javascript
jquery easyui使用心得
Jul 07 Javascript
获取input标签的所有属性的方法
Jun 28 Javascript
Vuejs 用$emit与$on来进行兄弟组件之间的数据传输通信
Feb 23 Javascript
vue构建单页面应用实战
Apr 10 Javascript
Easyui ueditor 整合解决不能编辑的问题(推荐)
Jun 25 Javascript
Angularjs实现控制器之间通信方式实例总结
Mar 27 Javascript
基于iview-admin实现动态路由的示例代码
Oct 02 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面向对象全攻略 (一) 面向对象基础知识
2009/09/30 PHP
解析PHP实现多进程并行执行脚本
2013/06/18 PHP
ThinkPHP的模版中调用session数据的方法
2014/07/01 PHP
PHP设计模式之适配器模式代码实例
2015/05/11 PHP
无需数据库在线投票调查php代码
2016/07/20 PHP
php实现推荐功能的简单实例
2019/09/29 PHP
Laravel中如何轻松容易的输出完整的SQL语句
2020/07/26 PHP
JavaScript与函数式编程解释
2007/04/27 Javascript
javascript 通用简单的table选项卡实现
2010/05/07 Javascript
javascript按位非运算符的使用方法
2013/11/14 Javascript
javascript弹出页面回传值的方法
2015/01/28 Javascript
JS使用post提交的两种方式
2015/12/03 Javascript
基于JavaScript判断浏览器到底是关闭还是刷新(超准确)
2016/02/01 Javascript
jQuery仿京东商城楼梯式导航定位菜单
2016/07/25 Javascript
jQuery实现点击任意位置弹出层外关闭弹出层效果
2016/10/19 Javascript
EasyUI学习之Combobox级联下拉列表(2)
2016/12/29 Javascript
jquery uploadify如何取消已上传成功文件
2017/02/08 Javascript
jQuery移除或禁用html元素点击事件常用方法小结
2017/02/10 Javascript
zTree树形插件异步加载方法详解
2017/06/14 Javascript
nodejs超出最大的调用栈错误问题
2017/12/27 NodeJs
vue2.0之多页面的开发的示例
2018/01/30 Javascript
详解JS中统计函数执行次数与执行时间
2018/09/04 Javascript
Vue.js 中 axios 跨域访问错误问题及解决方法
2018/11/21 Javascript
vue使用recorder.js实现录音功能
2019/11/22 Javascript
vue中keep-alive、activated的探讨和使用详解
2020/07/26 Javascript
[03:02]2014DOTA2西雅图邀请赛 让队员自己告诉你DK NAVI备战情况
2014/07/08 DOTA
Python可跨平台实现获取按键的方法
2015/03/05 Python
python绘制已知点的坐标的直线实例
2019/07/04 Python
pandas DataFrame 警告(SettingWithCopyWarning)的解决
2019/07/23 Python
python中threading开启关闭线程操作
2020/05/02 Python
Python+logging输出到屏幕将log日志写入文件
2020/11/11 Python
微软香港官网及网上商店:Microsoft HK
2016/09/01 全球购物
Nike香港官网:Nike HK
2019/03/23 全球购物
武汉东之林科技有限公司机试
2013/09/17 面试题
护林员个人总结
2015/03/04 职场文书
培训后的感想
2015/08/07 职场文书