src/test/local-day.ts
Rama main · réplica de lectura del repositorio original.
// The calendar day an ISO instant falls on *in whatever timezone the suite is
// running in*, formatted the way the cards format it.
//
// Cards that print a `created_at`/`last_used_at` render it for the reader's own
// zone (`formatDateTime`), so a test asserting a day has to ask the same
// question the browser will. Writing the day down instead encodes the runner's
// timezone into the suite: UTC offsets run from -12 to +14, a 26-hour spread, so
// no instant renders as the same calendar day everywhere and there is no "safe"
// hour to pick - `12:00Z` is already 02:00 the next day in Kiritimati. Four
// assertions across three tests were red on `main` in one corner or the other
// before this existed;
// see DECISIONS.md, "A fixture meaning 'in the future' is derived, never written
// down".
//
// The options are spelled out here rather than reusing `formatDateTime` so the
// shape a test expects - short month, no time - stays pinned by the tests
// independently of the helper the component happens to call.
export function localDay(iso: string): string {
return new Date(iso).toLocaleDateString("en-US", {
year: "numeric",
month: "short",
day: "numeric",
});
}
// A bare "YYYY-MM-DD" `days` from now, in the suite's own timezone.
//
// Built from local getters because the fields these fixtures feed are compared against
// a local date (`todayIsoDate` in `lib/date-time.ts`). East of UTC in the small
// hours `toISOString().slice(0, 10)` renders tomorrow as today, and an assertion that a
// future date is refused then never fires. Spelled out rather than calling
// `todayIsoDate` so a bug in that one cannot cancel itself out here.
export function isoDaysFromNow(days: number): string {
const date = new Date();
date.setDate(date.getDate() + days);
const pad = (value: number) => String(value).padStart(2, "0");
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
}