Skip to content

Preserve subsecond rounding for minutes, hours and days - #509

Open
liugedragon wants to merge 1 commit into
python-humanize:mainfrom
liugedragon:fix/precisedelta-coarse-subseconds
Open

liugedragon wants to merge 1 commit into
python-humanize:mainfrom
liugedragon:fix/precisedelta-coarse-subseconds

Conversation

@liugedragon

Copy link
Copy Markdown

Changes proposed in this pull request:

  • Include the microsecond remainder when rounding precisedelta() to a minimum unit of minutes, hours or days.
  • Add it only at the chosen unit's rounding step, including when suppression raises the effective minimum unit.
  • Update the documented precision limitation and cover numeric/timedelta inputs, both signs, custom formats, suppressed units and rounding boundaries.

For example:

precisedelta(30.6, minimum_unit="minutes")
# Before: "0.50 minutes"
# After:  "0.51 minutes"

precisedelta(59.999999, minimum_unit="minutes")
# Before: "0.98 minutes"
# After:  "1 minute"

This intentionally improves an existing documented limitation. The old expectation for precisedelta(3630.99, minimum_unit="minutes", format="%.0f") changes from "1 hour" to "1 hour and 1 minute": the remaining 30.99 seconds is above half a minute. An exact 3630-second control preserves the half-even tie, and the existing 90.0001-second documentation example still produces "1.50 minutes".

Month/year decomposition and the default seconds/subsecond path retain their existing behavior. Related #436 addresses sub-day seconds for months/years; #500 addresses exact large integer microsecond counts.

Validation on Windows / Python 3.13.4:

  • New cases before the change: 36 failed, 4 passed; after: 40 passed.
  • Full suite plus source doctests: 932 passed, 2 skipped, with benchmark timing disabled. Catalogs were compiled with GNU msgfmt through the project's translation script; the two translation-update tests require xgettext in the Windows test process.
  • Ruff 0.16.10, Black 26.10.0, mypy 2.4.0 (14 files), and git diff --check: passed.

@Ekko82 Ekko82 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.

I replayed the 40 added parameter combinations in a focused public-API harness on Windows/Python 3.13.9 at 0485b3d. All pass, along with 48 further calls covering one-microsecond steps at half-unit thresholds, %.12f, suppression, both signs and numeric/timedelta inputs. Against base d16e635, 36 of the original combinations and 32 of the additional calls fail.

For example, timedelta(seconds=3630, microseconds=1) now gives 1 hour and 1 minute with minimum_unit="minutes", format="%.0f", while the exact-half control remains 1 hour.

The full pytest suite, localization tests and lint were not run. The pytest file requires freezegun, which is unavailable in this environment.

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