工作周计算BUG修复
This commit is contained in:
parent
1aadf8cd2e
commit
14b2bc40ad
|
|
@ -87,15 +87,53 @@ function getWeekEndDate(weekStartDate) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 ISO 周编号 (YYYY-Www)
|
* 获取 ISO 周编号 (YYYY-Www)
|
||||||
|
* 遵循 ISO 8601 标准:每周从周一开始,第一个包含1月4日的周是W1
|
||||||
*/
|
*/
|
||||||
function getWeekNumber(dateStr) {
|
function getWeekNumber(dateStr) {
|
||||||
const date = new Date(dateStr);
|
const date = new Date(dateStr);
|
||||||
// ISO 周码:每年的第一个周四所在的周为第1周
|
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
|
// 找到该日期所在周的周四(ISO 8601 以包含1月4日的周为W1)
|
||||||
const thursday = new Date(date);
|
const thursday = new Date(date);
|
||||||
thursday.setDate(date.getDate() + (4 - (date.getDay() === 0 ? 7 : date.getDay())));
|
thursday.setDate(date.getDate() + (4 - (date.getDay() === 0 ? 7 : date.getDay())));
|
||||||
|
|
||||||
|
// 计算该年的1月1日是周几
|
||||||
const yearStart = new Date(thursday.getFullYear(), 0, 1);
|
const yearStart = new Date(thursday.getFullYear(), 0, 1);
|
||||||
const weekNum = Math.ceil(((thursday - yearStart) / 86400000 + 1) / 7);
|
const jan1Day = yearStart.getDay(); // 0=Sun, 1=Mon, ..., 6=Sat
|
||||||
return `${thursday.getFullYear()}-W${String(weekNum).padStart(2, '0')}`;
|
|
||||||
|
// 计算这是该年的第几天(1月1日=1)
|
||||||
|
const dayOfYear = Math.floor((thursday - yearStart) / MS_PER_DAY) + 1;
|
||||||
|
|
||||||
|
// ISO 周号:(dayOfYear + 该年1月1日的星期几 - 1) / 7 向上取整
|
||||||
|
// 如果1月1日是周四(day=4),则 Jan1 就在 W01 中
|
||||||
|
// 如果1月1日是周五/周六/周日,则需要调整(这些天属于上一年最后一周)
|
||||||
|
const weekNum = Math.ceil((dayOfYear + (jan1Day === 0 ? 6 : jan1Day) - 1) / 7);
|
||||||
|
|
||||||
|
// 处理年末/年初边界情况:
|
||||||
|
// 如果计算的周号是0,说明属于上一年最后一周
|
||||||
|
// 如果周号超过该年最大周数,说明属于下一年第一周
|
||||||
|
let year = thursday.getFullYear();
|
||||||
|
let finalWeek = weekNum;
|
||||||
|
|
||||||
|
if (finalWeek === 0) {
|
||||||
|
// 上一年最后一周
|
||||||
|
year = year - 1;
|
||||||
|
const prevJan1Day = new Date(year, 0, 1).getDay();
|
||||||
|
finalWeek = prevJan1Day === 4 || (prevJan1Day === 3 && isLeapYear(year)) ? 53 : 52;
|
||||||
|
} else {
|
||||||
|
const maxWeeks = (jan1Day === 4 || (jan1Day === 3 && isLeapYear(thursday.getFullYear()))) ? 53 : 52;
|
||||||
|
if (finalWeek > maxWeeks) {
|
||||||
|
// 下一年第一周
|
||||||
|
year = year + 1;
|
||||||
|
finalWeek = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${year}-W${String(finalWeek).padStart(2, '0')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLeapYear(year) {
|
||||||
|
return (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -188,37 +226,13 @@ function getWeekStartFromWeekNumber(year, weekNum) {
|
||||||
const jan4 = new Date(year, 0, 4);
|
const jan4 = new Date(year, 0, 4);
|
||||||
const jan4Day = jan4.getDay(); // 0=Sun, 1=Mon, ..., 6=Sat
|
const jan4Day = jan4.getDay(); // 0=Sun, 1=Mon, ..., 6=Sat
|
||||||
|
|
||||||
// 找到W1的周一
|
// 找到W1的周一(ISO 8601:每年第一个包含1月4日的周是W1,该周的周一是W1起始)
|
||||||
let firstMonday;
|
// jan4Day: 0=Sun, 1=Mon, ..., 6=Sat
|
||||||
if (jan4Day === 1) {
|
// 如果1月4日是周日,W1周一是Dec 29(上周一)
|
||||||
// 1月4日是周一 -> W1周一是1月4日
|
// 如果1月4日是周一,W1周一是1月4日
|
||||||
firstMonday = jan4;
|
// 否则,W1周一是1月4日往前到周一的天数
|
||||||
} else if (jan4Day === 0) {
|
const daysToSubtract = (jan4Day === 0 ? 7 : jan4Day) - 1;
|
||||||
// 1月4日是周日 -> W1周一是上周一(12月X日)
|
const firstMonday = new Date(jan4.getTime() - daysToSubtract * MS_PER_DAY);
|
||||||
// 1月4日 - 7天 = 12月28日(上上个周一),再 -1天 = 12月29日(上周一)
|
|
||||||
firstMonday = new Date(jan4.getTime() - 7 * MS_PER_DAY);
|
|
||||||
// 但这已经是12月28了,而1月4日是周日,那上周一是12月29日
|
|
||||||
// 所以实际上 1月4日 - 8天 = 12月27... 这不对
|
|
||||||
// 让我重新想:
|
|
||||||
// 如果1月4日是周日,那这一周是 Dec 28 - Jan 3 (W1 ends Jan 3)
|
|
||||||
// 所以W1的周一是 Dec 28
|
|
||||||
// 那么 Dec 28 + 7 = Jan 4,W2从 Jan 5开始
|
|
||||||
// 所以 W1 of 2026 = Dec 28 - Jan 3
|
|
||||||
// W1 starts on Monday Dec 28
|
|
||||||
// Let me recalculate: Jan 4 - 6 = Dec 29 (that's Monday if Jan 4 is Sunday)
|
|
||||||
// Wait, if Jan 4 is Sunday, then Jan 4 - 1 = Jan 3 (Saturday)
|
|
||||||
// Jan 4 - 2 = Jan 2, ..., Jan 4 - 7 = Dec 28
|
|
||||||
// But that's 7 days back, not 6. And Dec 28 is Monday?
|
|
||||||
// Let me just use getTime()
|
|
||||||
const daysToSubtract = jan4Day === 0 ? 6 : jan4Day - 1;
|
|
||||||
firstMonday = new Date(jan4.getTime() - daysToSubtract * MS_PER_DAY);
|
|
||||||
} else {
|
|
||||||
// 1月4日是 Tue(2), Wed(3), Thu(4), Fri(5), Sat(6) -> 找到上溯到周一
|
|
||||||
// 如果1月4日是周三,那周一就是1月4日 - 2天
|
|
||||||
// daysToSubtract = 4 - 1 = 3, 1月4日 - 3天 = 1月1日 = 周一 ✓
|
|
||||||
const daysToSubtract = jan4Day - 1;
|
|
||||||
firstMonday = new Date(jan4.getTime() - daysToSubtract * MS_PER_DAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算目标周的周一
|
// 计算目标周的周一
|
||||||
const targetMonday = new Date(firstMonday.getTime() + (weekNum - 1) * 7 * MS_PER_DAY);
|
const targetMonday = new Date(firstMonday.getTime() + (weekNum - 1) * 7 * MS_PER_DAY);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue