按当前日期过滤JSON数组并按开始日期排序时过滤无结果的问题
过滤逻辑失效的核心问题
- 隐式类型转换引发的比较失效:JS在执行
<=这类关系运算时,会将Date对象通过valueOf()方法转为数字类型的时间戳;当比较另一侧是时间格式字符串时,JS会强制将字符串转为数字完成比较。但2021-01-01T18:24:18.790+08:00这类带时区的ISO时间字符串,无法通过Number()直接解析为有效数字,转换结果为NaN。所有和NaN参与的关系比较结果恒为false,导致filter回调永远不返回匹配值,最终筛选结果为空。 - 过滤条件与业务逻辑不匹配:原代码判断
item.start_date <= dateNow && item.end_date <= dateNow,匹配的是“开始时间早于当前、且结束时间也早于当前”的完全过期条目。如果业务目标是筛选当前仍在生效期的时间区间,正确逻辑应该是当前时间落在start和end的闭区间内,即startDate <= 当前时间 <= endDate。此外你提供的测试样例中,两个条目的end_date(2020年)都早于自身的start_date(2021年),属于异常数据,即使逻辑修正也无法通过有效区间的判断。
正确的实现方式
// 初始化当前时间Date实例 const dateNow = new Date(); const filteredJson = ufjson .filter(item => { // 手动将字符串格式时间转为Date对象,规避隐式转换问题 const startDate = new Date(item.start_date); const endDate = new Date(item.end_date); // 按“当前时间在有效区间内”的规则过滤,可根据实际业务调整判断条件 return startDate <= dateNow && endDate >= dateNow; }) // 过滤完成后按start_date升序排序 .sort((a, b) => { // 转换为时间戳比较大小,避免字符串格式差异影响排序 return new Date(a.start_date).getTime() - new Date(b.start_date).getTime(); });
实现说明:
- 所有涉及时间比较的环节,都手动将字符串格式的时间转为Date实例,完全规避不可控的隐式类型转换,从根源上解决NaN导致的比较失效问题。
- 排序环节通过两个时间的时间戳差值确定先后顺序,不受字符串格式影响;当前实现为按start_date从早到晚升序排列,如需降序只需调换两个比较对象的计算顺序。
- 如果业务确实需要筛选完全过期的条目,仅需将filter中的判断条件调整为
startDate <= dateNow && endDate <= dateNow即可,手动转Date的核心修正逻辑不要改动。
内容的提问来源于stack exchange,提问作者Qr1ea1
相关产品推荐
相关产品推荐

