如何用JavaScript在时间范围内迭代,为对象字段生成YYYY-mm-dd格式每日数据?
解决JavaScript在时间范围内迭代生成每日格式化数据的问题
我来帮你排查下代码里的问题,然后给你一个靠谱的实现方案~
先说说你原代码里的几个小坑:
- 月份参数是0起始的:
Date构造函数的第二个参数(月份)是从0开始计数的,所以你写的new Date(2018, 03, 28)实际对应的是2018年4月28日,如果要表示3月的话得写成02,这是很容易踩的坑! - 循环中类型不匹配:你把
loop转换成了字符串(toISOString().substring(0,10)),之后再和end(Date对象)做loop <= end的比较,字符串和Date对象的比较逻辑完全不符合预期,会导致循环要么提前终止要么无限循环。 - 没有保存结果:你调用了
index(loop)但没把返回的对象存下来,相当于白忙活了一场~ - 变量声明不严谨:循环里用
var newDate会有变量提升的问题,建议换成let或者const。
修正后的完整实现
这里我把代码拆分成更清晰的函数,同时解决时区和类型问题:
// 手动格式化本地日期为YYYY-mm-dd(避免时区影响) const formatLocalDate = (date) => { const year = date.getFullYear(); // 月份要+1,因为Date的月份是0-based,再补前导0 const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; }; // 生成你需要的格式对象 const createTimeIndexObj = (formattedDate) => { return { index: `time-${formattedDate}` }; }; // 注意:月份参数是0-based,2018年3月28日对应第二个参数为02 const startDate = new Date(2018, 02, 28); const endDate = new Date(2019, 02, 28); // 用来存储所有生成的对象 const dailyDataList = []; // 初始化循环用的日期,拷贝startDate避免修改原对象 let currentDate = new Date(startDate); while (currentDate <= endDate) { // 先格式化当前日期 const formattedDate = formatLocalDate(currentDate); // 生成对象并加入结果数组 dailyDataList.push(createTimeIndexObj(formattedDate)); // 将日期往后推一天,直接操作Date对象即可 currentDate.setDate(currentDate.getDate() + 1); } // 打印结果看看 console.log(dailyDataList);
额外说明:为什么不用toISOString?
如果直接用date.toISOString().substring(0,10),会把本地时间转换成UTC时间。比如你的本地时区是东八区,当本地时间是2018-03-28 00:00时,UTC时间是2018-03-27 16:00,这样格式化出来的日期就会变成2018-03-27,完全不符合预期。所以手动拼接本地日期的方式更可靠。
内容的提问来源于stack exchange,提问作者Palaniichuk Dmytro
相关产品推荐
相关产品推荐

