/** * 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(wall), '7:52am', 'fmtTime(toDate) prints stored digits') eq(fmtTime(instant), fmtTime(new Date(GRAPH)), 'fmtTime(toInstant) matches local clock') if (new Date().getTimezoneOffset() !== 0) { eq(fmtTime(instant) === fmtTime(wall), false, 'non-UTC zone: instant display differs from wall-clock') } if (failed) { console.error(`\n${failed} failed`) process.exit(1) } console.log('format.test.mjs ok')