/** * Date parsing — wall-clock digits vs UTC instants. * * node format.test.mjs * * Graph receivedDateTime is always UTC (…Z). toDate() prints those digits as * written (7:52). toInstant() converts to the browser timezone the way Outlook * does (12:52 in Pakistan). */ import { fmtTime, toDate, toInstant } from './src/lib/format.js' let failed = 0 function eq(actual, expected, label) { if (Object.is(actual, expected)) return failed += 1 console.error(`FAIL ${label}\n expected: ${JSON.stringify(expected)}\n actual: ${JSON.stringify(actual)}`) } const GRAPH = '2026-09-07T07:52:00Z' const GRAPH_NAKED = '2026-09-07T07:52:00' const GRAPH_OFFSET = '2026-09-07T07:52:00+00:00' eq(toDate(null), null, 'toDate(null)') eq(toInstant(null), null, 'toInstant(null)') eq(toDate(''), null, 'toDate empty') eq(toInstant('not-a-date'), null, 'toInstant garbage') const wall = toDate(GRAPH) eq(wall instanceof Date, true, 'toDate returns Date') eq(wall.getHours(), 7, 'toDate ignores Z — hour is the stored digit') eq(wall.getMinutes(), 52, 'toDate minutes') const instant = toInstant(GRAPH) eq(instant instanceof Date, true, 'toInstant returns Date') eq(instant.getTime(), Date.parse(GRAPH), 'toInstant is the UTC instant') eq(toInstant(GRAPH_NAKED).getTime(), Date.parse(GRAPH), 'Graph without Z is still UTC') eq(toInstant(GRAPH_OFFSET).getTime(), Date.parse(GRAPH), 'Graph +00:00 is UTC') eq(fmtTime(instant), '12:52pm', '7:52 UTC Date paints 12:52pm PKT') eq(fmtTime(GRAPH), '12:52pm', '7:52 UTC string paints 12:52pm PKT') eq(fmtTime(GRAPH_OFFSET), '12:52pm', '+00:00 paints PKT') eq(fmtTime('2026-09-09T11:50:24Z'), '4:50pm', 'live Graph sample is 4:50pm PKT') eq(fmtTime('2026-08-27T13:23:32'), '1:23pm', 'naive sheet ISO is PKT digits') if (new Date().getTimezoneOffset() === -300) { eq(fmtTime(wall), '7:52am', 'on a PKT machine wall-clock Date stays 7:52am') } if (failed) { console.error(`\n${failed} failed`) process.exit(1) } console.log('format.test.mjs ok')