Skip to content

fix: preserve microsecond precision in Time differences and selection - #1069

Open
mkantautas wants to merge 2 commits into
python-pendulum:masterfrom
mkantautas:fix/time-diff-microseconds-584-r2
Open

mkantautas wants to merge 2 commits into
python-pendulum:masterfrom
mkantautas:fix/time-diff-microseconds-584-r2

Conversation

@mkantautas

Copy link
Copy Markdown

Fixes #584.

Time.diff() built both totals from hours, minutes and seconds only, so both operands' microseconds were dropped. For example, Time(12, 0, 0, 500000).diff(Time(12, 0, 1)) returned 1 second instead of 0.5. Time - Time uses diff() and had the same error. This adds the microseconds to both totals.

closest() and farthest() compared diff(...).in_seconds(), which truncates to whole seconds. Before this change they could pick the wrong candidate when sub-second parts mattered. For example, Time(12, 0, 0, 900000).closest(Time(12, 0, 1), Time(12, 0, 0)) returned 12:00:00, which is 0.9 seconds away, instead of 12:00:01, which is 0.1 seconds away. With precise differences, truncation would also turn distinct sub-second distances into ties. They now compare total_seconds(), in line with DateTime.closest() and DateTime.farthest(), which already compare full-precision distances. Equal distances still return the second candidate.

Tests:

  • tests/time/test_diff.py and tests/time/test_sub.py cover differences within and across seconds, signed results, the minimum and maximum times, and standard-library time operands.
  • tests/time/test_comparison.py covers closest() and farthest() with sub-second distances, both candidate orders and standard-library time candidates.
  • Six existing diff_for_humans() tests now freeze the clock, matching the equivalent DateTime tests. With microsecond precision, a future comparison against a ticking clock can fall just short of a minute or an hour and show the preceding unit, as DateTime already does.

Validation:

  • Without the fix, the six new difference and subtraction tests fail (65 passed, 6 failed).
  • All results below come from one run with Python 3.13 on Linux and python-dateutil 3.0.0.
  • On master (e06dace), two of the six new comparison tests fail: the cross-second closest() and farthest() cases (24 passed, 2 failed).
  • With the fix, tests/time/test_diff.py, tests/time/test_sub.py and tests/time/test_comparison.py give 97 passed with the pure-Python backend. With the compiled extension, they also give 97 passed; that run used the extension module from the pendulum 3.3.0 wheel, since this change touches no Rust code.
  • Ruff 0.14.11 check and format: clean.
  • Full suite with the pure-Python backend: 1,882 passed, 3 skipped, 1 failed. The failure is tests/test_main.py::test_instance_with_aware_datetime_any_tzinfo, which expects +02:00 and gets Europe/Paris. It fails the same way on unchanged master with the same dependencies.

Pull Request Check List

  • Added tests for changed code.
  • Updated documentation for changed code. Not updated: this restores microsecond precision and adds no API.

This branch has not been deployed

No deployments
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.

Missing microseconds in Time difference

1 participant