最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • new Date()引发的血案

    正文概述 掘金(冲锋陷阵的书生)   2021-03-31   690

    new Date()引发的血案

    • 背景

      • 距离上线就剩一天了,晚上临下班的时候,我们测试小姐姐火急火燎的找我来了,日期插件出问题啦,顿时虎躯一震,感觉距离下班时间又远了一步,这个插件是从其他项目直接拿过来的,已经在线上运行很久了,怎么还会有问题呢。
      • 先让测试小姐姐莫急,然后了解了一下问题,原来是插件初始化是3月份,点击下一月的时候直接跳转至5月了,初听一脸懵逼,还有这种神奇的bug,果然bug之多,无奇不有。
    • 排查

      • 开始一顿排查,最终发现是new Date()的问题,因为默认日期是3月31号,所以new Date()的时间是2021-3-31,问题就出在了这个31上边。
    • 原理

      • 创建一个 JavaScript Date 实例,该实例呈现时间中的某个时刻。Date 对象则基于 Unix Time Stamp,即自1970年1月1日(UTC)起经过的毫秒数。

      • Date()构造函数有四种基本形式

        • new Date();  //如果没有提供参数,那么新创建的Date对象表示实例化时刻的日期和时间。
          new Date(value);  //一个 Unix 时间戳(Unix Time Stamp),它是一个整数值,表示自1970年1月1日00:00:00 UTC(the Unix epoch)以来的毫秒数,忽略了闰秒。请注意大多数 Unix 时间戳功能仅精确到最接近的秒
          new Date(dateString); //表示日期的字符串值。该字符串应该能被 Date.parse() 正确方法识别
          new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]]);//当至少提供了年份与月份时,这一形式的 Date() 返回的 Date 对象中的每一个成员都来自下列参数。没有提供的成员将使用最小可能值(对日期为1,其他为0)。
          //参数monthIndex 是从“0”开始计算的,这就意味着一月份为“0”,十二月份为“11”。
          
      • 而此时问题就出在了 new Date(year, monthIndex, day)上边,new Date(2021,3,31)得出的时间竟然是(Sat May 01 2021 00:00:00 GMT+0800 (中国标准时间))2021年5月1号。

      • 注意 参数monthIndex 是从“0”开始计算的,这就意味着一月份为“0”,十二月份为“11”。

      • 首先我们要知道,使用new Date(2021,3,31)这样的格式来传入参数的时候,会将月份自动加1,得到真实月份,即传入的是3月份,则得到的是4月份。

      • **注意:**当Date作为构造函数调用并传入多个参数时,如果数值大于合理范围时(如月份为 13 或者分钟数为 70),相邻的数值会被调整。比如 new Date(2013, 13, 1)等于new Date(2014, 1, 1),它们都表示日期2014-02-01(注意月份是从0开始的)。其他数值也是类似,new Date(2013, 2, 1, 0, 70)等于new Date(2013, 2, 1, 1, 10),都表示同一个时间:2013-03-01T01:10:00。(来自MDN)

      • 所以当new Date(2021,3,31)时,由于3月份是31天而4月份并没有31号,所以数值大于了合理范围,相邻的数值被调整为了5月1号。

    • 解决方案

      • 最简单的就是调整参数格式,即new Date(YYYY,MM,DD)改为new Date(YYYY-MM-DD),但是这样的格式在我的项目代码中改动太多,不适合我当前的情况。

      • 既然是和每月的天数和月份有关系,那么就从当前月的月份和天数来解决此问题,即以下解决方案

        • var currentDay; //当前月份天数
          var currentMonthDays = new Date(year, month, 0).getDate(); //拿到当前月份的天数
          var nextMonthDays = new Date(year, month + 1, 0).getDate();  //拿到下一月份的天数
          var days = currentDay > nextMonthDays? nextMonthDays: currentDay; //进行比较,如果当前月份天数大于下一月份天数,则days等于下一个月份的天数,否则为当前月份天数
          new Date(that.year, that.month, days);
          //即可解决此问题
          

    我是书生,前端浪花中的一朵小浪花。


    起源地下载网 » new Date()引发的血案

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元