Description
The format() function throws Error: Invalid offset format on Microsoft Edge 32-bit (Chromium-based, version 144.0.3719.82). The same code works perfectly on Edge 64-bit.
Root Cause
Edge 32-bit has a bug in Intl.DateTimeFormat.formatToParts() where time components are silently dropped when:
- A non-UTC timezone is specified (e.g.,
timeZone: 'Europe/Berlin')
- AND time options use
'2-digit' format
This causes tempo's offset() function (in offset.mjs) to receive incomplete date parts, resulting in an invalid Date object and ultimately NaN values in the offset calculation.
Reproduction
// This works on Edge 64-bit but FAILS on Edge 32-bit
import { format } from '@formkit/tempo';
const date = new Date('2026-01-20T08:07:40.000Z');
const result = format(date, 'YYYY-MM-DD HH:mm:ss');
// Edge 32-bit throws: Error: Invalid offset format
Debug Information
Edge 32-bit behavior with Intl.DateTimeFormat:
// Using '2-digit' - BROKEN on Edge 32-bit
const formatter = new Intl.DateTimeFormat('en-US', {
timeZone: 'Europe/Berlin',
year: 'numeric', month: '2-digit', day: '2-digit',
hour: '2-digit', minute: '2-digit', second: '2-digit',
hourCycle: 'h23'
});
console.log(formatter.formatToParts(new Date()));
// Output on Edge 32-bit (TIME PARTS MISSING!):
[
{ "type": "month", "value": "01" },
{ "type": "literal", "value": "/" },
{ "type": "day", "value": "20" },
{ "type": "literal", "value": "/" },
{ "type": "year", "value": "2026" }
]
// Using 'numeric' - WORKS on Edge 32-bit
const formatter2 = new Intl.DateTimeFormat('en-US', {
timeZone: 'Europe/Berlin',
year: 'numeric', month: '2-digit', day: '2-digit',
hour: 'numeric', minute: 'numeric', second: 'numeric'
});
console.log(formatter2.formatToParts(new Date()));
// Output on Edge 32-bit (correct):
[
{ "type": "month", "value": "01" },
{ "type": "literal", "value": "/" },
{ "type": "day", "value": "20" },
{ "type": "literal", "value": "/" },
{ "type": "year", "value": "2026" },
{ "type": "literal", "value": ", " },
{ "type": "hour", "value": "10" },
{ "type": "literal", "value": ":" },
{ "type": "minute", "value": "47" },
{ "type": "literal", "value": ":" },
{ "type": "second", "value": "30" },
{ "type": "literal", "value": " " },
{ "type": "dayPeriod", "value": "AM" }
]
How tempo fails
format() calls offset(inputDate, tz, "utc") in format.mjs:30
offset() uses relativeTime() which calls Intl.DateTimeFormat(...).formatToParts()
- On Edge 32-bit,
formatToParts() returns only date parts (no hour/minute/second)
relativeTime() constructs: "2026-01-20T${undefined}:${undefined}:${undefined}Z"
new Date(...) returns Invalid Date
getTime() returns NaN
secsToOffset(NaN) produces "+NaN:NaN:NaN"
fixedLengthByOffset("+NaN:NaN:NaN") throws "Invalid offset format"
Environment
- Browser: Microsoft Edge 144.0.3719.82 (Official build) (32-bit) - Chromium-based
- OS: Windows
- @formkit/tempo version: 1.0.0
Suggested Fix
Option 1: Add try/catch in format() with graceful degradation
Option 2: In offset.mjs, validate that relativeTime() returns a valid Date before calculating offset
Option 3: Consider using 'numeric' instead of '2-digit' for internal Intl.DateTimeFormat options (though this may affect output formatting)
Workaround
We've implemented a wrapper that catches the error and falls back to native Date formatting:
import { format as tempoFormat } from '@formkit/tempo';
export function format(date, formatStr) {
try {
return tempoFormat(date, formatStr);
} catch {
// Native fallback for Edge 32-bit
const pad = (n) => n.toString().padStart(2, '0');
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
}
}
Related
This is a Chromium/Edge bug that should also be reported to Microsoft, but tempo could be more resilient to malformed Intl responses.
Description
The
format()function throwsError: Invalid offset formaton Microsoft Edge 32-bit (Chromium-based, version 144.0.3719.82). The same code works perfectly on Edge 64-bit.Root Cause
Edge 32-bit has a bug in
Intl.DateTimeFormat.formatToParts()where time components are silently dropped when:timeZone: 'Europe/Berlin')'2-digit'formatThis causes tempo's
offset()function (inoffset.mjs) to receive incomplete date parts, resulting in an invalid Date object and ultimatelyNaNvalues in the offset calculation.Reproduction
Debug Information
Edge 32-bit behavior with
Intl.DateTimeFormat:How tempo fails
format()callsoffset(inputDate, tz, "utc")informat.mjs:30offset()usesrelativeTime()which callsIntl.DateTimeFormat(...).formatToParts()formatToParts()returns only date parts (no hour/minute/second)relativeTime()constructs:"2026-01-20T${undefined}:${undefined}:${undefined}Z"new Date(...)returns Invalid DategetTime()returnsNaNsecsToOffset(NaN)produces"+NaN:NaN:NaN"fixedLengthByOffset("+NaN:NaN:NaN")throws"Invalid offset format"Environment
Suggested Fix
Option 1: Add try/catch in
format()with graceful degradationOption 2: In
offset.mjs, validate thatrelativeTime()returns a valid Date before calculating offsetOption 3: Consider using
'numeric'instead of'2-digit'for internalIntl.DateTimeFormatoptions (though this may affect output formatting)Workaround
We've implemented a wrapper that catches the error and falls back to native Date formatting:
Related
This is a Chromium/Edge bug that should also be reported to Microsoft, but tempo could be more resilient to malformed
Intlresponses.