JavaScript Date getTime()方法行为不一致返回值异常问题
问题根因
代码中存在5个核心错误,共同导致时间比较异常:
- 月份参数不符合JS Date规则:JS的
Date构造函数接收的月份参数为0索引(0代表1月,11代表12月),代码直接将字符串解析出的1-12格式月份传入,会导致月份偏移1个月 - 使用了已废弃的API:
getYear()/setYear()是早已废弃的方法,getYear()返回值为当前年份减1900(比如2020年返回120),传入setYear()后会生成完全错误的日期,这是控制台出现离谱数值、负数时间戳的核心原因 - 全局基准对象被污染:代码在filter循环中反复修改外部定义的
beginningTimeValue对象,每处理一行数据就会篡改一次基准时间,后续循环使用的基准值已经完全不符合预期 - 判断逻辑错误:
!beginningTimeValue == ""写法存在逻辑漏洞,!运算符会先将Date对象转为布尔值取反(结果恒为false),根本无法实现非空校验的效果 - 日志计算错误:
getTime()本身已经返回毫秒级时间戳,代码额外给返回值乘了24*3600*1000的系数,将数值放大了8640万倍,进一步放大了数值异常的表现
修正方案
核心思路是固定基准时分秒,循环内为每条记录单独生成当日的基准对比时间,不共享可变Date对象,修正API使用和参数错误,修正后的可运行代码如下:
// 定义要过滤的小时基准:每天8点0分0秒 const BASE_HOUR = 8; const BASE_MINUTE = 0; const BASE_SECOND = 0; const unique = [ ["value","value","value","value","12/01/2021 00:03:35","value"], ["value","value","value","value","01/01/2020 00:03:35","value"], ["value","value","value","value","01/01/2020 08:03:35","value"], ["value","value","value","value","01/01/2020 13:03:35","value"] ]; const filteredResult = unique.filter((row) => { const timeStr = row[4]; // 解析DD/MM/YYYY HH:mm:ss格式的时间字符串 const year = parseInt(timeStr.substring(6, 10), 10); // 注意:月份参数传Date构造函数时要减1,匹配0索引规则 const month = parseInt(timeStr.substring(3, 5), 10) - 1; const day = parseInt(timeStr.substring(0, 2), 10); const hour = parseInt(timeStr.substring(11, 13), 10); const minute = parseInt(timeStr.substring(14, 16), 10); const second = parseInt(timeStr.substring(17, 19), 10); // 生成当前记录的时间对象 const recordTime = new Date(year, month, day, hour, minute, second); // 单独生成当日8点的基准时间对象,每次循环新建实例不污染外部变量 const dayBaseTime = new Date(year, month, day, BASE_HOUR, BASE_MINUTE, BASE_SECOND); // 毫秒时间戳可直接比较,无需额外换算 return recordTime.getTime() >= dayBaseTime.getTime(); }); console.log(filteredResult);
运行后会正确过滤掉两条0点03分的记录,保留8点03分、13点03分的两条记录,符合按小时过滤的需求。
修正点说明
- 替换废弃API:全部使用
getFullYear()/setFullYear()处理年份,避免年份计算错误 - 修正月份偏移:传入Date构造函数的月份值统一减1,匹配JS原生API的参数规则
- 隔离可变对象:循环内每次新建基准时间实例,不修改外部共享变量,避免循环间数据污染
- 移除冗余计算:去掉时间戳的多余乘法运算,毫秒时间戳可以直接比较大小
- 简化判断逻辑:去掉错误的非空判断写法,可根据实际业务场景补充基准值校验
内容的提问来源于stack exchange,提问作者Rus Paul Adrian
相关产品推荐
相关产品推荐

