具体可实现的效果例如:
数据格式:
具体代码实现:
/**
* 获取当前日期的第一个周一是哪天
* @params date - 'YYYY-MM'
*/
function getMonthFirstWeekDay(date) {
let year = new Date(date).getFullYear();
let month = new Date(date).getMonth();
for (let week = 1; week < 8; week++) {
if (new Date(`${year}-${month + 1}-${week}`).getDay() === 1) {
return week;
}
}
}
/**
* 获取start日期到end日期的周集合
* @params start - 'YYYY-MM'
* @params end - 'YYYY-MM'
*/
function getAllWeeks(start, end) {
if (!start) return [];
// 结束日期
try {
let endDate = end ? new Date(end) : new Date();
let endYear = endDate.getFullYear();
let endMonth = endDate.getMonth() + 2;
if (endMonth > 11) {
endMonth = "1";
endYear++;
}
end = `${endYear}-${endMonth}`;
const weeks = []; // 周数组
let firstWeek = getMonthFirstWeekDay(start); // 周几
let firstDate = `${start}-${firstWeek}`; // 第一周日期
let endTimestamp = new Date(end).getTime(); // 不超过最后月份时间戳
let prevTimestamp = new Date(firstDate).getTime(); // 第一周时间戳
let oneDay = 24 * 60 * 60 * 1000; // 一天的时间戳偏移量
while (prevTimestamp < endTimestamp) {
let prevDate = new Date(prevTimestamp);
let nextDate = new Date(prevTimestamp + oneDay * 6);
let prevY = prevDate.getFullYear();
let prevM = prevDate.getMonth() + 1;
let prevD = prevDate.getDate();
let nextY = nextDate.getFullYear();
let nextM = nextDate.getMonth() + 1;
let nextD = nextDate.getDate();
weeks.push([
{
year: prevY,
month: prevM,
day: prevD,
ymd: `${prevY}-${prevM}-${prevD}`,
ym: `${prevY}-${prevM}`,
md: `${prevM}-${prevD}`,
},
{
year: nextY,
month: nextM,
day: nextD,
ymd: `${nextY}-${nextM}-${nextD}`,
ym: `${nextY}-${nextM}`,
md: `${nextM}-${nextD}`,
},
]);
prevTimestamp += oneDay * 7;
}
return weeks;
} catch (error) {
return [];
}
}
// 使用示例
// 全部周
const weeks = getAllWeeks("2023-12", "2024-01");
console.log("weeks:", weeks);
// 按月分组
const weeksByMonth = Object.groupBy(weeks, (op) => op[0].ym);
console.log("weeksByMonth:", weeksByMonth);
// 按年分组
const weeksByYear = Object.groupBy(weeks, (op) => op[0].year);
console.log("weeksByYear:", weeksByYear);
需求简要描述一下吧
就是获取某个时间范围内,生成月报周报,第一个周报为时间范围当月的第一周,跨周则依然归属于当月,跨周的下个周一才归属下个月。生成这样的周报月报下拉选项。