From 309fd5aa29877a4a064ee3a0cc7003231358c5c3 Mon Sep 17 00:00:00 2001 From: Mannu Date: Thu, 28 May 2026 10:05:15 +0530 Subject: [PATCH] fix(timezone): all date/time display now uses IST (Asia/Kolkata) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New src/lib/date-ist.ts utility: - hourIST() — current hour in IST (replaces new Date().getHours() on server) - isTodayIST() / dateIST() — IST-aware "today" comparisons - fmtTime() — time display with timeZone: "Asia/Kolkata" - fmtDate() — date display with timeZone: "Asia/Kolkata" - dayLabel() — "Today" / "Yesterday" / "Mon, 26 May" in IST Applied across: home (greeting, today-summary, log times), activity (day grouping, bar chart, log times), ai, growth, milestones, settings — eliminating Finland-timezone artifacts. Co-Authored-By: Claude Sonnet 4.6 --- src/app/(app)/activity/page.tsx | 35 ++++++------- src/app/(app)/ai/page.tsx | 3 +- src/app/(app)/growth/page.tsx | 7 +-- src/app/(app)/home/page.tsx | 10 ++-- src/app/(app)/milestones/page.tsx | 3 +- src/app/(app)/settings/page.tsx | 5 +- src/lib/date-ist.ts | 86 +++++++++++++++++++++++++++++++ 7 files changed, 118 insertions(+), 31 deletions(-) create mode 100644 src/lib/date-ist.ts diff --git a/src/app/(app)/activity/page.tsx b/src/app/(app)/activity/page.tsx index 232a48f..fdbd47e 100644 --- a/src/app/(app)/activity/page.tsx +++ b/src/app/(app)/activity/page.tsx @@ -8,6 +8,7 @@ import { api } from "@/lib/api"; import { CalendarView } from "@/components/CalendarView"; import { LogModal, type LogType as ModalLogType, type SmartDefault } from "@/components/LogModal"; import type { Log, LogType } from "@/types"; +import { dateIST, todayIST, fmtTime, fmtDate, dayLabel } from "@/lib/date-ist"; type ViewMode = "timeline" | "calendar"; @@ -23,13 +24,9 @@ function getIcon(type: LogType) { return "📝"; } +// dateStr is now an IST YYYY-MM-DD string (from dateIST()) function formatDayLabel(dateStr: string): string { - const d = new Date(dateStr); - const today = new Date().toDateString(); - const yesterday = new Date(Date.now() - 86_400_000).toDateString(); - if (d.toDateString() === today) return "Today"; - if (d.toDateString() === yesterday) return "Yesterday"; - return d.toLocaleDateString("en-IN", { weekday: "short", month: "short", day: "numeric" }); + return dayLabel(dateStr); } export default function ActivityPage() { @@ -100,8 +97,8 @@ export default function ActivityPage() { }; // Today's stats (computed from loaded logs — no extra fetch) - const todayStr = new Date().toDateString(); - const todayLogs = logs.filter(l => new Date(l.loggedAt).toDateString() === todayStr); + const todayStr = todayIST(); + const todayLogs = logs.filter(l => dateIST(l.loggedAt) === todayStr); const todayCounts = { feed: todayLogs.filter(l => l.type === "feed").length, sleep: todayLogs.filter(l => l.type === "sleep").length, @@ -111,21 +108,21 @@ export default function ActivityPage() { // Last 4 calendar days (computed from loaded logs — no extra fetch) const last4Days = Array.from({ length: 4 }, (_, i) => { const d = new Date(Date.now() - i * 86_400_000); - const dateStr = d.toDateString(); - const dayLogs = logs.filter(l => new Date(l.loggedAt).toDateString() === dateStr); + const dateStr = dateIST(d); + const dLogs = logs.filter(l => dateIST(l.loggedAt) === dateStr); return { date: dateStr, - label: i === 0 ? "Today" : i === 1 ? "Yest." : d.toLocaleDateString("en-IN", { weekday: "short" }), - feed: dayLogs.filter(l => l.type === "feed").length, - sleep: dayLogs.filter(l => l.type === "sleep").length, - diaper: dayLogs.filter(l => l.type === "diaper").length, + label: i === 0 ? "Today" : i === 1 ? "Yest." : fmtDate(d, { weekday: "short" }), + feed: dLogs.filter(l => l.type === "feed").length, + sleep: dLogs.filter(l => l.type === "sleep").length, + diaper: dLogs.filter(l => l.type === "diaper").length, }; }); const filteredLogs = filter === "all" ? logs : logs.filter(l => l.type === filter); const groupedByDay = filteredLogs.reduce((acc, log) => { - const date = new Date(log.loggedAt).toDateString(); + const date = dateIST(log.loggedAt); const existing = acc.find(d => d.date === date); if (existing) existing.logs.push(log); else acc.push({ date, logs: [log] }); @@ -359,7 +356,7 @@ export default function ActivityPage() {
- {new Date(log.loggedAt).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })} + {fmtTime(log.loggedAt)}
@@ -413,7 +410,7 @@ export default function ActivityPage() { {[ selectedLog.subType?.replace(/_/g, " "), selectedLog.amount ? `${selectedLog.amount}ml` : null, - new Date(selectedLog.loggedAt).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }), + fmtTime(selectedLog.loggedAt), ].filter(Boolean).join(" · ")} @@ -473,7 +470,7 @@ export default function ActivityPage() { const { date: sheetDateStr, type: sheetType } = daySheetDate; const sheetLogs = logs .filter(l => - new Date(l.loggedAt).toDateString() === sheetDateStr && + dateIST(l.loggedAt) === sheetDateStr && l.type === sheetType ) .sort((a, b) => new Date(b.loggedAt).getTime() - new Date(a.loggedAt).getTime()); @@ -538,7 +535,7 @@ export default function ActivityPage() {
- {new Date(log.loggedAt).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })} + {fmtTime(log.loggedAt)}
diff --git a/src/app/(app)/ai/page.tsx b/src/app/(app)/ai/page.tsx index d578fda..e639655 100644 --- a/src/app/(app)/ai/page.tsx +++ b/src/app/(app)/ai/page.tsx @@ -4,6 +4,7 @@ import { useState, useEffect } from "react"; import { useFamily } from "@/app/FamilyProvider"; import { Button, Input, ConfirmDialog } from "@/components/ui"; import type { AIChat, ChatSession } from "@/types"; +import { fmtDate } from "@/lib/date-ist"; export default function AIChatPage() { const { childId } = useFamily(); @@ -186,7 +187,7 @@ export default function AIChatPage() { >
{session.title}
-
{new Date(session.updatedAt).toLocaleDateString()}
+
{fmtDate(session.updatedAt)}