Procházet zdrojové kódy

Refactor date handling in StatsDashboardPage to utilize natural week definitions

- Updated date range calculations to use natural week definitions instead of ISO weeks, ensuring consistency in weekly report generation.
- Enhanced week date range formatting to reflect the new natural week logic, improving clarity in date representations.
- Added necessary Day.js plugins for week of year and week year support to facilitate these changes.
0es před 3 týdny
rodič
revize
18871dc358

+ 9 - 10
src/app/(dashboard)/statistics/dashboard/page.tsx

@@ -59,7 +59,7 @@ function getDefaultRange(type: number): [Dayjs, Dayjs] {
     case 2: // 月报:过去 6 个月
       return [today.subtract(5, "month").startOf("month"), today];
     default: // 周报:过去 8 周
-      return [today.subtract(7, "week").startOf("isoWeek"), today];
+      return [today.subtract(7, "week").startOf("week"), today];
   }
 }
 
@@ -78,10 +78,10 @@ function generatePeriodIds(start: Dayjs, end: Dayjs, type: number): string[] {
       cur = cur.add(1, "day");
     }
   } else if (type === 1) {
-    let cur = start.startOf("isoWeek");
+    let cur = start.startOf("week");
     while (!cur.isAfter(end)) {
-      const week = cur.isoWeek();
-      const year = cur.isoWeekYear();
+      const week = cur.week();
+      const year = cur.weekYear();
       ids.push(`${year}-W${String(week).padStart(2, "0")}`);
       cur = cur.add(1, "week");
     }
@@ -163,7 +163,7 @@ function fillPlaymateData(
 }
 
 /**
- * Given an ISO week ID like "2026-W10", returns the Sun–Sat date range string.
+ * Given a natural-week ID like "2026-W10", returns the Sun–Sat date range string.
  * Returns null for non-week IDs.
  */
 function getWeekDateRange(id: string): string | null {
@@ -171,11 +171,10 @@ function getWeekDateRange(id: string): string | null {
   if (!match) return null;
   const year = Number(match[1]);
   const week = Number(match[2]);
-  const jan4 = dayjs(`${year}-01-04`);
-  const week1Monday = jan4.subtract(jan4.isoWeekday() - 1, "day");
-  const monday = week1Monday.add((week - 1) * 7, "day");
-  // Natural week: Sunday (one day before ISO Monday) ~ Saturday
-  const sunday = monday.subtract(1, "day");
+  // Natural week: week 1 starts on the Sunday of the week containing Jan 1
+  const sunday = dayjs(`${year}-01-01`)
+    .startOf("week")
+    .add((week - 1) * 7, "day");
   const saturday = sunday.add(6, "day");
   return `${sunday.format("YYYY-MM-DD")} ~ ${saturday.format("YYYY-MM-DD")}`;
 }

+ 5 - 1
src/utils/dayjs.ts

@@ -2,11 +2,15 @@ import dayjs from "dayjs";
 import isoWeek from "dayjs/plugin/isoWeek";
 import timezone from "dayjs/plugin/timezone";
 import utc from "dayjs/plugin/utc";
+import weekOfYear from "dayjs/plugin/weekOfYear";
+import weekYear from "dayjs/plugin/weekYear";
 
-// Enable UTC, timezone, and ISO week support
+// Enable UTC, timezone, ISO week, and locale week support
 dayjs.extend(utc);
 dayjs.extend(timezone);
 dayjs.extend(isoWeek);
+dayjs.extend(weekOfYear);
+dayjs.extend(weekYear);
 
 // Set default timezone to Indonesia (GMT+7)
 dayjs.tz.setDefault("Asia/Jakarta");