61 lines
2.1 KiB
TypeScript
61 lines
2.1 KiB
TypeScript
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
|
|||
|
|
import { isoDateIn, todayIn, wallClockInstant, zoneOption } from "./zone";
|
||
|
|
import { formatClockTime } from "../today/format";
|
||
|
|
|
||
|
|
// 13:00 UTC on Sep 23 is already 01:00 on Sep 24 in Auckland (NZST, UTC+12).
|
||
|
|
const NOW = new Date("2026-09-23T13:00:00Z");
|
||
|
|
|
||
|
|
describe("application timezone helpers (process in UTC)", () => {
|
||
|
|
beforeAll(() => {
|
||
|
|
vi.stubEnv("TZ", "UTC");
|
||
|
|
});
|
||
|
|
|
||
|
|
afterAll(() => {
|
||
|
|
vi.unstubAllEnvs();
|
||
|
|
});
|
||
|
|
|
||
|
|
it("a stored zone decides the calendar date; empty means the browser's zone", () => {
|
||
|
|
expect(todayIn("Pacific/Auckland", NOW)).toBe("2026-09-24");
|
||
|
|
expect(isoDateIn(NOW, "Pacific/Auckland")).toBe("2026-09-24");
|
||
|
|
expect(todayIn("", NOW)).toBe("2026-09-23");
|
||
|
|
});
|
||
|
|
|
||
|
|
it("wall-clock time converts in the stored zone, across its DST change", () => {
|
||
|
|
// NZST (UTC+12) before 27 Sep 2026, NZDT (UTC+13) after.
|
||
|
|
expect(wallClockInstant("2026-09-24", 0, 10, "Pacific/Auckland")).toBe(
|
||
|
|
Date.parse("2026-09-23T12:10:00Z"),
|
||
|
|
);
|
||
|
|
expect(wallClockInstant("2026-09-28", 7, 30, "Pacific/Auckland")).toBe(
|
||
|
|
Date.parse("2026-09-27T18:30:00Z"),
|
||
|
|
);
|
||
|
|
expect(wallClockInstant("2026-09-24", 0, 10, "")).toBe(Date.parse("2026-09-24T00:10:00Z"));
|
||
|
|
});
|
||
|
|
|
||
|
|
it("the completion clock reads in the stored zone", () => {
|
||
|
|
expect(formatClockTime("2026-09-23T11:04:00Z", "Pacific/Auckland")).toBe("11:04 PM");
|
||
|
|
expect(formatClockTime("2026-09-23T11:04:00Z", "")).toBe("11:04 AM");
|
||
|
|
});
|
||
|
|
|
||
|
|
it("an invalid stored zone fails fast", () => {
|
||
|
|
expect(zoneOption("")).toBeUndefined();
|
||
|
|
expect(() => todayIn("Not/AZone", NOW)).toThrow(RangeError);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe("empty zone keeps browser-local behavior", () => {
|
||
|
|
beforeAll(() => {
|
||
|
|
vi.stubEnv("TZ", "America/Los_Angeles");
|
||
|
|
});
|
||
|
|
|
||
|
|
afterAll(() => {
|
||
|
|
vi.unstubAllEnvs();
|
||
|
|
});
|
||
|
|
|
||
|
|
it("matches the browser's own calendar and wall clock", () => {
|
||
|
|
// 13:00 UTC is 06:00 PDT on Sep 23.
|
||
|
|
expect(todayIn("", NOW)).toBe("2026-09-23");
|
||
|
|
expect(wallClockInstant("2026-09-23", 7, 30, "")).toBe(new Date(2026, 8, 23, 7, 30).getTime());
|
||
|
|
expect(formatClockTime("2026-09-23T14:04:00Z", "")).toBe("7:04 AM");
|
||
|
|
});
|
||
|
|
});
|