Array.some()满足匹配条件却始终返回false的问题排查
为啥你的日期匹配总是返回false?问题分析和解决办法
嘿,我一眼就看出问题出在哪了——时区差异和日期字符串格式不规范在搞鬼!
先看你第一版代码的问题:
- 当你用
new Date('2020-06-29')这种ISO格式字符串创建日期时,JS默认会把它解析成UTC时区的午夜0点。 - 但
new Date(2020, 5, 29)(提醒下,JS的月份是从0开始的,5对应6月哦)创建的是你本地时区的午夜0点。 - 这两个时间的时间戳(
getTime()返回的数值)肯定不一样啊,所以some方法自然返回false了。
再看你优化后的代码:
你尝试转成字符串再重新创建日期,但这里踩了个小坑——你生成的日期字符串是'2020-6-29',月份是单数字,这种非标准的ISO格式在不同JS环境里解析规则可能不一样,有的还是会出现时区问题,导致时间戳依然不匹配。
给你两个靠谱的解决办法:
方法1:统一用UTC时间创建所有日期
不管是解析字符串还是手动创建目标日期,都用UTC相关的方法,彻底规避时区差异:
let dates = ['2020-06-29', '2020-07-13']; // 把字符串日期转成UTC时间对象 dates = dates.map(dateStr => { const [year, month, day] = dateStr.split('-').map(Number); return new Date(Date.UTC(year, month - 1, day)); }); // 创建UTC时区的目标日期 const someDay = new Date(Date.UTC(2020, 5, 29)); console.log(dates.some(day => day.getTime() === someDay.getTime())); // 这下会输出true啦
方法2:直接比较标准日期字符串(更简单!)
既然时间戳的问题都是时区闹的,那我们干脆跳过时间戳,直接比较日期的纯日期字符串:
let dates = ['2020-06-29', '2020-07-13']; // 把数组里的日期转成YYYY-MM-DD格式的标准字符串 dates = dates.map(dateStr => new Date(dateStr).toISOString().split('T')[0]); // 把目标日期也转成同样格式的字符串 const someDay = new Date(2020, 5, 29).toISOString().split('T')[0]; console.log(dates.some(day => day === someDay)); // 输出true
toISOString()会把日期转成UTC的标准ISO格式字符串,截取T之前的部分就是纯粹的日期,不管创建时的时区是什么,最终的字符串格式都是统一的,完美避免时区问题。
最后补个小技巧:如果以后要手动构造YYYY-MM-DD字符串,记得给月份和日期补零,比如用String(month).padStart(2, '0'),确保是两位数字,避免解析出问题。
内容的提问来源于stack exchange,提问作者Ambitions
相关产品推荐
相关产品推荐

