JavaScript中Filter函数无法过滤11月、12月Date对象的问题排查
夏令时切换导致日期过滤失效问题解决
问题场景
使用以下代码从saturdays数组中移除excludedDates包含的日期时,多数情况正常,但11月、12月的目标日期无法被过滤,仍保留在结果数组中:
const newSaturdays = this.saturdays.filter(date => !excludedDates.find(ex => ex.getTime() === date.getTime()));
示例测试数据:
saturdays = [new Date('2022-09-10'), new Date('2022-09-17'), new Date('2022-10-01'), new Date('2022-10-08'), new Date('2022-10-15'), new Date('2022-10-22'), new Date('2022-10-29'), new Date('2022-11-05'), new Date('2022-11-12'), new Date('2022-11-19'), new Date('2022-11-26'), new Date('2022-12-03'), new Date('2022-12-10'), new Date('2022-12-17')] excludedDates = [new Date('2022-09-24'), new Date('2022-10-15'), new Date('2022-10-22'), new Date('2022-10-29'), new Date('2022-11-19'), new Date('2022-12-17')]
问题原因
10月底英国地区夏令时切换为UTC时区,导致getTime()返回的时间戳出现偏差:Date对象在本地时区与UTC时区转换时,夏令时切换会让同一天的日期对象产生不同的时间戳,原本应该匹配的日期,getTime()结果不相等,直接导致过滤逻辑失效。
解决方案
方案1:统一比较UTC日期组件
通过getUTCFullYear()、getUTCMonth()、getUTCDate()获取UTC标准下的年、月、日进行比较,彻底规避时区/夏令时影响:
const newSaturdays = this.saturdays.filter(date => { return !excludedDates.some(ex => ex.getUTCFullYear() === date.getUTCFullYear() && ex.getUTCMonth() === date.getUTCMonth() && ex.getUTCDate() === date.getUTCDate() ); });
方案2:转换为ISO日期字符串(高效版)
先将excludedDates转换为仅包含年月日的ISO字符串集合,再进行查找,同时提升大数组下的查询效率:
const excludedDateSet = new Set(excludedDates.map(d => d.toISOString().split('T')[0])); const newSaturdays = this.saturdays.filter(d => !excludedDateSet.has(d.toISOString().split('T')[0]));
方案3:本地时区日期比较(适配单一时区场景)
如果所有日期都在同一本地时区处理,也可以直接使用getFullYear()、getMonth()、getDate()进行比较,和你提到的改用getDate()思路一致:
const newSaturdays = this.saturdays.filter(date => { return !excludedDates.some(ex => ex.getFullYear() === date.getFullYear() && ex.getMonth() === date.getMonth() && ex.getDate() === date.getDate() ); });
内容的提问来源于stack exchange,提问作者Chris Wheatland
相关产品推荐
相关产品推荐

