51 lines
1.8 KiB
JavaScript
51 lines
1.8 KiB
JavaScript
/**
|
|
* 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')
|