Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

signed_duration: add round method #189

Merged
merged 2 commits into from
Jan 1, 2025
Merged

Conversation

BurntSushi
Copy link
Owner

This adds a new SignedDuration::round method that behaves like Span,
but for time (non-calendar) units only.

For the most part, we just copy Span::round as-is, but without the
largest unit knob (which doesn't make sense for something like
SignedDuration) or the relative datetime knob (which isn't needed
for a duration with all invariant units, as is the case for
SignedDuration). We can even reuse the same implementation for Span
rounding: we convert the duration to a 128-bit signed integer of
nanoseconds, do the rounding and then convert back (and check for
overflow).

Note that we specifically don't both with adding rounding functionality
built into APIs like Zoned::duration_since or
civil::DateTime::duration_until, unlike what we do for Span, since
composition works better for SignedDuration than it does for Span.
Namely, in order to round a Span with calendar units, you need to
provide a relative datetime. By building rounding into the datetime
arithmetic routines, we absolve the caller of needing to manage this
carefully across two distinct operations. Since SignedDuration only
supports invariant units, there is no purpose to providing a relative
datetime and rounding is thus fully orthogonal. Moreover, if we
overloaded methods like Zoned::duration_since, then they would go from
infallible to fallible, which is kind of a bummer.

Closes #187

I commented this out a while ago and meant to remove it since it turned
out to be incorrect. Unfortunately, I don't quite remember the details
of why it is wrong.
This adds a new `SignedDuration::round` method that behaves like `Span`,
but for time (non-calendar) units only.

For the most part, we just copy `Span::round` as-is, but without the
`largest` unit knob (which doesn't make sense for something like
`SignedDuration`) or the `relative` datetime knob (which isn't needed
for a duration with all invariant units, as is the case for
`SignedDuration`). We can even reuse the same implementation for `Span`
rounding: we convert the duration to a 128-bit signed integer of
nanoseconds, do the rounding and then convert back (and check for
overflow).

Note that we specifically don't both with adding rounding functionality
built into APIs like `Zoned::duration_since` or
`civil::DateTime::duration_until`, unlike what we do for `Span`, since
composition works better for `SignedDuration` than it does for `Span`.
Namely, in order to round a `Span` with calendar units, you need to
provide a relative datetime. By building rounding into the datetime
arithmetic routines, we absolve the caller of needing to manage this
carefully across two distinct operations. Since `SignedDuration` only
supports invariant units, there is no purpose to providing a relative
datetime and rounding is thus fully orthogonal. Moreover, if we
overloaded methods like `Zoned::duration_since`, then they would go from
infallible to fallible, which is kind of a bummer.

Closes #187
@BurntSushi BurntSushi merged commit 21218a0 into master Jan 1, 2025
18 checks passed
@BurntSushi BurntSushi deleted the ag/round-signed-duration branch January 1, 2025 19:20
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.

add rounding APIs on SignedDuration
1 participant