From 50f7f131ea12378d01df19e4cb77d34627157060 Mon Sep 17 00:00:00 2001 From: Wen Sun Date: Tue, 30 Jan 2024 08:56:03 +0900 Subject: [PATCH] fix: month grouping error in timeline page (#2861) --- web/src/components/ActivityCalendar.tsx | 10 ++++++---- web/src/helpers/datetime.ts | 12 ++++++++++++ web/src/pages/Timeline.tsx | 4 ++-- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/web/src/components/ActivityCalendar.tsx b/web/src/components/ActivityCalendar.tsx index e22f0a1a..feb03040 100644 --- a/web/src/components/ActivityCalendar.tsx +++ b/web/src/components/ActivityCalendar.tsx @@ -1,6 +1,6 @@ import { Tooltip } from "@mui/joy"; import classNames from "classnames"; -import { getNormalizedDateString } from "@/helpers/datetime"; +import { getNormalizedDateString, getDateWithOffset } from "@/helpers/datetime"; interface Props { // Format: 2021-1 @@ -26,8 +26,8 @@ const getCellAdditionalStyles = (count: number, maxCount: number) => { const ActivityCalendar = (props: Props) => { const { month: monthStr, data, onClick } = props; - const year = new Date(monthStr).getFullYear(); - const month = new Date(monthStr).getMonth() + 1; + const year = new Date(monthStr).getUTCFullYear(); + const month = new Date(monthStr).getUTCMonth() + 1; const dayInMonth = new Date(year, month, 0).getDate(); const firstDay = new Date(year, month - 1, 1).getDay(); const lastDay = new Date(year, month - 1, dayInMonth).getDay(); @@ -47,7 +47,9 @@ const ActivityCalendar = (props: Props) => { return (
{days.map((day, index) => { - const date = getNormalizedDateString(`${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`); + const date = getNormalizedDateString( + getDateWithOffset(`${year}-${String(month).padStart(2, "0")}-${String(day).padStart(2, "0")}`), + ); const count = data[date] || 0; const isToday = new Date().toDateString() === new Date(date).toDateString(); const tooltipText = count ? `${count} memos in ${date}` : date; diff --git a/web/src/helpers/datetime.ts b/web/src/helpers/datetime.ts index 576d08c9..54d57158 100644 --- a/web/src/helpers/datetime.ts +++ b/web/src/helpers/datetime.ts @@ -169,3 +169,15 @@ export function isFutureDate(t?: Date | number | string): boolean { const timestamp = getTimeStampByDate(t ? t : Date.now()); return timestamp > Date.now(); } + +/** + * Calculates a new Date object by adjusting the provided date, timestamp, or date string + * based on the current timezone offset. + * + * @param t - The input date, timestamp, or date string (optional). If not provided, + * the current date and time will be used. + * @returns A new Date object adjusted by the current timezone offset. + */ +export function getDateWithOffset(t?: Date | number | string): Date { + return new Date(getTimeStampByDate(t) + new Date().getTimezoneOffset() * 60 * 1000); +} diff --git a/web/src/pages/Timeline.tsx b/web/src/pages/Timeline.tsx index 2f344905..d5868456 100644 --- a/web/src/pages/Timeline.tsx +++ b/web/src/pages/Timeline.tsx @@ -148,9 +148,9 @@ const Timeline = () => {
- {new Date(group.month).toLocaleString(i18n.language, { month: "short" })} + {new Date(group.month).toLocaleString(i18n.language, { month: "short", timeZone: "UTC" })} - {new Date(group.month).getFullYear()} + {new Date(group.month).getUTCFullYear()} Total: {sum(Object.values(group.data))}
setSelectedDay(date)} />