Commit be8aee6
fix: handle fractional-hour timezone offsets correctly (nesquena#1144)
The Etc/GMT-X mapping in _serverTzOptions can only express whole-hour
offsets — IANA Etc/GMT zones don't support fractional hours. Users in
India (+0530), Iran (+0330/+0430), Newfoundland (-0330), Nepal (+0545),
Sri Lanka (+0530), Afghanistan (+0430), and Burma (+0630) — collectively
~1.5 billion people — would see timestamps off by 30 minutes after this
PR's whole-hour-only TZ conversion. That's actively WORSE than the pre-PR
behaviour for them: pre-PR they saw browser-tz times (consistent with
their wall clock), post-PR they'd see times 30 min off from the server.
Fix: introduce _formatInServerTz(date, options) that uses offset
arithmetic — shift the timestamp by the server's offset, then format
with timeZone:'UTC' so no further conversion is applied. The formatted
output reads as the wall-clock time in the server's timezone for ANY
offset, including fractional.
_serverTzOptions is kept for whole-hour fast-path callers that spread
its result; updated to return undefined for fractional offsets so it
can't silently produce off-by-30-min output via the spread path.
ui.js: _formatMessageFooterTimestamp and tsTitle in renderMessages now
go through _formatInServerTz with a fallback to bare toLocaleString
when sessions.js hasn't loaded yet.
Tests:
- test_message_footer_timestamp_uses_server_tz: stubs _formatInServerTz
with the same offset-arithmetic logic as sessions.js, asserts UTC+8
conversion produces the right wall-clock hour.
- test_message_footer_timestamp_handles_fractional_offset: NEW. Stubs
_formatInServerTz with +0530 (IST), asserts 02:00 UTC → 07:30 IST and
explicitly NOT 07:00 (the broken Etc/GMT-5 result).
- test_ui_js_message_timestamp_uses_server_tz: relaxed to accept either
_formatInServerTz or _serverTzOptions reference.
- test_sessions_js_has_format_in_server_tz_helper: NEW. Verifies the
function exists and uses offset arithmetic + UTC formatting.
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>1 parent 2b91f28 commit be8aee6
3 files changed
Lines changed: 138 additions & 27 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
778 | 778 | | |
779 | 779 | | |
780 | 780 | | |
781 | | - | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
782 | 788 | | |
783 | 789 | | |
784 | 790 | | |
| 791 | + | |
785 | 792 | | |
786 | 793 | | |
787 | 794 | | |
788 | 795 | | |
789 | 796 | | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
| 817 | + | |
790 | 818 | | |
791 | 819 | | |
792 | 820 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2148 | 2148 | | |
2149 | 2149 | | |
2150 | 2150 | | |
2151 | | - | |
| 2151 | + | |
| 2152 | + | |
| 2153 | + | |
| 2154 | + | |
2152 | 2155 | | |
2153 | | - | |
2154 | | - | |
2155 | | - | |
2156 | | - | |
2157 | | - | |
2158 | | - | |
2159 | | - | |
2160 | | - | |
2161 | | - | |
| 2156 | + | |
| 2157 | + | |
| 2158 | + | |
| 2159 | + | |
| 2160 | + | |
2162 | 2161 | | |
2163 | 2162 | | |
2164 | 2163 | | |
| |||
2363 | 2362 | | |
2364 | 2363 | | |
2365 | 2364 | | |
2366 | | - | |
2367 | | - | |
| 2365 | + | |
| 2366 | + | |
| 2367 | + | |
| 2368 | + | |
2368 | 2369 | | |
2369 | 2370 | | |
2370 | 2371 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
326 | 326 | | |
327 | 327 | | |
328 | 328 | | |
329 | | - | |
| 329 | + | |
330 | 330 | | |
331 | 331 | | |
332 | 332 | | |
333 | 333 | | |
334 | 334 | | |
335 | 335 | | |
336 | 336 | | |
337 | | - | |
338 | | - | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
339 | 343 | | |
340 | | - | |
341 | | - | |
342 | | - | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
343 | 349 | | |
344 | 350 | | |
345 | 351 | | |
346 | | - | |
| 352 | + | |
347 | 353 | | |
348 | 354 | | |
349 | 355 | | |
350 | 356 | | |
351 | 357 | | |
352 | 358 | | |
353 | 359 | | |
354 | | - | |
355 | | - | |
356 | | - | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
357 | 412 | | |
358 | 413 | | |
359 | 414 | | |
| |||
404 | 459 | | |
405 | 460 | | |
406 | 461 | | |
407 | | - | |
408 | | - | |
409 | | - | |
410 | | - | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
0 commit comments