记得以前参加校招的时候,总是有日期相关的面试题,比如计算两个日期之间的间隔天数。以前还觉得这种题就是为了纯粹为了面试的,但工作了之后,还就碰到了跟日期相关的bug。下面是一段js代码,是要把字符串描述的日期转换为Date类型的函数。其中,字符串的格式为年占用4个字符,月份2个字符,天数2个字符,小时2个字符,分钟2个字符,秒数2个字符。

 1 function str2Date(str) {
 2     var year = parseInt(str.substr(0, 4));
 3     // Month value range is [0, 11]
 4     var month = parseInt(str.substr(4, 2)) - 1;
 5     var day = parseInt(str.substr(6, 2));
 6     var hour = parseInt(str.substr(8, 2));
 7     var minute = parseInt(str.substr(10, 2));
 8     var second = parseInt(str.substr(12, 2));
 9
10     var date = new Date();
11     date.setYear(year);
12     date.setMonth(month);
13     date.setDate(day);
14     date.setHours(hour);
15     date.setMinutes(minute);
16     date.setSeconds(second);
17     return date;
18 }
19
20 console.log(str2Date('20150515180000').toString());
21 console.log(str2Date('20160229235959').toString());
22 console.log(str2Date('20171231235959').toString());
23 console.log(str2Date('20181101000000').toString());

今天的日期是2019年3月20日,以上代码的测试用例运行结果全部正常。输出结果如下

1234
Fri May 15 2015 18:00:00 GMT+0800 (CST)Mon Feb 29 2016 23:59:59 GMT+0800 (CST)Sun Dec 31 2017 23:59:59 GMT+0800 (CST)Thu Nov 01 2018 00:00:00 GMT+0800 (CST)

但是在某个特定日期(月末),就发现这段代码的运行结果出错了。原来,new Date()生成的值是运行时的时间,在不同的时间,运行的结果是不同的。下面来看一个特定日期的运行结果。把第10行代码中的new Date的初始化,设置日期为2019年3月31日。

var date = new Date('2019-03-31 00:00:00');

修改之后的运行结果如下,有两个用例的运行结果是不符合预期的。

1234
Fri May 15 2015 18:00:00 GMT+0800 (CST)Tue Mar 29 2016 23:59:59 GMT+0800 (CST)Sun Dec 31 2017 23:59:59 GMT+0800 (CST)Sat Dec 01 2018 00:00:00 GMT+0800 (CST)

那究竟是怎么回事呢?只能逐步调试来看下哪一步出了问题。因为是日期错了,我这里通过日志把改变日期值的中间过程都打印出来。下面以第2个用例(2016年2月29日)调试看下。

function str2Date(str) {var year = parseInt(str.substr(0, 4));// Month value range is [0, 11]var month = parseInt(str.substr(4, 2)) - 1;var day = parseInt(str.substr(6, 2));var hour = parseInt(str.substr(8, 2));var minute = parseInt(str.substr(10, 2));var second = parseInt(str.substr(12, 2));var date = new Date('2019-03-31 00:00:00');date.setYear(year);console.log(date.toString());date.setMonth(month);console.log(date.toString());date.setDate(day);console.log(date.toString());date.setHours(hour);date.setMinutes(minute);date.setSeconds(second);return date;
}

输出的结果如下:

1234
Thu Mar 31 2016 00:00:00 GMT+0800 (CST)Wed Mar 02 2016 00:00:00 GMT+0800 (CST)Tue Mar 29 2016 00:00:00 GMT+0800 (CST)Tue Mar 29 2016 23:59:59 GMT+0800 (CST)

从输出结果来看SetMonth这一步就出错了。原来在当前场景下,调用SetMonth设置的月份,会导致预期时间是一个不合法的时间,而Date类进行了自动的纠正,也就改变了月份的值。后面又重新设置了天数,是合法值,Date不再对日期进行改变,最终就导致月份是错误的。
通过查询MDN文档,发现setFullYear函数是可以把年月日都作为参数输入,这样就能保证日期的完整性,特殊日期也不会出错。修改后的代码如下:

function str2Date(str) {var year = parseInt(str.substr(0, 4));// Month value range is [0, 11]var month = parseInt(str.substr(4, 2)) - 1;var day = parseInt(str.substr(6, 2));var hour = parseInt(str.substr(8, 2));var minute = parseInt(str.substr(10, 2));var second = parseInt(str.substr(12, 2));var date = new Date('2019-03-31 00:00:00');date.setFullYear(year, month, day);date.setHours(hour, minute, second);return date;
}console.log(str2Date('20150515180000').toString());
console.log(str2Date('20160229235959').toString());
console.log(str2Date('20171231235959').toString());
console.log(str2Date('20181101000000').toString());

通过这个例子说明,每个函数的异常处理都有可能导致最终的结果出错,如果使用了系统函数或者其他库的函数,都需要对每个函数的异常处理有足够的了解,才能保证结果符合预期。

关于作者

bingoli

原文地址:https://www.cnblogs.com/bingoli/p/10574465.html

转载于:https://www.cnblogs.com/bingoli/p/10574465.html

JavaScript的Date类的函数特殊处理导致的问题相关推荐

  1. c++日期类(Date类)

    1.Date中的构造函数 构造函数的作用可以说是对类变量的初始化(Init)如果我们不写构造函数,系统会生成默认的构造函数,但是对于date类来说,这里的默认构造函数什么都不做,如果你创建了一个 Da ...

  2. 设计Date类,该类采用3个整型存储日期: month、 data和year。其函数成员具有按如下格式输出日期的功能(异常处理)

    1.简答题 设计Date类,该类采用3个整型存储日期: month. data和year.其函数成员具有按如下格式输出日期的功能: 12-25-11 December 25,2011 25 Decem ...

  3. java的Date类的getYear(),getMonth()等函数过时

    java的Date类的getYear(),getMonth()等函数都已经过时,可以使用Calendar 来替代. SimpleDateFormat ft = new SimpleDateFormat ...

  4. Json 时间 转换为 Javascript 时间 Date Jquery 调用WCF

    "/Date(1232035200000)/" 怎么转换成 javascript 的 Date 对象 做法:new Date(+/\d+/.exec(value)[1]); val ...

  5. javascript常用工具类整理(copy)

    JavaScript常用工具类 类型 日期 数组 字符串 数字 网络请求 节点 存储 其他 1.类型 isString (o) { //是否字符串return Object.prototype.toS ...

  6. Java 常用对象-Date类和Calender类

    2017-11-02 22:29:34 Date类:类 Date 表示特定的瞬间,精确到毫秒. 在 JDK 1.1 之前,类 Date 有两个其他的函数.它允许把日期解释为年.月.日.小时.分钟和秒值 ...

  7. javascript tab切换类LixTabs最新版

    javascript Tab切换类LixTabs,更新至0.5版: 受snandy的"读jquery"系列的启发,改进了代码,现在调用LixTabs时不用加new了.即可以这样写: ...

  8. Javascript基础与面向对象基础~第四讲 Javascript中的类对象

    今天来说JS中如何实现类(class),事实上本应该昨天晚上写的,可我失言了,在些说一声"抱歉"!JS中的类是JS面向对象的基础,也是我最拿手的东西,你写的代码能否提高一个层次,一 ...

  9. Javascript中的类实现

    Javascript本身并不支持面向对象,它没有访问控制符,它没有定义类的关键字class,它没有支持继承的extend或冒号,它也没有用来支持虚函数的virtual,不过,Javascript是一门 ...

  10. zend studio中ctrl+鼠标左键无法转到类或函数定义文件的解决方法

    转载自:http://blog.csdn.net/wide288/article/details/21622183 zend studio中ctrl+鼠标左键无法转到类或函数定义文件的解决方法:  z ...

最新文章

  1. win8计算机安全模式,安全模式,教您Win8怎么进入安全模式
  2. linux jdk配置环境变量
  3. linux系统安装nginx步骤,虚拟机(linux)下安装nginx的步骤教程
  4. Golang基础之数组
  5. 实现Operations Manager 2012 R2单一部署
  6. 黑客游戏系列--------第四关
  7. 使用 Flask-apidoc 自动生成 Api 文档
  8. Ubuntu16.04下面壁纸切换软件variety设置
  9. 链式队列的实现(头文件及源程序)
  10. apache camel_探索Apache Camel Core –文件组件
  11. 本博打开方式,请详读
  12. mysql 修改表 引擎,mysql如何修改表类型(表引擎)
  13. include查找文件路径
  14. 0基础学java可行吗_上海0基础学JAVA可行吗?
  15. 系统集成项目管理工程师和信息系统项目管理师的区别
  16. D-Link DWA-160 wifi抓包
  17. c语言幂函数_了解C / C ++中的幂函数
  18. 无线测温采集设备及无线测温监控系统的选型指导-安科瑞王婧
  19. html小游戏——看你有多色
  20. 橱柜图片-橱柜效果图-整体橱柜衣柜效果图如何选购

热门文章

  1. Flink + TiDB,体验实时数仓之美
  2. android AChartEnginee讲解之自定义图表类
  3. 什么是中台?这篇漫画总算讲清楚了
  4. Android View框架总结(九)KeyEvent事件分发机制
  5. 计算机应用软件专家证,计算机应用软件项目验收报告专家
  6. java gson json_Java利用gson处理json字符串
  7. python爬取数据库数据类型_python中从搭建Mysql平台到爬取数据一站式全部完成
  8. rac san+oracle_Oracle RAC安装部署之规划(一)
  9. 记在windows上MySQL8.0安装过程中遇到的问题及解决方案
  10. python 列表相关应用大全