Skip to content

feat(odf): write a date and a time into an ods cell - #977

Merged
andiwand merged 2 commits into
mainfrom
feat/ods-write-dates
Oct 4, 2026
Merged

andiwand merged 2 commits into
mainfrom
feat/ods-write-dates

Conversation

@andiwand

@andiwand andiwand commented Oct 4, 2026 •

Copy link
Copy Markdown
Member

🤖 Generated with Claude Code

Step 2 of the typed-dates plan (decision 18, the ods half).

Change

  • writable takes a date or time value that states its number. One without a number is still refused, before the cell changes.
  • A date: office:value-type="date" and office:date-value, either YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS when it has a time of day. number_format::civil_from_days turns the days back into a civil date.
  • A time: office:value-type="time" and office:time-value as a duration, PT18H30M00S, with hours past 24 where the value runs over a day.
  • The text: shown_number becomes shown_value. A date or time takes its text:p from the cell's date or time data style, and a number from its number style. A cell whose data style is of the other kind, or which has none, keeps the typed text.
  • The time of day: a time, and a date below one day, go to the formatter as they are. The 1900 shift of serial_from_days would make a time of day negative, and the formatter then falls back to General. The LibreOffice probe below found that: 18:30 showed as -0.229166666666667 before the fix.

Review after the rebase

A date outside the years 1 to 9999 wrote an office:date-value that the reader refuses, and a very large number overflowed the calendar arithmetic. writable now refuses such a date, and a time that is not finite; a_date_past_9999_or_an_infinite_time_refuses covers both. civil_from_days returns std::uint32_t and has a qualified definition, as #976 now does. The rest holds: the floor of a negative day, the duration spelling, and the choice of a style by the category of the value.

Proof

  • New OdfSheetWrite tests:
    • a date with a time, and a time, into cells without a style: exact markup, and the values read back;
    • the date op into a dd.mm.yyyy cell gives 02.01.2025;
    • a time into an hh:mm cell gives 18:30;
    • a date without its number is refused.
  • OdfSheetWrite.*, OdfSheetValue.*, NumberFormat.*, Ooxml*, html.*, Csv* and the edit suites: 357 passed.
  • LibreOffice oracle: LibreOffice converted an xlsx with dd.mm.yyyy, hh:mm and yyyy-mm-dd hh:mm cells to ods. back_translate wrote a date, a time, a date with a time, and a date into a plain cell. LibreOffice's csv export reads each value as written: 02.01.2025,18:30,2025-01-02 18:00,01/02/25 12:00 AM. Our text:p agrees for every styled cell. The plain cell keeps the typed 1/2/2025, while LibreOffice renders it in its own default date format.
  • g++-15 -Wall -Wextra -Werror is clean on the touched files.

@andiwand
andiwand force-pushed the feat/ods-write-dates branch from dcca778 to ee25c2b Compare October 4, 2026 10:57
Base automatically changed from feat/date-serials to main October 4, 2026 11:10
andiwand and others added 2 commits October 4, 2026 13:10
`sheet_set_cell` takes a date or time `CellValue` that states its number. A
date writes `office:value-type="date"` and an `office:date-value`, with its
time where it has one; a time writes `office:time-value` as a duration. The
`text:p` comes from the cell's date or time data style where it has one, and
from the typed text otherwise. A time of day does not move onto the 1900
system, so it stays positive.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011qFgpigFCwbfZ24TFj7eqA
An `office:date-value` spells its year in four digits, so a date outside
the years 1 to 9999 gave a value that the reader refuses. A very large
number also overflowed the calendar arithmetic.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011qFgpigFCwbfZ24TFj7eqA
@andiwand
andiwand force-pushed the feat/ods-write-dates branch from ee25c2b to 3c8286b Compare October 4, 2026 11:13
@andiwand
andiwand merged commit e40a848 into main Oct 4, 2026
23 checks passed
@andiwand
andiwand deleted the feat/ods-write-dates branch October 4, 2026 11:17
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