Skip to content

fix(xlsx): honor the 1904 date system on read#3

Merged
mitresthen merged 1 commit into
masterfrom
fix/date1904-read
Jul 2, 2026
Merged

fix(xlsx): honor the 1904 date system on read#3
mitresthen merged 1 commit into
masterfrom
fix/date1904-read

Conversation

@mitresthen

Copy link
Copy Markdown
Owner

Summary

readXlsx and readXlsxRows now parse <workbookPr date1904="1"/> and convert date serials from the 1904 epoch. Previously the flag was ignored — the conversion support existed in src/utils/date.ts (oracle-validated in SP-1) but was never wired into the xlsx codecs, so dates in legacy Mac workbooks read back ~4 years off. This was documented as a known gap in the migration guide and README roadmap; this PR closes it.

Write behavior is unchanged by design: the model stores real Date objects, so writes keep emitting the standard 1900 system. Round-tripping a 1904 workbook preserves every instant while normalizing the file to 1900.

Changes

  • workbook-reader: parse workbookPr → new date1904 field on WorkbookParts
  • worksheet-reader / read: thread the flag into serialToDate via ReadContext
  • stream-reader: same threading through parseRow
  • Docs: CHANGELOG (Unreleased → Fixed), migration-guide gotcha updated, roadmap item removed

Test plan

TDD: both tests were written first and failed on the 1900 epoch (read 1900-01-01), then passed after the fix:

  • read-conformance: 1904.xlsx fixture B4 (serial 0) must read as 1904-01-01 — expected value confirmed against the exceljs oracle
  • stream-reader: same assertion through readXlsxRows
  • The existing readXlsx↔readXlsxRows parity sweep over all 36 fixtures guards both readers staying consistent

Full suite: 255 tests green, typecheck/lint/format clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JrxsnGbCRtq7VPskBRoSPr

readXlsx and readXlsxRows now parse <workbookPr date1904="1"/> and
convert date serials from the 1904 epoch — previously the flag was
ignored and dates in legacy Mac workbooks read back ~4 years off
(the conversion utility existed in utils/date.ts but was unwired).
Writes still emit the 1900 system: the model stores real Dates, so a
1904 round-trip preserves instants while normalizing the file.

Verified against the 1904.xlsx fixture with exceljs as oracle
(B4 = serial 0 = 1904-01-01).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JrxsnGbCRtq7VPskBRoSPr
@mitresthen mitresthen merged commit d0ff3cc into master Jul 2, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant