Angular中Moment.js日期处理异常:TO日期修改重置FROM日期致差值错误
Angular中Moment.js日期显示与计算异常问题
问题现象
- 初始状态:FROM和TO日期均默认设为03/2023
- 异常表现:修改FROM日期后可正常更新为目标值(如01/2000);但修改TO日期时,TO日期更新为目标值(如01/2005)的同时,FROM日期会被重置为默认的03/2023,导致日期月份差值计算错误,甚至出现负数
相关代码
// called when FROM date is changed getBeginMthYr(bDate: Moment) { this.selBeginDate = bDate; this.selectedDates = []; this.selectedDates.push(this.convertDateString(this.selBeginDate, this.selEndDate)); } // called when TO date is changed getEndMthYr(endDate: Moment) { this.selEndDate = endDate; this.selectedDates = []; this.selectedDates.push(this.convertDateString(this.selBeginDate, this.selEndDate)); } convertDateString(beginDate: Moment, endDate: Moment) { let dmths = endDate.diff(beginDate, 'months'); let i: number; let dateStr: string = ''; if (this.validRangeDate) { dateStr = beginDate.format('YYYYM'); for (i = 0; i < dmths; i++) { let stepDate = beginDate.add(1, 'M'); dateStr = dateStr + ',' + stepDate.format('YYYYM'); } } return dateStr; } validRangeDate(beginDate: Moment, endDate: Moment): boolean { if (endDate.diff(beginDate, 'months') < 0) { return false; } else { return true; } }
问题根源
Moment.js的add()方法是原地修改调用它的Moment对象,而非返回新对象。在convertDateString函数的循环中,beginDate.add(1, 'M')直接修改了传入的selBeginDate引用对象,导致组件中保存的起始日期被篡改,最终出现FROM日期被重置的异常。
同时,原代码中if (this.validRangeDate)的判断逻辑错误,它只是检查函数是否存在,而非调用函数验证日期范围。
修复方案
1. 修复convertDateString函数(避免原地修改原日期对象)
convertDateString(beginDate: Moment, endDate: Moment) { let dmths = endDate.diff(beginDate, 'months'); let dateStr: string = ''; // 克隆起始日期,操作副本而非原对象 let currentDate = beginDate.clone(); // 正确调用日期范围验证函数 if (this.validRangeDate(beginDate, endDate)) { dateStr = currentDate.format('YYYYM'); for (let i = 0; i < dmths; i++) { currentDate.add(1, 'M'); dateStr += ',' + currentDate.format('YYYYM'); } } return dateStr; }
2. 关键说明
- 使用
clone()方法创建Moment对象的副本,所有日期操作都在副本上进行,避免修改原对象导致的状态异常 - 修正日期范围验证的调用逻辑,确保只有当日期范围有效时才生成日期字符串
内容的提问来源于stack exchange,提问作者user1015388
相关产品推荐
相关产品推荐

