JavaScript/AppsScript while循环生成日期数组首个元素覆盖问题
连续日期数组生成异常问题
需求与异常现象
- 目标任务:生成指定时间范围内的连续日期数组,测试区间为2月9日至2月13日,预期输出为
[Feb 9, Feb 10, Feb 11, Feb 12, Feb 13] - 前置已知经验:参考历史技术分享了解到,生成日期数组时每次迭代需要创建新的Date对象,避免出现数组所有元素最终被覆盖为最后一个日期的常见问题
- 实际异常:最终输出结果为
[Feb 10, Feb 11, Feb 12, Feb 13, Feb 13],通过在while循环内每次push后打印数组状态排查,确认异常为首个推入数组的元素被持续覆盖,每次push后的数组状态为:
运行截图可直观复现上述打印的状态异常。[Feb 09] [Feb 10, Feb 10] [Feb 10, Feb 11, Feb 11] [Feb 10, Feb 11, Feb 12, Feb 12] [Feb 10, Feb 11, Feb 12, Feb 13, Feb 13]
现存问题代码
var Current_Date = new Date(Date_start) // 初始值为2月9日 Current_Date = new Date(Current_Date.setHours(Current_Date.getHours() - 24)); // 偏移为2月8日 var Billing_Dates = [] while (Current_Date.valueOf() <= Date_end.valueOf()) { Current_Date = new Date(Current_Date.setHours(Current_Date.getHours() + 24)); Billing_Dates.push(Current_Date); Logger.log(Billing_Dates) }
问题根因
Date 对象的 setHours() 是典型的原地修改方法,调用后会直接改动当前对象本身存储的时间值,并不会生成全新的独立对象。
循环的执行逻辑刚好触发了引用共享的问题:
- 每轮循环启动时,
Current_Date指向的 Date 实例,就是上一轮刚被 push 进Billing_Dates数组的元素 - 执行
Current_Date.setHours(Current_Date.getHours() + 24)时,直接对已经存在数组里的对象做了修改,把它的时间值推到了下一天 - 之后再用修改后的时间戳新建一个 Date 实例赋值给
Current_Date,push 进数组
这就导致每轮循环都会顺手改掉上一轮存进数组的元素,最终出现元素被持续覆盖、相邻值重复的异常输出。
修正方案
调整循环内的时间计算逻辑,避免在已经被数组引用的Date对象上调用原地修改方法,直接基于纯时间戳做算术偏移,再新建独立的Date对象:
var Billing_Dates = [] // 初始偏移到区间开始的前一天,存储纯时间戳值 let currentTime = Date_start.getTime() - 24 * 60 * 60 * 1000 const endTime = Date_end.getTime() while (currentTime <= endTime) { currentTime += 24 * 60 * 60 * 1000 // 基于独立的时间戳新建Date实例,不会和数组内已存的对象产生引用关联 Billing_Dates.push(new Date(currentTime)) Logger.log(Billing_Dates) }
修正后可正常输出预期的连续日期数组,不会出现元素互相覆盖的问题。
内容的提问来源于stack exchange,提问作者business
相关产品推荐
相关产品推荐

