近期有个项目的业务场景是要获取包含当前月份在内的近三个月的数据,后台要求传入的数值是:
["2021-03", "2021-02", "2021-01"]
注释:月份是从当前让往后推。
然后,我写了一个函数获取近三个月的数据,代码如下:
function date(num) {
console.log(num);
const dd = new Date();
dd.setMonth(dd.getMonth() - num);
const y = dd.getFullYear();
const m =
dd.getMonth() + 1 < 10
? '0' + (dd.getMonth() + 1)
: dd.getMonth() + 1;
return y + '-' + m;
}
const arr = [];
for (let i = 0; i < 3; i++) {
arr.push(date(i));
}
console.log(arr);// ["2021-03", "2021-03", "2021-01"]
得到数据是:["2021-03", "2021-03", "2021-01"],居然出现了两个3月,没有2月。
经过查找文档分析,我开发的这一天是2021-03-31,也就是写这片博客的这一天。
dd.setMonth("01")为2月,然而2月份没有31天自动向后进一个月,最终日期为3月1日。因此当循环传入1的时候,得到的日期是2021-02-31,由于2月份没有31号这一天,因此会选择向后进一个月,最终得到是2021-03-01,因此获得月份就是3月,无法得到2月份。
那么,如何去规避setMonth这个bug呢?
可以使用setDate()这个方法,这个方法是设置一个月的某一天,可以从在 const dd = new Date();之后设置dd.setDate(1),也就是先把每个月份日期设置为从每月的第一天开始。具体代码如下:
function date(num) {
console.log(num);
const dd = new Date();
dd.setDate(1);
dd.setMonth(dd.getMonth() - num);
const y = dd.getFullYear();
const m =
dd.getMonth() + 1 < 10
? '0' + (dd.getMonth() + 1)
: dd.getMonth() + 1;
return y + '-' + m;
}
const arr = [];
for (let i = 0; i < 3; i++) {
arr.push(date(i));
}
console.log(arr);//["2021-03", "2021-02", "2021-01"]
最后附上一个函数,大家去慢慢品,或许有用:
function initLastMonth(date) {
const now = new Date(date);
now.setDate(1)
now.setMonth(now.getMonth() - 1)
console.log(now.toLocaleString())
return now
}
initLastMonth("2018-10-31")
// 2018/9/1 上午8:00:00