authorgravatar for 154429365+Rishet11@users.noreply.github.comRishet11 <154429365+Rishet11@users.noreply.github.com> 2026-08-15 17:37:24+05:30
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-15 12:07:24+00:00
log684d703b0a8a0632a18c8453277f7e5e6312b200
treea5321f402ba9e7504c4cda558f83fa61b19d99ac
parent40ab7bf32a81a66b20571ed280dc238c2276dc61
signature Signed by PGP key B5690EEEBB952194

fix(shared): degrade an unknown system time zone to UTC in usage windows (#6670)


2 files changed, 36 insertions(+), 8 deletions(-)

packages/shared/src/usageFormat.test.ts+17-1
......@@ -1,5 +1,5 @@
11// @effect-diagnostics globalDate:off -- A fixed instant keeps calendar-window assertions deterministic.
2import { describe, expect, it } from "vite-plus/test";
2import { describe, expect, it, vi } from "vite-plus/test";
33
44import {
55 enumerateHourStarts,
......@@ -54,4 +54,20 @@ describe("hourly usage formatting", () => {
5454 expect(window.sinceTime).toBe("2026-08-10T12:37:00.000Z");
5555 expect(window.untilTime).toBe("2026-08-11T12:37:00.000Z");
5656 });
57
58 it("degrades an unknown resolved zone to UTC instead of crashing", () => {
59 const resolved = new Intl.DateTimeFormat().resolvedOptions();
60 const resolvedOptions = vi
61 .spyOn(Intl.DateTimeFormat.prototype, "resolvedOptions")
62 .mockReturnValue({ ...resolved, timeZone: "Etc/Unknown" });
63
64 try {
65 const now = new Date("2026-08-11T12:37:42.123Z");
66
67 expect(makeWindow(1, now, "hour").timeZone).toBe("UTC");
68 expect(makeWindow(30, now).timeZone).toBe("UTC");
69 } finally {
70 resolvedOptions.mockRestore();
71 }
72 });
5773});
packages/shared/src/usageFormat.ts+19-7
......@@ -179,13 +179,25 @@ export function makeWindow(
179179 now = new Date(),
180180 resolution: UsageResolution = "day",
181181): UsageSummaryInput {
182 const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
183 const format = new Intl.DateTimeFormat("en-CA", {
184 timeZone,
185 year: "numeric",
186 month: "2-digit",
187 day: "2-digit",
188 });
182 let timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
183 let format: Intl.DateTimeFormat;
184 try {
185 format = new Intl.DateTimeFormat("en-CA", {
186 timeZone,
187 year: "numeric",
188 month: "2-digit",
189 day: "2-digit",
190 });
191 } catch {
192 // An unknown zone should degrade to UTC rather than crash the page.
193 timeZone = "UTC";
194 format = new Intl.DateTimeFormat("en-CA", {
195 timeZone: "UTC",
196 year: "numeric",
197 month: "2-digit",
198 day: "2-digit",
199 });
200 }
189201 const untilDay = format.format(now);
190202 if (resolution === "hour") {
191203 // Minute-aligned bounds keep labels readable while still representing an