使用RxJS、Moment.js与Akita筛选近30天数据异常求助
问题分析与解决
你遇到的问题根源在于将日期转换为字符串后进行比较——字符串的比较是按字符顺序逐位判断的,这和日期的时间逻辑完全不匹配,导致筛选结果完全相反。
举个简单的例子:假设今天是2024-10-01,30天前是2024-09-01。如果有一条数据的日期是2024-09-30,转成字符串是"30-09-2024",30天前的日期字符串是"01-09-2024"。字符串比较时"30..."会被判定为大于"01...",但实际上这个日期确实在近30天内;但如果有一条日期为2024-08-31的数据,字符串是"31-08-2024",和"01-09-2024"比较时"31..."也会被判定为更大,但这个日期其实已经超出30天范围了。
正确的实现方式
你应该直接比较moment对象的时间逻辑,而不是字符串。这里提供两种可靠的写法:
方法1:比较时间戳(valueOf)
qtLastMonth(): Observable<Data[]> { // 获取30天前的时间戳(毫秒数) const thirtyDaysAgoTimestamp = moment().subtract(30, "days").valueOf(); return this.selectAll().pipe( map((allDatas) => allDatas.filter(data => moment(data.date).valueOf() > thirtyDaysAgoTimestamp) ) ) }
方法2:使用moment的isAfter方法(更直观)
qtLastMonth(): Observable<Data[]> { const thirtyDaysAgo = moment().subtract(30, "days"); return this.selectAll().pipe( map((allDatas) => allDatas.filter(data => moment(data.date).isAfter(thirtyDaysAgo)) ) ) }
额外建议
如果你的data.date格式不是moment默认能解析的格式,建议在创建moment对象时明确指定格式,避免解析错误:
moment(data.date, 'DD-MM-YYYY') // 替换成你的日期实际格式
内容的提问来源于stack exchange,提问作者Boubou
相关产品推荐
相关产品推荐

