Skip to content

Fix #2966: convert formula result to Date when numFmt is date-like#76

Open
senoff wants to merge 1 commit into
protobi:masterfrom
senoff:senoff/fix-2966-formula-result-date
Open

Fix #2966: convert formula result to Date when numFmt is date-like#76
senoff wants to merge 1 commit into
protobi:masterfrom
senoff:senoff/fix-2966-formula-result-date

Conversation

@senoff
Copy link
Copy Markdown

@senoff senoff commented May 7, 2026

Summary

Tracked at exceljs#2966.

When a cell holds a formula whose cached result is a numeric Excel date serial and the cell's numFmt is date-like (m/d/yyyy, etc.), the reader should materialise cell.value.result as a JS Date. It did for the plain case (<v>46143</v>, no t attribute), but not when an off-spec writer marked the formula cell with t="str" and still put a numeric serial inside <v>. The streaming WorkbookReader had the same gap and never applied date conversion to formula results at all.

Fix

lib/xlsx/xform/sheet/cell-xform.js (reconcile, Formula branch) and lib/stream/xlsx/worksheet-reader.js (formula cell handling) both now:

  1. Detect numFmt is date-like (utils.isDateFmt).
  2. If result is a string, try Number(trimmed) — stricter than parseFloat so partial strings like "2026-05-07" are rejected (return NaN), not silently coerced to 2026.
  3. Only call utils.excelToDate when the result is actually a number. Non-numeric values ("", "N/A", booleans) pass through unchanged.

Files changed

  • lib/xlsx/xform/sheet/cell-xform.js — add string→number coercion + typeof === 'number' guard before excelToDate (Formula reconcile branch)
  • lib/stream/xlsx/worksheet-reader.js — same coercion + guard in the formula cell handler
  • spec/integration/issues/issue-2966-formula-result-date-numfmt.spec.js — 4-case integration test using JSZip-injected fixture shapes

Test cases

Shape Expected
numeric <v>, no t (regression baseline) Date
numeric <v> with t="str" (the actual bug) Date
non-numeric display string with t="str" string, not Invalid Date
streaming reader: numeric serial with t="str" Date

Notes

…#2966)

When a formula cell's cached result is a numeric Excel date serial, the
reader now materialises `cell.value.result` as a JS Date, even when an
off-spec writer has marked the cell as t="str" and put a numeric serial
inside <v>. This matches the behaviour for non-formula date cells.

Uses Number() instead of parseFloat() for string coercion so that partial
strings like "2026-05-07" are not silently truncated to 2026.  Guards the
excelToDate call behind typeof === 'number' so non-numeric results
(empty string, "N/A", booleans) are passed through unchanged.

Both the non-streaming reconcile path (cell-xform.js) and the streaming
worksheet reader (worksheet-reader.js) are fixed.

Adds 4-case integration test that covers:
  - numeric <v> with no t attribute (regression baseline)
  - numeric <v> with t="str" (the actual bug)
  - non-numeric display string with t="str" (must not become Invalid Date)
  - streaming reader: numeric serial with t="str" becomes a Date
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