需求及实现思路
为设置周报对应周数,以周五为重点时间节点来划分周数。即周五在哪一年,这周就算哪一年的
重点实现思路为:当年第一周大于等于三天即从上一年补足七天,小于三天则该周从本年删除、计入上一年;最后一周大于等于五天即从下一年补足七天,小于五天则该周从本年删除、计入下一年; 依据自然周计算,不考虑法定节假日等其他因素,效果如下:
运行效果
1.工具函数中间状态
2.最终返回结果
完整源码
/**
* 获取指定年度的全部周数及每周对应日期范围
* @param year 指定年份
* @remark 第一周大于等于三天即从上一年补足七天,小于三天则该周从本年删除、计入上一年;最后一周大于等于五天即从下一年补足七天,小于五天则该周从本年删除、计入下一年
* @remark 依据自然周计算,不考虑法定节假日等其他因素
*/
export function getWeekDates(year: number) {
let days = getDay(year || new Date().getFullYear());
let weeks = [];
for (let i = 0; i < days.length; i++) {
let daySplit = days[i].split('_');
if (weeks.length === 0) {
// 创建新一周[]
weeks.push([`${year}/${daySplit[0]}`]);
} else {
if (daySplit[1] == '1') {
// 创建新一周[]
weeks.push([`${year}/${daySplit[0]}`]);
} else {
// 加入已有但未满七天的一周
weeks[weeks.length - 1].push(`${year}/${daySplit[0]}`);
}
}
}
// 最后一周逻辑处理
if (weeks[weeks.length - 1].length < 5) {
// 最后一周不到周五,删除
weeks.pop();
} else if (weeks[weeks.length - 1].length > 4 && weeks[weeks.length - 1].length < 7) {
// 最后一周包括周五但不到周日,从下一年补足一周
let nextYear = year + 1;
let nextWeek = [`${nextYear}/01/01`, `${nextYear}/01/02`];
const needDays = 7 - weeks[weeks.length - 1].length;
for (let i = 0; i < needDays; i++) {
weeks[weeks.length - 1].push(nextWeek[i]);
}
}
// 第一周逻辑处理
if (weeks[0].length < 3) {
// 第一周不满三天即删除(即只有周六周日两天,计入上一年最后一周)
weeks.shift();
} else if (weeks[0].length > 2 && weeks[0].length < 7) {
// 第一周大于等于三天但不满七天,从前一年补足一周
let lastYear = year - 1;
let lastWeek = [`${lastYear}/12/31`, `${lastYear}/12/30`, `${lastYear}/12/29`, `${lastYear}/12/28`];
const needDays = 7 - weeks[0].length;
for (let i = 0; i < needDays; i++) {
weeks[0].unshift(lastWeek[i]);
}
}
console.log('weeks', weeks);
let option = [];
for (let i = 0; i < weeks.length; i++) {
let obj: { [key: string]: any } = {};
obj.year = year;
obj.week = '第' + (i + 1) + '周';
obj.md = weeks[i][0] + '-' + weeks[i][weeks[i].length - 1];
obj.start = weeks[i][0];
obj.end = weeks[i][weeks[i].length - 1];
obj.text = '第' + (i + 1) + '周' + '(' + weeks[i][0] + '-' + weeks[i][weeks[i].length - 1] + ')';
obj.value = i + 1;
option.push(obj);
}
console.log('option', option);
return option;
}
function getDay(year: number) {
let dates = [];
for (let i = 1; i <= 12; i++) {
for (let j = 1; j <= new Date(year, i, 0).getDate(); j++) {
dates.push(formatNumber(i) + '/' + formatNumber(j) + '_' + new Date([year, formatNumber(i), formatNumber(j)].join('-')).getDay()); //返回当年所有日期(带星期数)
}
}
return dates;
}
function formatNumber(n: number) {
return n.toString().length > 1 ? n : '0' + n;
}
代码还有很大优化空间,欢迎补充建议!