Keep the 1904 date system when reading and writing - #375
Conversation
`workbookPr/@date1904` was never read, and the writer always emitted `<workbookPr filterPrivacy="1"/>`. Opening a 1904-system workbook and saving it therefore turned it into a 1900-system workbook, which moves every date in it back by 1,462 days (4 years and a day): serial 45000 reads as 2027-03-16 before the round trip and 2023-03-15 after it. Read the attribute (both "1" and "true" spellings of xsd:boolean), write it back when set, and expose it as `Workbook::date1904()` / `Workbook::set_date1904()`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019hXzkiuCwk5QQRsyU9wT9h
|
|
||
| /// Whether the workbook uses the 1904 date system (`workbookPr/@date1904`). | ||
| /// | ||
| /// In the 1904 system, serial 0 is 1904-01-01 instead of 1900-01-00, so the |
There was a problem hiding this comment.
Don't have the time to double check right now but this seems wrong. I think serial 0 is 1899-12-31 and serial 1 is 1900-01-01.
Just read the comment over and yeah the comment is wrong for sure (even though I'm not 100% on the above) because 1900-01-00 is NOT a real date.
There was a problem hiding this comment.
Thanks, good catch. Excel does display serial 0 as 1900-01-00, but you're right that it isn't a real date and doesn't belong in a doc comment. I've reworded it in fe6f031: serial 0 is 1904-01-01 and serial 1 is 1904-01-02 in the 1904 system, serial 1 is 1900-01-01 in the 1900 system, and the 1,462-day offset is stated as holding from 1900-03-01 on (past Excel's fictitious 1900-02-29). Happy to help with anything else here.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@keithadler @c-git |
Problem
workbookPr/@date1904is never read, and the writer always emits<workbookPr filterPrivacy="1"/>. So opening a workbook that uses the 1904 date system and saving it turns it into a 1900-system workbook, and every date in it moves back by 1,462 days (4 years and a day), with no error:workbookPr<workbookPr date1904="1"/>reader::xlsx::read+writer::xlsx::write<workbookPr filterPrivacy="1"/>Workbooks from older Mac versions of Excel use the 1904 system.
Change
date1904fromworkbookPr(both"1"and"true", since it is anxsd:boolean).Workbook::date1904()/Workbook::set_date1904().Cell::formatted_value()still formats serials in the 1900 system, since a cell has no access to its workbook. Fixing that needs an API decision (for example passing the date system into the formatter), so I left it out of this PR. With this change a caller can at least readdate1904()and adjust.Tests
tests/date1904_roundtrip.rs: the default is false and not written;truesurvives write → read → write; the"true"spelling is read.cargo +nightly fmt --all --check,cargo clippy -- -D warningsandcargo testpass.Found by differential testing with xlsx-lean, a formal model of the XLSX format in Lean, whose corpus includes a 1904-system workbook.
🤖 Generated with Claude Code
https://claude.ai/code/session_019hXzkiuCwk5QQRsyU9wT9h