// server/lib/time.test.ts import { test } from "node:test"; import assert from "node:assert/strict"; import { bizDateISO, bizTodayISO, bizDayBoundsSqlite, bizDayBoundsIso, wallToUtcISO, wallToUtcDate, toSqliteUtc, toIsoUtc, } from "./time.ts"; const MX = "America/Mexico_City"; // UTC-6 (no DST since 2023) const BA = "America/Buenos_Aires"; // UTC-3 test("bizTodayISO: UTC instant just past midnight (00:30Z) is still the previous day in MX", () => { // 2026-07-27T00:30:00Z == 2026-07-26T18:30 local → still the 26th assert.equal(bizTodayISO(MX, new Date("2026-07-27T00:30:00Z")), "2026-07-26"); }); test("bizTodayISO: late afternoon UTC (17:00Z) is same biz day in MX", () => { assert.equal(bizTodayISO(MX, new Date("2026-07-26T17:00:00Z")), "2026-07-26"); }); test("bizDateISO: Buenos Aires UTC-3 midday stays same day", () => { // 17:00Z == 14:00 local assert.equal(bizDateISO(new Date("2026-07-26T17:00:00Z"), BA), "2026-07-26"); }); test("bizDateISO: Buenos Aires UTC-3 evening stays same day", () => { // 23:00Z == 20:00 local assert.equal(bizDateISO(new Date("2026-07-26T23:00:00Z"), BA), "2026-07-26"); }); test("bizDateISO: UTC instant rolls to next local day", () => { // 2026-07-27T05:00:00Z == 2026-07-26T23:00 in MX → still 26th assert.equal(bizDateISO(new Date("2026-07-27T05:00:00Z"), MX), "2026-07-26"); // 2026-07-27T06:30:00Z == 2026-07-27T00:30 in MX → now 27th assert.equal(bizDateISO(new Date("2026-07-27T06:30:00Z"), MX), "2026-07-27"); }); test("wallToUtcISO: MX wall 18:00 → UTC next-day 00:00", () => { assert.equal(wallToUtcISO(MX, 2026, 7, 26, 18, 0, 0), "2026-07-27T00:00:00.000Z"); }); test("wallToUtcISO: MX wall 00:00 → UTC 06:00 same date", () => { assert.equal(wallToUtcISO(MX, 2026, 7, 26, 0, 0, 0), "2026-07-26T06:00:00.000Z"); }); test("wallToUtcDate: round-trip via bizDateISO stays on the wall day", () => { const utc = wallToUtcDate(MX, 2026, 7, 26, 18, 0, 0); assert.equal(bizDateISO(utc, MX), "2026-07-26"); }); test("bizDayBoundsSqlite: today bounds capture the evening rush (UTC-6)", () => { // "now" is 2026-07-26T23:30:00Z == 2026-07-26T17:30 local MX → biz day 2026-07-26 const b = bizDayBoundsSqlite(MX, 0, new Date("2026-07-26T23:30:00Z")); // biz-local midnight 2026-07-26 in MX == 06:00Z; end of day 23:59:59 == 2026-07-27T05:59:59Z assert.equal(b.start, "2026-07-26 06:00:00"); assert.equal(b.end, "2026-07-27 05:59:59"); }); test("bizDayBoundsIso: ISO-Z bounds for start_at comparisons", () => { const b = bizDayBoundsIso(MX, 0, new Date("2026-07-26T23:30:00Z")); assert.equal(b.start, "2026-07-26T06:00:00Z"); assert.equal(b.end, "2026-07-27T05:59:59Z"); }); test("bizDayBoundsSqlite: negative offset reaches into the past", () => { // 30 days before biz day 2026-07-26 → 2026-06-26, midnight MX == 06:00Z const b = bizDayBoundsSqlite(MX, -30, new Date("2026-07-26T23:30:00Z")); assert.equal(b.start, "2026-06-26 06:00:00"); }); test("toSqliteUtc / toIsoUtc format helpers", () => { const d = new Date("2026-07-27T00:00:00.000Z"); assert.equal(toSqliteUtc(d), "2026-07-27 00:00:00"); assert.equal(toIsoUtc(d), "2026-07-27T00:00:00Z"); });