Skip to content

Truncate fractional seconds per UTS 35 - #1292

Merged
akx merged 1 commit into
python-babel:masterfrom
vineethsaivs:fix/frac-seconds-field-overflow
Nov 4, 2026
Merged

akx merged 1 commit into
python-babel:masterfrom
vineethsaivs:fix/frac-seconds-field-overflow

Conversation

@vineethsaivs

@vineethsaivs vineethsaivs commented Jul 13, 2026 •

Copy link
Copy Markdown
Contributor

format_frac_seconds rounded microseconds, which could carry to a whole second and overflow the field (S gave 10). UTS #35 says to truncate to the field length, so it now truncates with integer math, which also removes the overflow. The docs and the three rounding expectations are updated, and a 999999 regression test covers S, SS, SSSS and SSSSSSSS.

@vineethsaivs
vineethsaivs force-pushed the fix/frac-seconds-field-overflow branch from d4e3c2b to dbd44a5 Compare August 27, 2026 17:15
@codecov

codecov Bot commented Aug 27, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.57%. Comparing base (7576e5d) to head (4a0d92d).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1292   +/-   ##
=======================================
  Coverage   93.57%   93.57%           
=======================================
  Files          27       27           
  Lines        4951     4952    +1     
=======================================
+ Hits         4633     4634    +1     
  Misses        318      318           
Flag Coverage Δ
macos-14-3.10 92.60% <100.00%> (+<0.01%) ⬆️
macos-14-3.11 92.54% <100.00%> (+<0.01%) ⬆️
macos-14-3.12 92.81% <100.00%> (+<0.01%) ⬆️
macos-14-3.13 92.81% <100.00%> (+<0.01%) ⬆️
macos-14-3.14 92.79% <100.00%> (+<0.01%) ⬆️
macos-14-3.15 92.79% <100.00%> (+<0.01%) ⬆️
macos-14-3.8 92.48% <100.00%> (+<0.01%) ⬆️
macos-14-3.9 92.54% <100.00%> (+<0.01%) ⬆️
macos-14-pypy3.10 92.60% <100.00%> (+<0.01%) ⬆️
ubuntu-24.04-3.10 92.62% <100.00%> (+<0.01%) ⬆️
ubuntu-24.04-3.11 92.56% <100.00%> (+<0.01%) ⬆️
ubuntu-24.04-3.12 92.83% <100.00%> (+<0.01%) ⬆️
ubuntu-24.04-3.13 92.83% <100.00%> (+<0.01%) ⬆️
ubuntu-24.04-3.14 92.81% <100.00%> (+<0.01%) ⬆️
ubuntu-24.04-3.15 92.81% <100.00%> (+<0.01%) ⬆️
ubuntu-24.04-3.8 92.50% <100.00%> (+<0.01%) ⬆️
ubuntu-24.04-3.9 92.56% <100.00%> (+<0.01%) ⬆️
ubuntu-24.04-pypy3.10 92.62% <100.00%> (+<0.01%) ⬆️
windows-2022-3.10 92.62% <100.00%> (+<0.01%) ⬆️
windows-2022-3.11 92.56% <100.00%> (+<0.01%) ⬆️
windows-2022-3.12 92.82% <100.00%> (+<0.01%) ⬆️
windows-2022-3.13 92.82% <100.00%> (+<0.01%) ⬆️
windows-2022-3.14 92.80% <100.00%> (+<0.01%) ⬆️
windows-2022-3.15 92.80% <100.00%> (+<0.01%) ⬆️
windows-2022-3.8 92.59% <100.00%> (+<0.01%) ⬆️
windows-2022-3.9 92.55% <100.00%> (+<0.01%) ⬆️
windows-2022-pypy3.10 92.62% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codspeed

codspeed Bot commented Aug 27, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 88 untouched benchmarks


Comparing vineethsaivs:fix/frac-seconds-field-overflow (4a0d92d) with master (7576e5d)

Open in CodSpeed

@jun66j5

jun66j5 commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

According to https://www.unicode.org/reports/tr35/tr35-dates.html#dfst-second, it says Fractional Second (numeric). Truncates, like other numeric time fields, but in this case to the number of digits specified by the field length. So, the format_frac_seconds should truncate the fractional second, not round.

The document of Date and Time in Babel, https://babel.pocoo.org/en/latest/dates.html#time-fields, says Fractional second, rounds to the count of letters, and the document should be fixed too.

@vineethsaivs

Copy link
Copy Markdown
Contributor Author

You are right, and that is the better fix: TR35 says the field truncates, and truncation makes the overflow impossible rather than clamping it after the fact. round(0.999, 1) * 10 can reach 10; 0.999 truncated to one digit is 9 and never can.

Two things worth deciding before I switch this PR over, since truncating is a wider change than the overflow repair.

It changes three expectations that test_fractional_seconds currently pins:

input field today truncated
time(8, 3, 1, 799) SSSS 0008 0007
time(8, 3, 1, 34567) SSSS 0346 0345
time(8, 3, 1, 799) SSSSS 00080 00079

The other two cases in that test, and test_fractional_seconds_zero, are unchanged. The docstring on format_frac_seconds says "Rounds the time's microseconds", so it would move too.

The arithmetic is also better done on the integer microseconds than on the float:

return self.format(self.value.microsecond // 10 ** (6 - num), num)   # num <= 6

int(self.value.microsecond / 1000000 * 10**num) is exact on every case I checked, but it is a float round-trip that does not need to happen, and // on the microsecond field cannot land a digit low.

Happy to push that as this PR, updating the three expectations and the docstring and dropping the clamp, if you would rather have the spec-correct behaviour than the narrower overflow fix. Say the word and I will rework it.

@vineethsaivs

Copy link
Copy Markdown
Contributor Author

Friendly bump: still relevant, and it merges cleanly with the base branch. Happy to adjust anything.

@akx

akx commented Oct 30, 2026

Copy link
Copy Markdown
Member

Happy to push that as this PR, updating the three expectations and the docstring and dropping the clamp, if you would rather have the spec-correct behaviour than the narrower overflow fix.

We would rather have the spec-correct behaviour, yes. :)

@vineethsaivs
vineethsaivs force-pushed the fix/frac-seconds-field-overflow branch from dbd44a5 to f3e47e5 Compare November 3, 2026 21:05
@vineethsaivs

Copy link
Copy Markdown
Contributor Author

Switched to truncation per UTS #35, rebased on current master, and updated the docs and tests. The overflow case is still covered by a regression test.

@vineethsaivs vineethsaivs changed the title Clamp rounded fractional seconds to the field width Truncate fractional seconds per UTS 35 Nov 3, 2026
format_frac_seconds rounded microseconds, which could carry to a whole second and overflow the field (S gave 10). UTS python-babel#35 says to truncate to the field length, so it now truncates with integer math. Docs and expectations updated.
@vineethsaivs
vineethsaivs force-pushed the fix/frac-seconds-field-overflow branch from f3e47e5 to 4a0d92d Compare November 3, 2026 21:06

@akx akx left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM.

https://www.unicode.org/reports/tr35/tr35-dates.html#dfst-second plainly says

Fractional Second (numeric). Truncates, like other numeric time fields, but in this case to the number of digits specified by the field length. (Example shows display using pattern SSSS for seconds value 12.34567)

and it looks like that's what we do now.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

No active review issues remain, and the fractional-second formatting change includes corresponding regression tests and documentation updates.

No open issues 🎉

What changed in this PR

Updates fractional-second formatting to comply with UTS #35 by truncating microseconds instead of rounding, preventing values from carrying into the next whole second.

Changes:

  • Replaced rounding-based formatting with integer truncation and zero-padding.
  • Updated tests and added regression coverage for high-precision values.
  • Documented truncation behavior for fractional-second fields.
File Description
tests/​test_date_time_format.py Updates expected truncation results and adds carry-over regression tests.
docs/​dates.rst Documents truncation semantics for the S field.
babel/​dates.py Implements truncation-based fractional-second formatting.

Review effort: Lite

@akx
akx merged commit d02d6a8 into python-babel:master Nov 4, 2026
36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants