@@ -447,21 +447,35 @@ function localizeTimestamp(input) {
447447 return formatSafe ( input , tz ) ;
448448
449449 function formatSafe ( str , tz ) {
450- const date = new Date ( str ) ;
450+ // CHECK: Does the input string have timezone information?
451+ // - Ends with Z: "2026-02-11T11:37:02Z"
452+ // - Has GMT±offset: "Wed Feb 11 2026 12:34:12 GMT+1100 (...)"
453+ // - Has offset at end: "2026-02-11 11:37:02+11:00"
454+ // - Has timezone name in parentheses: "(Australian Eastern Daylight Time)"
455+ const hasOffset = / Z $ / i. test ( str . trim ( ) ) ||
456+ / G M T [ + - ] \d { 2 , 4 } / . test ( str ) ||
457+ / [ + - ] \d { 2 } : ? \d { 2 } $ / . test ( str . trim ( ) ) ||
458+ / \( [ ^ ) ] + \) $ / . test ( str . trim ( ) ) ;
459+
460+ // ⚠️ CRITICAL: All DB timestamps are stored in UTC without timezone markers.
461+ // If no offset is present, we must explicitly mark it as UTC by appending 'Z'
462+ // so JavaScript doesn't interpret it as local browser time.
463+ let isoStr = str . trim ( ) ;
464+ if ( ! hasOffset ) {
465+ // Ensure proper ISO format before appending Z
466+ // Replace space with 'T' if needed: "2026-02-11 11:37:02" → "2026-02-11T11:37:02Z"
467+ isoStr = isoStr . trim ( ) . replace ( / ^ ( \d { 4 } - \d { 2 } - \d { 2 } ) ( \d { 2 } : \d { 2 } : \d { 2 } ) $ / , '$1T$2' ) + 'Z' ;
468+ }
469+
470+ const date = new Date ( isoStr ) ;
451471 if ( ! isFinite ( date ) ) {
452472 console . error ( `ERROR: Couldn't parse date: '${ str } ' with TIMEZONE ${ tz } ` ) ;
453473 return 'Failed conversion' ;
454474 }
455475
456- // CHECK: Does the input string have an offset (e.g., +11:00 or Z)?
457- // If it does, and we apply a 'tz' again, we double-shift.
458- const hasOffset = / [ Z | [ + - ] \d { 2 } : ? \d { 2 } ] $ / . test ( str . trim ( ) ) ;
459-
460476 return new Intl . DateTimeFormat ( LOCALE , {
461- // If it has an offset, we display it as-is (UTC mode in Intl
462- // effectively means "don't add more hours").
463- // If no offset, apply your variable 'tz'.
464- timeZone : hasOffset ? 'UTC' : tz ,
477+ // Convert from UTC to user's configured timezone
478+ timeZone : tz ,
465479 year : 'numeric' , month : '2-digit' , day : '2-digit' ,
466480 hour : '2-digit' , minute : '2-digit' , second : '2-digit' ,
467481 hour12 : false
0 commit comments