This closes #2372, fix precision loss for time.Duration cell values - #2373
Merged
Conversation
…lues setCellDuration formatted the Excel serial number with bitSize 32, so FormatFloat emitted the shortest decimal that round-trips as a float32 and discarded the float64 precision the division produced. Every other float write path in the package already uses 64. Signed-off-by: alliasgher <alliasgher123@gmail.com>
2 tasks
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #2373 +/- ##
=======================================
Coverage 99.62% 99.62%
=======================================
Files 32 32
Lines 26994 26994
=======================================
Hits 26892 26892
Misses 53 53
Partials 49 49
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
xuri
approved these changes
Aug 9, 2026
xuri
left a comment
Member
There was a problem hiding this comment.
Thanks for your contribution! I've made some modification based on your branch.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
setCellDurationformats the Excel serial number withbitSize32:value.Seconds()returns afloat64and the division is done infloat64, butbitSize32 tellsFormatFloatto emit the shortest decimal that round-trips as afloat32, so the extra precision is thrown away on write.It is the only float write path in the package that does this —
cell.go:278,cell.go:603,cell.go:646/648,lib.go:815,numfmt.go:5290/5544/5676,stream.go:358/722and thecalc.gosites all use 64. (cell.go:420takes a caller-suppliedbitSizefromSetCellFloat, which is by design.)Reproduced on master before the change:
100*24*time.Hour + 123456789ns100100.000001428898021m30s0.00104166670.0010416666666666667For the first one the entire fractional part is gone. Durations whose serial is exactly representable in a few decimal digits (
25h30m,3h15m45s) were already unaffected.Related Issue
This closes #2372
Motivation and Context
Excel stores serials as IEEE doubles, so writing the full
float64expansion is what the format expects. Note this does change the raw value written into the XML for durations that are not exactly representable — that is the point of the fix, but it is an output change worth stating.StreamWriter.SetRow(stream.go) also goes throughsetCellDuration, so it is fixed by the same one-line change.How Has This Been Tested
The existing duration table in
cell_test.goonly asserts formatted output ("21:51:44"and friends), which passes both before and after — those are whole-second values that the number format rounds anyway, so they could not guard this. Added a raw-value assertion usingOptions{RawCellValue: true}for two durations that are not exactly representable; it fails on master withexpected: "100.00000142889802" / actual: "100".go test -race -timeout 60m ./...passes in full (839s —TestZip64needs the longer timeout), andgofmt -s -lis clean on both changed files.Types of changes