Skip to content

Carry rounded fractional seconds in fsec2hms and fsec2dhms - #2282

Merged
johnkerl merged 3 commits into
johnkerl:mainfrom
ChandraChaan:fix/fsec2hms-carry
Nov 2, 2026
Merged

johnkerl merged 3 commits into
johnkerl:mainfrom
ChandraChaan:fix/fsec2hms-carry

Conversation

@ChandraChaan

@ChandraChaan ChandraChaan commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

fsec2hms and fsec2dhms split off the whole seconds with math.Trunc and print the fraction with %.6f. When the fraction rounds up to 1 at six decimal places, the carry stays in the printed seconds instead of reaching the seconds/minutes/hours split:

Call Current main Expected
fsec2hms(9.9999999) 00:00:010.000000 00:00:10.000000
fsec2hms(59.9999999) 00:00:60.000000 00:01:00.000000
fsec2hms(3599.9999999) 00:59:60.000000 01:00:00.000000
fsec2dhms(59.9999999) 60.000000s 1m00.000000s
fsec2dhms(3599.9999999) 59m60.000000s 1h00m00.000000s

(These are the values the new test reports on current main, from the test-only CI run linked below.)

(fsec2hms also adds its own zero pad when s < 10, which is where 010 comes from.)

Both functions now get the whole seconds and fraction from a small helper, splitFractionalSeconds, which carries a fraction that rounds to 1 into the whole seconds. So these now print the expected values. Only the fraction is rounded, so large inputs are unaffected.

Added TestBIF_fsec2hms_fsec2dhms_carry in pkg/bifs/datetime_test.go: carries into seconds, minutes and hours, a negative value, and a value with no carry (1.25).

I ran the Miller-Go workflow on my fork:

I didn't run make dev, since the change doesn't touch docs or function help text.

Both functions split off the whole seconds with math.Trunc and then
printed the fraction with %.6f. When the fraction rounded up to 1, the
carry stayed in the printed seconds: fsec2hms(9.9999999) gave
00:00:010.000000, fsec2hms(59.9999999) gave 00:00:60.000000, and
fsec2dhms(59.9999999) gave 60.000000s.

The fraction is now rounded to the printed precision before splitting, and
a fraction that rounds to 1 is carried into the whole seconds.

@johnkerl johnkerl left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great @ChandraChaan -- thank you! :)

Comment thread pkg/bifs/datetime_test.go
{59.9999999, "00:01:00.000000", "1m00.000000s"},
{3599.9999999, "01:00:00.000000", "1h00m00.000000s"},
{-59.9999999, "-00:01:00.000000", "-1m00.000000s"},
}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a case for 86399.9999999, expecting 24:00:00.000000 and 1d00h00m00.000000s?

@ChandraChaan

Copy link
Copy Markdown
Contributor Author

Thanks! Added the 86399.9999999 case in 1da0dd2: it gives 24:00:00.000000 and 1d00h00m00.000000s. Unit and regression tests pass on Ubuntu, macOS and Windows on my fork: https://github.com/ChandraChaan/miller/actions/runs/41463940058

@johnkerl
johnkerl merged commit 1a679f4 into johnkerl:main Nov 2, 2026
8 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.

2 participants