Struct SignedDuration
pub struct SignedDuration { /* private fields */ }Expand description
A signed duration of time represented as a 96-bit integer of nanoseconds.
Each duration is made up of a 64-bit integer of whole seconds and a
32-bit integer of fractional nanoseconds less than 1 whole second. Unlike
std::time::Duration, this duration is signed. The sign applies
to the entire duration. That is, either both the seconds and the
fractional nanoseconds are negative or neither are. Stated differently,
it is guaranteed that the signs of SignedDuration::as_secs and
SignedDuration::subsec_nanos are always the same, or one component is
zero. (For example, -1 seconds and 0 nanoseconds, or 0 seconds and
-1 nanoseconds.)
§Parsing and printing
Like the Span type, the SignedDuration type
provides convenient trait implementations of std::str::FromStr and
std::fmt::Display:
use jiff::SignedDuration;
let duration: SignedDuration = "PT2h30m".parse()?;
assert_eq!(duration.to_string(), "PT2H30M");
// Or use the "friendly" format by invoking the alternate:
assert_eq!(format!("{duration:#}"), "2h 30m");
// Parsing automatically supports both the ISO 8601 and "friendly" formats:
let duration: SignedDuration = "2h 30m".parse()?;
assert_eq!(duration, SignedDuration::new(2 * 60 * 60 + 30 * 60, 0));
let duration: SignedDuration = "2 hours, 30 minutes".parse()?;
assert_eq!(duration, SignedDuration::new(2 * 60 * 60 + 30 * 60, 0));
Unlike the Span type, though, only uniform units are supported. This
means that ISO 8601 durations with non-zero units of days or greater cannot
be parsed directly into a SignedDuration:
use jiff::SignedDuration;
assert_eq!(
"P1d".parse::<SignedDuration>().unwrap_err().to_string(),
"parsing ISO 8601 duration in this context requires that \
the duration contain a time component and no components of days or \
greater",
);
To parse such durations, one should first parse them into a Span and
then convert them to a SignedDuration by providing a relative date:
use jiff::{civil::date, Span};
let span: Span = "P1d".parse()?;
let relative = date(2024, 11, 3).in_tz("US/Eastern")?;
let duration = span.to_duration(&relative)?;
// This example also motivates *why* a relative date
// is required. Not all days are the same length!
assert_eq!(duration.to_string(), "PT25H");
The format supported is a variation (nearly a subset) of the duration format specified in ISO 8601 and a Jiff-specific “friendly” format. Here are more examples:
use jiff::SignedDuration;
let durations = [
// ISO 8601
("PT2H30M", SignedDuration::from_secs(2 * 60 * 60 + 30 * 60)),
("PT2.5h", SignedDuration::from_secs(2 * 60 * 60 + 30 * 60)),
("PT1m", SignedDuration::from_mins(1)),
("PT1.5m", SignedDuration::from_secs(90)),
("PT0.0021s", SignedDuration::new(0, 2_100_000)),
("PT0s", SignedDuration::ZERO),
("PT0.000000001s", SignedDuration::from_nanos(1)),
// Jiff's "friendly" format
("2h30m", SignedDuration::from_secs(2 * 60 * 60 + 30 * 60)),
("2 hrs 30 mins", SignedDuration::from_secs(2 * 60 * 60 + 30 * 60)),
("2 hours 30 minutes", SignedDuration::from_secs(2 * 60 * 60 + 30 * 60)),
("2.5h", SignedDuration::from_secs(2 * 60 * 60 + 30 * 60)),
("1m", SignedDuration::from_mins(1)),
("1.5m", SignedDuration::from_secs(90)),
("0.0021s", SignedDuration::new(0, 2_100_000)),
("0s", SignedDuration::ZERO),
("0.000000001s", SignedDuration::from_nanos(1)),
];
for (string, duration) in durations {
let parsed: SignedDuration = string.parse()?;
assert_eq!(duration, parsed, "result of parsing {string:?}");
}
For more details, see the fmt::temporal and
fmt::friendly modules.
§API design
A SignedDuration is, as much as is possible, a replica of the
std::time::Duration API. While there are probably some quirks in the API
of std::time::Duration that could have been fixed here, it is probably
more important that it behave “exactly like a std::time::Duration but
with a sign.” That is, this type mirrors the parallels between signed and
unsigned integer types.
While the goal was to match the std::time::Duration API as much as
possible, there are some differences worth highlighting:
- As stated, a
SignedDurationhas a sign. Therefore, it usesi64andi32instead ofu64andu32to represent its 96-bit integer. - Because it’s signed, the range of possible values is different. For
example, a
SignedDuration::MAXhas a whole number of seconds equivalent toi64::MAX, which is less thanu64::MAX. - There are some additional APIs that don’t make sense on an unsigned
duration, like
SignedDuration::absandSignedDuration::checked_neg. - A
SignedDuration::system_untilroutine is provided as a replacement forstd::time::SystemTime::duration_since, but with signed durations. - Fallible constructors are provided, where as the standard library lacks them.
- Unlike the standard library, this type implements the
std::fmt::Displayandstd::str::FromStrtraits via the ISO 8601 duration format, just like theSpantype does. Also likeSpan, the ISO 8601 duration format is used to implement the serdeSerializeandDeserializetraits when theserdecrate feature is enabled. Additionally, the Jiff-specific [friendly] format is supported when parsing (or deserializing) automatically. And is available as an alternate via thestd::fmt::Displayimplementation, i.e.,format!("{duration:#}"). - The
std::fmt::Debugtrait implementation is a bit different. If you have a problem with it, please file an issue. - At present, there is no
SignedDuration::abs_diffsince there are some API design questions. If you want it, please file an issue.
§When should I use SignedDuration versus Span?
Jiff’s primary duration type is Span. The key differences between it and
SignedDuration are:
- A
Spankeeps track of each individual unit separately. That is, even though1 hour 60 minutesand2 hoursare equivalent durations of time, representing each as aSpancorresponds to two distinct values in memory. And serializing them to the ISO 8601 duration format will also preserve the units, for example,PT1h60mandPT2h. - A
Spansupports non-uniform units like days, weeks, months and years. Since not all days, weeks, months and years have the same length, they cannot be represented by aSignedDuration. In some cases, it may be appropriate, for example, to assume that all days are 24 hours long. But since Jiff sometimes assumes all days are 24 hours (for civil time) and sometimes doesn’t (like forZonedwhen respecting time zones), it would be inappropriate to bake one of those assumptions into aSignedDuration. - A
SignedDurationis a much smaller type than aSpan. Specifically, it’s a 96-bit integer. In contrast, aSpanis much larger since it needs to track each individual unit separately.
Those differences in turn motivate some approximate reasoning for when to
use Span and when to use SignedDuration:
- If you don’t care about keeping track of individual units separately or
don’t need the sophisticated rounding options available on a
Span, it might be simpler and faster to use aSignedDuration. - If you specifically need performance on arithmetic operations involving
datetimes and durations, even if it’s not as convenient or correct, then it
might make sense to use a
SignedDuration. - If you need to perform arithmetic using a
std::time::Durationand otherwise don’t need the functionality of aSpan, it might make sense to first convert thestd::time::Durationto aSignedDuration, and then use one of the corresponding operations defined forSignedDurationon the datetime types. (They all support it.)
In general, a Span provides more functionality and is overall more
flexible. A Span can also deserialize all forms of ISO 8601 durations
(as long as they’re within Jiff’s limits), including durations with units
of years, months, weeks and days. A SignedDuration, by contrast, only
supports units up to and including hours.
§Integration with datetime types
All datetime types that support arithmetic using Span also
support arithmetic using SignedDuration (and std::time::Duration).
For example, here’s how to add an absolute duration to a [Timestamp]:
use jiff::{SignedDuration, Timestamp};
let ts1 = Timestamp::from_second(1_123_456_789)?;
assert_eq!(ts1.to_string(), "2005-08-07T23:19:49Z");
let duration = SignedDuration::new(59, 999_999_999);
// Timestamp::checked_add is polymorphic! It can accept a
// span or a duration.
let ts2 = ts1.checked_add(duration)?;
assert_eq!(ts2.to_string(), "2005-08-07T23:20:48.999999999Z");
The same API pattern works with [Zoned], [DateTime], [Date] and
[Time].
§Interaction with daylight saving time and time zone transitions
A SignedDuration always corresponds to a specific number of nanoseconds.
Since a [Zoned] is always a precise instant in time, adding a SignedDuration
to a Zoned always behaves by adding the nanoseconds from the duration to
the timestamp inside of Zoned. Consider 2024-03-10 in US/Eastern.
At 02:00:00, daylight saving time came into effect, switching the UTC
offset for the region from -05 to -04. This has the effect of skipping
an hour on the clocks:
use jiff::{civil::date, SignedDuration};
let zdt = date(2024, 3, 10).at(1, 59, 0, 0).in_tz("US/Eastern")?;
assert_eq!(
zdt.checked_add(SignedDuration::from_hours(1))?,
// Time on the clock skipped an hour, but in this time
// zone, 03:59 is actually precisely 1 hour later than
// 01:59.
date(2024, 3, 10).at(3, 59, 0, 0).in_tz("US/Eastern")?,
);
// The same would apply if you used a `Span`:
assert_eq!(
zdt.checked_add(jiff::Span::new().hours(1))?,
// Time on the clock skipped an hour, but in this time
// zone, 03:59 is actually precisely 1 hour later than
// 01:59.
date(2024, 3, 10).at(3, 59, 0, 0).in_tz("US/Eastern")?,
);
Where time zones might have a more interesting effect is in the definition
of the “day” itself. If, for example, you encode the notion that a day is
always 24 hours into your arithmetic, you might get unexpected results.
For example, let’s say you want to find the datetime precisely one week
after 2024-03-08T17:00 in the US/Eastern time zone. You might be
tempted to just ask for the time that is 7 * 24 hours later:
use jiff::{civil::date, SignedDuration};
let zdt = date(2024, 3, 8).at(17, 0, 0, 0).in_tz("US/Eastern")?;
assert_eq!(
zdt.checked_add(SignedDuration::from_hours(7 * 24))?,
date(2024, 3, 15).at(18, 0, 0, 0).in_tz("US/Eastern")?,
);
Notice that you get 18:00 and not 17:00! That’s because, as shown
in the previous example, 2024-03-10 was only 23 hours long. That in turn
implies that the week starting from 2024-03-08 is only 7 * 24 - 1 hours
long. This can be tricky to get correct with absolute durations like
SignedDuration, but a Span will handle this for you automatically:
use jiff::{civil::date, ToSpan};
let zdt = date(2024, 3, 8).at(17, 0, 0, 0).in_tz("US/Eastern")?;
assert_eq!(
zdt.checked_add(1.week())?,
// The expected time!
date(2024, 3, 15).at(17, 0, 0, 0).in_tz("US/Eastern")?,
);
A Span achieves this by keeping track of individual units. Unlike a
SignedDuration, it is not just a simple count of nanoseconds. It is a
“bag” of individual units, and the arithmetic operations defined on a
Span for Zoned know how to interpret “day” in a particular time zone
at a particular instant in time.
With that said, the above does not mean that using a SignedDuration is
always wrong. For example, if you’re dealing with units of hours or lower,
then all such units are uniform and so you’ll always get the same results
as with a Span. And using a SignedDuration can sometimes be simpler
or faster.
Implementations§
§impl SignedDuration
impl SignedDuration
pub const ZERO: SignedDuration
pub const ZERO: SignedDuration
A duration of zero time.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::ZERO;
assert!(duration.is_zero());
assert_eq!(duration.as_secs(), 0);
assert_eq!(duration.subsec_nanos(), 0);pub const MIN: SignedDuration
pub const MIN: SignedDuration
The minimum possible duration. Or the “most negative” duration.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::MIN;
assert_eq!(duration.as_secs(), i64::MIN);
assert_eq!(duration.subsec_nanos(), -999_999_999);pub const MAX: SignedDuration
pub const MAX: SignedDuration
The maximum possible duration.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::MAX;
assert_eq!(duration.as_secs(), i64::MAX);
assert_eq!(duration.subsec_nanos(), 999_999_999);pub const fn new(secs: i64, nanos: i32) -> SignedDuration
pub const fn new(secs: i64, nanos: i32) -> SignedDuration
Creates a new SignedDuration from the given number of whole seconds
and additional nanoseconds.
If the absolute value of the nanoseconds is greater than or equal to 1 second, then the excess balances into the number of whole seconds.
§Panics
When the absolute value of the nanoseconds is greater than or equal
to 1 second and the excess that carries over to the number of whole
seconds overflows i64.
This never panics when nanos is less than 1_000_000_000.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 0);
assert_eq!(duration.as_secs(), 12);
assert_eq!(duration.subsec_nanos(), 0);
let duration = SignedDuration::new(12, -1);
assert_eq!(duration.as_secs(), 11);
assert_eq!(duration.subsec_nanos(), 999_999_999);
let duration = SignedDuration::new(12, 1_000_000_000);
assert_eq!(duration.as_secs(), 13);
assert_eq!(duration.subsec_nanos(), 0);pub const fn from_secs(secs: i64) -> SignedDuration
pub const fn from_secs(secs: i64) -> SignedDuration
Creates a new SignedDuration from the given number of whole seconds.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::from_secs(12);
assert_eq!(duration.as_secs(), 12);
assert_eq!(duration.subsec_nanos(), 0);pub const fn from_millis(millis: i64) -> SignedDuration
pub const fn from_millis(millis: i64) -> SignedDuration
Creates a new SignedDuration from the given number of whole
milliseconds.
Note that since this accepts an i64, this method cannot be used
to construct the full range of possible signed duration values. In
particular, SignedDuration::as_millis returns an i128, and this
may be a value that would otherwise overflow an i64.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::from_millis(12_456);
assert_eq!(duration.as_secs(), 12);
assert_eq!(duration.subsec_nanos(), 456_000_000);
let duration = SignedDuration::from_millis(-12_456);
assert_eq!(duration.as_secs(), -12);
assert_eq!(duration.subsec_nanos(), -456_000_000);pub const fn from_millis_i128(millis: i128) -> SignedDuration
pub const fn from_millis_i128(millis: i128) -> SignedDuration
Creates a new SignedDuration from a given number of whole
milliseconds in 128 bits.
§Panics
When the given number of milliseconds is greater than the number of
nanoseconds represented by SignedDuration::MAX or smaller than
SignedDuration::MIN.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::from_millis_i128(12_456);
assert_eq!(duration.as_secs(), 12);
assert_eq!(duration.subsec_millis(), 456);
let duration = SignedDuration::from_millis_i128(-12_456);
assert_eq!(duration.as_secs(), -12);
assert_eq!(duration.subsec_millis(), -456);
// This input is bigger than what 64-bits can fit,
// and so demonstrates its utility in a case when
// `SignedDuration::from_nanos` cannot be used.
let duration = SignedDuration::from_millis_i128(
1_208_925_819_614_629_174,
);
assert_eq!(duration.as_secs(), 1_208_925_819_614_629);
assert_eq!(duration.subsec_millis(), 174);pub const fn from_micros(micros: i64) -> SignedDuration
pub const fn from_micros(micros: i64) -> SignedDuration
Creates a new SignedDuration from the given number of whole
microseconds.
Note that since this accepts an i64, this method cannot be used
to construct the full range of possible signed duration values. In
particular, SignedDuration::as_micros returns an i128, and this
may be a value that would otherwise overflow an i64.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::from_micros(12_000_456);
assert_eq!(duration.as_secs(), 12);
assert_eq!(duration.subsec_nanos(), 456_000);
let duration = SignedDuration::from_micros(-12_000_456);
assert_eq!(duration.as_secs(), -12);
assert_eq!(duration.subsec_nanos(), -456_000);pub const fn from_micros_i128(micros: i128) -> SignedDuration
pub const fn from_micros_i128(micros: i128) -> SignedDuration
Creates a new SignedDuration from a given number of whole
microseconds in 128 bits.
§Panics
When the given number of microseconds is greater than the number of
nanoseconds represented by SignedDuration::MAX or smaller than
SignedDuration::MIN.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::from_micros_i128(12_000_456);
assert_eq!(duration.as_secs(), 12);
assert_eq!(duration.subsec_micros(), 456);
let duration = SignedDuration::from_micros_i128(-12_000_456);
assert_eq!(duration.as_secs(), -12);
assert_eq!(duration.subsec_micros(), -456);
// This input is bigger than what 64-bits can fit,
// and so demonstrates its utility in a case when
// `SignedDuration::from_nanos` cannot be used.
let duration = SignedDuration::from_micros_i128(
1_208_925_819_614_629_174_706,
);
assert_eq!(duration.as_secs(), 1_208_925_819_614_629);
assert_eq!(duration.subsec_micros(), 174_706);pub const fn from_nanos(nanos: i64) -> SignedDuration
pub const fn from_nanos(nanos: i64) -> SignedDuration
Creates a new SignedDuration from the given number of whole
nanoseconds.
Note that since this accepts an i64, this method cannot be used
to construct the full range of possible signed duration values. In
particular, SignedDuration::as_nanos returns an i128, which may
be a value that would otherwise overflow an i64. To correctly
round-trip through an integer number of nanoseconds, use
SignedDuration::from_nanos_i128.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::from_nanos(12_000_000_456);
assert_eq!(duration.as_secs(), 12);
assert_eq!(duration.subsec_nanos(), 456);
let duration = SignedDuration::from_nanos(-12_000_000_456);
assert_eq!(duration.as_secs(), -12);
assert_eq!(duration.subsec_nanos(), -456);pub const fn from_nanos_i128(nanos: i128) -> SignedDuration
pub const fn from_nanos_i128(nanos: i128) -> SignedDuration
Creates a new SignedDuration from a given number of whole
nanoseconds in 128 bits.
§Panics
When the given number of nanoseconds is greater than the number of
nanoseconds represented by SignedDuration::MAX or smaller than
SignedDuration::MIN.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::from_nanos_i128(12_000_000_456);
assert_eq!(duration.as_secs(), 12);
assert_eq!(duration.subsec_nanos(), 456);
let duration = SignedDuration::from_nanos_i128(-12_000_000_456);
assert_eq!(duration.as_secs(), -12);
assert_eq!(duration.subsec_nanos(), -456);
// This input is bigger than what 64-bits can fit,
// and so demonstrates its utility in a case when
// `SignedDuration::from_nanos` cannot be used.
let duration = SignedDuration::from_nanos_i128(
1_208_925_819_614_629_174_706_176,
);
assert_eq!(duration.as_secs(), 1_208_925_819_614_629);
assert_eq!(duration.subsec_nanos(), 174_706_176);pub const fn from_hours(hours: i64) -> SignedDuration
pub const fn from_hours(hours: i64) -> SignedDuration
Creates a new SignedDuration from the given number of hours. Every
hour is exactly 3,600 seconds.
§Panics
Panics if the number of hours, after being converted to nanoseconds,
overflows the minimum or maximum SignedDuration values.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::from_hours(24);
assert_eq!(duration.as_secs(), 86_400);
assert_eq!(duration.subsec_nanos(), 0);
let duration = SignedDuration::from_hours(-24);
assert_eq!(duration.as_secs(), -86_400);
assert_eq!(duration.subsec_nanos(), 0);pub const fn from_mins(mins: i64) -> SignedDuration
pub const fn from_mins(mins: i64) -> SignedDuration
Creates a new SignedDuration from the given number of minutes. Every
minute is exactly 60 seconds.
§Panics
Panics if the number of minutes, after being converted to nanoseconds,
overflows the minimum or maximum SignedDuration values.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::from_mins(1_440);
assert_eq!(duration.as_secs(), 86_400);
assert_eq!(duration.subsec_nanos(), 0);
let duration = SignedDuration::from_mins(-1_440);
assert_eq!(duration.as_secs(), -86_400);
assert_eq!(duration.subsec_nanos(), 0);pub const fn is_zero(&self) -> bool
pub const fn is_zero(&self) -> bool
Returns true if this duration spans no time.
§Example
use jiff::SignedDuration;
assert!(SignedDuration::ZERO.is_zero());
assert!(!SignedDuration::MIN.is_zero());
assert!(!SignedDuration::MAX.is_zero());pub const fn as_secs(&self) -> i64
pub const fn as_secs(&self) -> i64
Returns the number of whole seconds in this duration.
The value returned is negative when the duration is negative.
This does not include any fractional component corresponding to units
less than a second. To access those, use one of the subsec methods
such as SignedDuration::subsec_nanos.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 999_999_999);
assert_eq!(duration.as_secs(), 12);
let duration = SignedDuration::new(-12, -999_999_999);
assert_eq!(duration.as_secs(), -12);pub const fn subsec_millis(&self) -> i32
pub const fn subsec_millis(&self) -> i32
Returns the fractional part of this duration in whole milliseconds.
The value returned is negative when the duration is negative. It is
guaranteed that the range of the value returned is in the inclusive
range -999..=999.
To get the length of the total duration represented in milliseconds,
use SignedDuration::as_millis.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 123_456_789);
assert_eq!(duration.subsec_millis(), 123);
let duration = SignedDuration::new(-12, -123_456_789);
assert_eq!(duration.subsec_millis(), -123);pub const fn subsec_micros(&self) -> i32
pub const fn subsec_micros(&self) -> i32
Returns the fractional part of this duration in whole microseconds.
The value returned is negative when the duration is negative. It is
guaranteed that the range of the value returned is in the inclusive
range -999_999..=999_999.
To get the length of the total duration represented in microseconds,
use SignedDuration::as_micros.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 123_456_789);
assert_eq!(duration.subsec_micros(), 123_456);
let duration = SignedDuration::new(-12, -123_456_789);
assert_eq!(duration.subsec_micros(), -123_456);pub const fn subsec_nanos(&self) -> i32
pub const fn subsec_nanos(&self) -> i32
Returns the fractional part of this duration in whole nanoseconds.
The value returned is negative when the duration is negative. It is
guaranteed that the range of the value returned is in the inclusive
range -999_999_999..=999_999_999.
To get the length of the total duration represented in nanoseconds,
use SignedDuration::as_nanos.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 123_456_789);
assert_eq!(duration.subsec_nanos(), 123_456_789);
let duration = SignedDuration::new(-12, -123_456_789);
assert_eq!(duration.subsec_nanos(), -123_456_789);pub const fn as_millis(&self) -> i128
pub const fn as_millis(&self) -> i128
Returns the total duration in units of whole milliseconds.
The value returned is negative when the duration is negative.
To get only the fractional component of this duration in units of
whole milliseconds, use SignedDuration::subsec_millis.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 123_456_789);
assert_eq!(duration.as_millis(), 12_123);
let duration = SignedDuration::new(-12, -123_456_789);
assert_eq!(duration.as_millis(), -12_123);pub const fn as_micros(&self) -> i128
pub const fn as_micros(&self) -> i128
Returns the total duration in units of whole microseconds.
The value returned is negative when the duration is negative.
To get only the fractional component of this duration in units of
whole microseconds, use SignedDuration::subsec_micros.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 123_456_789);
assert_eq!(duration.as_micros(), 12_123_456);
let duration = SignedDuration::new(-12, -123_456_789);
assert_eq!(duration.as_micros(), -12_123_456);pub const fn as_nanos(&self) -> i128
pub const fn as_nanos(&self) -> i128
Returns the total duration in units of whole nanoseconds.
The value returned is negative when the duration is negative.
To get only the fractional component of this duration in units of
whole nanoseconds, use SignedDuration::subsec_nanos.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 123_456_789);
assert_eq!(duration.as_nanos(), 12_123_456_789);
let duration = SignedDuration::new(-12, -123_456_789);
assert_eq!(duration.as_nanos(), -12_123_456_789);pub const fn checked_add(self, rhs: SignedDuration) -> Option<SignedDuration>
pub const fn checked_add(self, rhs: SignedDuration) -> Option<SignedDuration>
Add two signed durations together. If overflow occurs, then None is
returned.
§Example
use jiff::SignedDuration;
let duration1 = SignedDuration::new(12, 500_000_000);
let duration2 = SignedDuration::new(0, 500_000_000);
assert_eq!(
duration1.checked_add(duration2),
Some(SignedDuration::new(13, 0)),
);
let duration1 = SignedDuration::MAX;
let duration2 = SignedDuration::new(0, 1);
assert_eq!(duration1.checked_add(duration2), None);pub const fn saturating_add(self, rhs: SignedDuration) -> SignedDuration
pub const fn saturating_add(self, rhs: SignedDuration) -> SignedDuration
Add two signed durations together. If overflow occurs, then arithmetic saturates.
§Example
use jiff::SignedDuration;
let duration1 = SignedDuration::MAX;
let duration2 = SignedDuration::new(0, 1);
assert_eq!(duration1.saturating_add(duration2), SignedDuration::MAX);
let duration1 = SignedDuration::MIN;
let duration2 = SignedDuration::new(0, -1);
assert_eq!(duration1.saturating_add(duration2), SignedDuration::MIN);pub const fn checked_sub(self, rhs: SignedDuration) -> Option<SignedDuration>
pub const fn checked_sub(self, rhs: SignedDuration) -> Option<SignedDuration>
Subtract one signed duration from another. If overflow occurs, then
None is returned.
§Example
use jiff::SignedDuration;
let duration1 = SignedDuration::new(12, 500_000_000);
let duration2 = SignedDuration::new(0, 500_000_000);
assert_eq!(
duration1.checked_sub(duration2),
Some(SignedDuration::new(12, 0)),
);
let duration1 = SignedDuration::MIN;
let duration2 = SignedDuration::new(0, 1);
assert_eq!(duration1.checked_sub(duration2), None);pub const fn saturating_sub(self, rhs: SignedDuration) -> SignedDuration
pub const fn saturating_sub(self, rhs: SignedDuration) -> SignedDuration
Add two signed durations together. If overflow occurs, then arithmetic saturates.
§Example
use jiff::SignedDuration;
let duration1 = SignedDuration::MAX;
let duration2 = SignedDuration::new(0, -1);
assert_eq!(duration1.saturating_sub(duration2), SignedDuration::MAX);
let duration1 = SignedDuration::MIN;
let duration2 = SignedDuration::new(0, 1);
assert_eq!(duration1.saturating_sub(duration2), SignedDuration::MIN);pub const fn checked_mul(self, rhs: i32) -> Option<SignedDuration>
pub const fn checked_mul(self, rhs: i32) -> Option<SignedDuration>
Multiply this signed duration by an integer. If the multiplication
overflows, then None is returned.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 500_000_000);
assert_eq!(
duration.checked_mul(2),
Some(SignedDuration::new(25, 0)),
);pub const fn saturating_mul(self, rhs: i32) -> SignedDuration
pub const fn saturating_mul(self, rhs: i32) -> SignedDuration
Multiply this signed duration by an integer. If the multiplication overflows, then the result saturates to either the minimum or maximum duration depending on the sign of the product.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(i64::MAX, 0);
assert_eq!(duration.saturating_mul(2), SignedDuration::MAX);
assert_eq!(duration.saturating_mul(-2), SignedDuration::MIN);
let duration = SignedDuration::new(i64::MIN, 0);
assert_eq!(duration.saturating_mul(2), SignedDuration::MIN);
assert_eq!(duration.saturating_mul(-2), SignedDuration::MAX);pub const fn checked_div(self, rhs: i32) -> Option<SignedDuration>
pub const fn checked_div(self, rhs: i32) -> Option<SignedDuration>
Divide this duration by an integer. If the division overflows, then
None is returned.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 500_000_000);
assert_eq!(
duration.checked_div(2),
Some(SignedDuration::new(6, 250_000_000)),
);
assert_eq!(
duration.checked_div(-2),
Some(SignedDuration::new(-6, -250_000_000)),
);
let duration = SignedDuration::new(-12, -500_000_000);
assert_eq!(
duration.checked_div(2),
Some(SignedDuration::new(-6, -250_000_000)),
);
assert_eq!(
duration.checked_div(-2),
Some(SignedDuration::new(6, 250_000_000)),
);pub fn as_secs_f64(&self) -> f64
pub fn as_secs_f64(&self) -> f64
Returns the number of seconds, with a possible fractional nanosecond component, represented by this signed duration as a 64-bit float.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 123_456_789);
assert_eq!(duration.as_secs_f64(), 12.123456789);
let duration = SignedDuration::new(-12, -123_456_789);
assert_eq!(duration.as_secs_f64(), -12.123456789);pub fn as_secs_f32(&self) -> f32
pub fn as_secs_f32(&self) -> f32
Returns the number of seconds, with a possible fractional nanosecond component, represented by this signed duration as a 32-bit float.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 123_456_789);
assert_eq!(duration.as_secs_f32(), 12.123456789);
let duration = SignedDuration::new(-12, -123_456_789);
assert_eq!(duration.as_secs_f32(), -12.123456789);pub fn as_millis_f64(&self) -> f64
pub fn as_millis_f64(&self) -> f64
Returns the number of milliseconds, with a possible fractional nanosecond component, represented by this signed duration as a 64-bit float.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 123_456_789);
assert_eq!(duration.as_millis_f64(), 12123.456789);
let duration = SignedDuration::new(-12, -123_456_789);
assert_eq!(duration.as_millis_f64(), -12123.456789);pub fn as_millis_f32(&self) -> f32
pub fn as_millis_f32(&self) -> f32
Returns the number of milliseconds, with a possible fractional nanosecond component, represented by this signed duration as a 32-bit float.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 123_456_789);
assert_eq!(duration.as_millis_f32(), 12123.456789);
let duration = SignedDuration::new(-12, -123_456_789);
assert_eq!(duration.as_millis_f32(), -12123.456789);pub fn from_secs_f64(secs: f64) -> SignedDuration
pub fn from_secs_f64(secs: f64) -> SignedDuration
Returns a signed duration corresponding to the number of seconds represented as a 64-bit float. The number given may have a fractional nanosecond component.
§Panics
If the given float overflows the minimum or maximum signed duration values, then this panics.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::from_secs_f64(12.123456789);
assert_eq!(duration.as_secs(), 12);
assert_eq!(duration.subsec_nanos(), 123_456_789);
let duration = SignedDuration::from_secs_f64(-12.123456789);
assert_eq!(duration.as_secs(), -12);
assert_eq!(duration.subsec_nanos(), -123_456_789);
pub fn from_secs_f32(secs: f32) -> SignedDuration
pub fn from_secs_f32(secs: f32) -> SignedDuration
Returns a signed duration corresponding to the number of seconds represented as a 32-bit float. The number given may have a fractional nanosecond component.
§Panics
If the given float overflows the minimum or maximum signed duration values, then this panics.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::from_secs_f32(12.123456789);
assert_eq!(duration.as_secs(), 12);
// loss of precision!
assert_eq!(duration.subsec_nanos(), 123_456_952);
let duration = SignedDuration::from_secs_f32(-12.123456789);
assert_eq!(duration.as_secs(), -12);
// loss of precision!
assert_eq!(duration.subsec_nanos(), -123_456_952);
pub fn try_from_secs_f64(secs: f64) -> Result<SignedDuration, Error>
pub fn try_from_secs_f64(secs: f64) -> Result<SignedDuration, Error>
Returns a signed duration corresponding to the number of seconds represented as a 64-bit float. The number given may have a fractional nanosecond component.
If the given float overflows the minimum or maximum signed duration values, then an error is returned.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::try_from_secs_f64(12.123456789)?;
assert_eq!(duration.as_secs(), 12);
assert_eq!(duration.subsec_nanos(), 123_456_789);
let duration = SignedDuration::try_from_secs_f64(-12.123456789)?;
assert_eq!(duration.as_secs(), -12);
assert_eq!(duration.subsec_nanos(), -123_456_789);
assert!(SignedDuration::try_from_secs_f64(f64::NAN).is_err());
assert!(SignedDuration::try_from_secs_f64(f64::INFINITY).is_err());
assert!(SignedDuration::try_from_secs_f64(f64::NEG_INFINITY).is_err());
assert!(SignedDuration::try_from_secs_f64(f64::MIN).is_err());
assert!(SignedDuration::try_from_secs_f64(f64::MAX).is_err());
pub fn try_from_secs_f32(secs: f32) -> Result<SignedDuration, Error>
pub fn try_from_secs_f32(secs: f32) -> Result<SignedDuration, Error>
Returns a signed duration corresponding to the number of seconds represented as a 32-bit float. The number given may have a fractional nanosecond component.
If the given float overflows the minimum or maximum signed duration values, then an error is returned.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::try_from_secs_f32(12.123456789)?;
assert_eq!(duration.as_secs(), 12);
// loss of precision!
assert_eq!(duration.subsec_nanos(), 123_456_952);
let duration = SignedDuration::try_from_secs_f32(-12.123456789)?;
assert_eq!(duration.as_secs(), -12);
// loss of precision!
assert_eq!(duration.subsec_nanos(), -123_456_952);
assert!(SignedDuration::try_from_secs_f32(f32::NAN).is_err());
assert!(SignedDuration::try_from_secs_f32(f32::INFINITY).is_err());
assert!(SignedDuration::try_from_secs_f32(f32::NEG_INFINITY).is_err());
assert!(SignedDuration::try_from_secs_f32(f32::MIN).is_err());
assert!(SignedDuration::try_from_secs_f32(f32::MAX).is_err());
pub fn mul_f64(self, rhs: f64) -> SignedDuration
pub fn mul_f64(self, rhs: f64) -> SignedDuration
Returns the result of multiplying this duration by the given 64-bit float.
§Panics
This panics if the result is not finite or overflows a
SignedDuration.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 300_000_000);
assert_eq!(
duration.mul_f64(2.0),
SignedDuration::new(24, 600_000_000),
);
assert_eq!(
duration.mul_f64(-2.0),
SignedDuration::new(-24, -600_000_000),
);pub fn mul_f32(self, rhs: f32) -> SignedDuration
pub fn mul_f32(self, rhs: f32) -> SignedDuration
Returns the result of multiplying this duration by the given 32-bit float.
§Panics
This panics if the result is not finite or overflows a
SignedDuration.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 300_000_000);
assert_eq!(
duration.mul_f32(2.0),
// loss of precision!
SignedDuration::new(24, 600_000_384),
);
assert_eq!(
duration.mul_f32(-2.0),
// loss of precision!
SignedDuration::new(-24, -600_000_384),
);pub fn div_f64(self, rhs: f64) -> SignedDuration
pub fn div_f64(self, rhs: f64) -> SignedDuration
Returns the result of dividing this duration by the given 64-bit float.
§Panics
This panics if the result is not finite or overflows a
SignedDuration.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 300_000_000);
assert_eq!(
duration.div_f64(2.0),
SignedDuration::new(6, 150_000_000),
);
assert_eq!(
duration.div_f64(-2.0),
SignedDuration::new(-6, -150_000_000),
);pub fn div_f32(self, rhs: f32) -> SignedDuration
pub fn div_f32(self, rhs: f32) -> SignedDuration
Returns the result of dividing this duration by the given 32-bit float.
§Panics
This panics if the result is not finite or overflows a
SignedDuration.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 300_000_000);
assert_eq!(
duration.div_f32(2.0),
// loss of precision!
SignedDuration::new(6, 150_000_096),
);
assert_eq!(
duration.div_f32(-2.0),
// loss of precision!
SignedDuration::new(-6, -150_000_096),
);pub fn div_duration_f64(self, rhs: SignedDuration) -> f64
pub fn div_duration_f64(self, rhs: SignedDuration) -> f64
Divides this signed duration by another signed duration and returns the corresponding 64-bit float result.
§Example
use jiff::SignedDuration;
let duration1 = SignedDuration::new(12, 600_000_000);
let duration2 = SignedDuration::new(6, 300_000_000);
assert_eq!(duration1.div_duration_f64(duration2), 2.0);
let duration1 = SignedDuration::new(-12, -600_000_000);
let duration2 = SignedDuration::new(6, 300_000_000);
assert_eq!(duration1.div_duration_f64(duration2), -2.0);
let duration1 = SignedDuration::new(-12, -600_000_000);
let duration2 = SignedDuration::new(-6, -300_000_000);
assert_eq!(duration1.div_duration_f64(duration2), 2.0);pub fn div_duration_f32(self, rhs: SignedDuration) -> f32
pub fn div_duration_f32(self, rhs: SignedDuration) -> f32
Divides this signed duration by another signed duration and returns the corresponding 32-bit float result.
§Example
use jiff::SignedDuration;
let duration1 = SignedDuration::new(12, 600_000_000);
let duration2 = SignedDuration::new(6, 300_000_000);
assert_eq!(duration1.div_duration_f32(duration2), 2.0);
let duration1 = SignedDuration::new(-12, -600_000_000);
let duration2 = SignedDuration::new(6, 300_000_000);
assert_eq!(duration1.div_duration_f32(duration2), -2.0);
let duration1 = SignedDuration::new(-12, -600_000_000);
let duration2 = SignedDuration::new(-6, -300_000_000);
assert_eq!(duration1.div_duration_f32(duration2), 2.0);§impl SignedDuration
Additional APIs not found in the standard library.
impl SignedDuration
Additional APIs not found in the standard library.
In some cases, these APIs exist as a result of the fact that this duration is signed.
pub const fn try_from_hours(hours: i64) -> Option<SignedDuration>
pub const fn try_from_hours(hours: i64) -> Option<SignedDuration>
Fallibly creates a new SignedDuration from a 64-bit integer number
of hours.
If the number of hours is less than SignedDuration::MIN or
more than SignedDuration::MAX, then this returns None.
§Example
use jiff::SignedDuration;
assert_eq!(SignedDuration::try_from_hours(i64::MAX), None);pub const fn try_from_mins(mins: i64) -> Option<SignedDuration>
pub const fn try_from_mins(mins: i64) -> Option<SignedDuration>
Fallibly creates a new SignedDuration from a 64-bit integer number
of minutes.
If the number of minutes is less than SignedDuration::MIN or
more than SignedDuration::MAX, then this returns None.
§Example
use jiff::SignedDuration;
assert_eq!(SignedDuration::try_from_mins(i64::MAX), None);pub const fn try_from_millis_i128(millis: i128) -> Option<SignedDuration>
pub const fn try_from_millis_i128(millis: i128) -> Option<SignedDuration>
Fallibly creates a new SignedDuration from a 128-bit integer number
of milliseconds.
If the number of milliseconds is less than SignedDuration::MIN or
more than SignedDuration::MAX, then this returns None.
§Example
use jiff::SignedDuration;
assert_eq!(SignedDuration::try_from_millis_i128(i128::MAX), None);pub const fn try_from_micros_i128(micros: i128) -> Option<SignedDuration>
pub const fn try_from_micros_i128(micros: i128) -> Option<SignedDuration>
Fallibly creates a new SignedDuration from a 128-bit integer number
of microseconds.
If the number of microseconds is less than SignedDuration::MIN or
more than SignedDuration::MAX, then this returns None.
§Example
use jiff::SignedDuration;
assert_eq!(SignedDuration::try_from_micros_i128(i128::MAX), None);pub const fn try_from_nanos_i128(nanos: i128) -> Option<SignedDuration>
pub const fn try_from_nanos_i128(nanos: i128) -> Option<SignedDuration>
Fallibly creates a new SignedDuration from a 128-bit integer number
of nanoseconds.
If the number of nanoseconds is less than SignedDuration::MIN or
more than SignedDuration::MAX, then this returns None.
§Example
use jiff::SignedDuration;
assert_eq!(SignedDuration::try_from_nanos_i128(i128::MAX), None);pub const fn as_hours(&self) -> i64
pub const fn as_hours(&self) -> i64
Returns the number of whole hours in this duration.
The value returned is negative when the duration is negative.
This does not include any fractional component corresponding to units less than an hour.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(86_400, 999_999_999);
assert_eq!(duration.as_hours(), 24);
let duration = SignedDuration::new(-86_400, -999_999_999);
assert_eq!(duration.as_hours(), -24);pub const fn as_mins(&self) -> i64
pub const fn as_mins(&self) -> i64
Returns the number of whole minutes in this duration.
The value returned is negative when the duration is negative.
This does not include any fractional component corresponding to units less than a minute.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(3_600, 999_999_999);
assert_eq!(duration.as_mins(), 60);
let duration = SignedDuration::new(-3_600, -999_999_999);
assert_eq!(duration.as_mins(), -60);pub const fn abs(self) -> SignedDuration
pub const fn abs(self) -> SignedDuration
Returns the absolute value of this signed duration.
If this duration isn’t negative, then this returns the original duration unchanged.
§Panics
This panics when the seconds component of this signed duration is
equal to i64::MIN.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(1, -1_999_999_999);
assert_eq!(duration.abs(), SignedDuration::new(0, 999_999_999));pub const fn unsigned_abs(self) -> Duration
pub const fn unsigned_abs(self) -> Duration
Returns the absolute value of this signed duration as a
std::time::Duration. More specifically, this routine cannot
panic because the absolute value of SignedDuration::MIN is
representable in a std::time::Duration.
§Example
use std::time::Duration;
use jiff::SignedDuration;
let duration = SignedDuration::MIN;
assert_eq!(
duration.unsigned_abs(),
Duration::new(i64::MIN.unsigned_abs(), 999_999_999),
);pub const fn checked_neg(self) -> Option<SignedDuration>
pub const fn checked_neg(self) -> Option<SignedDuration>
Returns this duration with its sign flipped.
If this duration is zero, then this returns the duration unchanged.
This returns none if the negation does not exist. This occurs in
precisely the cases when SignedDuration::as_secs is equal to
i64::MIN.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(12, 123_456_789);
assert_eq!(
duration.checked_neg(),
Some(SignedDuration::new(-12, -123_456_789)),
);
let duration = SignedDuration::new(-12, -123_456_789);
assert_eq!(
duration.checked_neg(),
Some(SignedDuration::new(12, 123_456_789)),
);
// Negating the minimum seconds isn't possible.
assert_eq!(SignedDuration::MIN.checked_neg(), None);pub const fn signum(self) -> i8
pub const fn signum(self) -> i8
Returns a number that represents the sign of this duration.
- When
SignedDuration::is_zerois true, this returns0. - When
SignedDuration::is_positiveis true, this returns1. - When
SignedDuration::is_negativeis true, this returns-1.
The above cases are mutually exclusive.
§Example
use jiff::SignedDuration;
assert_eq!(0, SignedDuration::ZERO.signum());pub const fn is_positive(&self) -> bool
pub const fn is_positive(&self) -> bool
Returns true when this duration is positive. That is, greater than
SignedDuration::ZERO.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(0, 1);
assert!(duration.is_positive());pub const fn is_negative(&self) -> bool
pub const fn is_negative(&self) -> bool
Returns true when this duration is negative. That is, less than
SignedDuration::ZERO.
§Example
use jiff::SignedDuration;
let duration = SignedDuration::new(0, -1);
assert!(duration.is_negative());§impl SignedDuration
Additional APIs for computing the duration between date and time values.
impl SignedDuration
Additional APIs for computing the duration between date and time values.
pub fn system_until(
time1: SystemTime,
time2: SystemTime,
) -> Result<SignedDuration, Error>
Available on crate feature std only.
pub fn system_until( time1: SystemTime, time2: SystemTime, ) -> Result<SignedDuration, Error>
std only.Returns the duration from time1 until time2 where the times are
std::time::SystemTime values from the standard library.
§Errors
This returns an error if the difference between the two time values overflows the signed duration limits.
§Example
use std::time::{Duration, SystemTime};
use jiff::SignedDuration;
let time1 = SystemTime::UNIX_EPOCH;
let time2 = time1.checked_add(Duration::from_secs(86_400)).unwrap();
assert_eq!(
SignedDuration::system_until(time1, time2)?,
SignedDuration::from_hours(24),
);
§impl SignedDuration
Jiff specific APIs.
impl SignedDuration
Jiff specific APIs.
pub fn round<R>(self, options: R) -> Result<SignedDuration, Error>where
R: Into<SignedDurationRound>,
pub fn round<R>(self, options: R) -> Result<SignedDuration, Error>where
R: Into<SignedDurationRound>,
Returns a new signed duration that is rounded according to the given configuration.
Rounding a duration has a number of parameters, all of which are optional. When no parameters are given, then no rounding is done, and the duration as given is returned. That is, it’s a no-op.
As is consistent with SignedDuration itself, rounding only supports
time units, i.e., units of hours or smaller. If a calendar Unit is
provided, then an error is returned. In order to round a duration with
calendar units, you must use Span::round and
provide a relative datetime.
The parameters are, in brief:
- [
SignedDurationRound::smallest] sets the smallest [Unit] that is allowed to be non-zero in the duration returned. By default, it is set to [Unit::Nanosecond], i.e., no rounding occurs. When the smallest unit is set to something bigger than nanoseconds, then the non-zero units in the duration smaller than the smallest unit are used to determine how the duration should be rounded. For example, rounding1 hour 59 minutesto the nearest hour using the default rounding mode would produce2 hours. - [
SignedDurationRound::mode] determines how to handle the remainder when rounding. The default is [RoundMode::HalfExpand], which corresponds to how you were likely taught to round in school. Alternative modes, like [RoundMode::Trunc], exist too. For example, a truncating rounding of1 hour 59 minutesto the nearest hour would produce1 hour. - [
SignedDurationRound::increment] sets the rounding granularity to use for the configured smallest unit. For example, if the smallest unit is minutes and the increment is 5, then the duration returned will always have its minute units set to a multiple of5.
§Errors
In general, there are two main ways for rounding to fail: an improper
configuration like trying to round a duration to the nearest calendar
unit, or when overflow occurs. Overflow can occur when the duration
would exceed the minimum or maximum SignedDuration values. Typically,
this can only realistically happen if the duration before rounding is
already close to its minimum or maximum value.
§Example: round to the nearest second
This shows how to round a duration to the nearest second. This might be useful when you want to chop off any sub-second component in a way that depends on how close it is (or not) to the next second.
use jiff::{SignedDuration, Unit};
// rounds up
let dur = SignedDuration::new(4 * 60 * 60 + 50 * 60 + 32, 500_000_000);
assert_eq!(
dur.round(Unit::Second)?,
SignedDuration::new(4 * 60 * 60 + 50 * 60 + 33, 0),
);
// rounds down
let dur = SignedDuration::new(4 * 60 * 60 + 50 * 60 + 32, 499_999_999);
assert_eq!(
dur.round(Unit::Second)?,
SignedDuration::new(4 * 60 * 60 + 50 * 60 + 32, 0),
);
§Example: round to the nearest half minute
One can use [SignedDurationRound::increment] to set the rounding
increment:
use jiff::{SignedDuration, SignedDurationRound, Unit};
let options = SignedDurationRound::new()
.smallest(Unit::Second)
.increment(30);
// rounds up
let dur = SignedDuration::from_secs(4 * 60 * 60 + 50 * 60 + 15);
assert_eq!(
dur.round(options)?,
SignedDuration::from_secs(4 * 60 * 60 + 50 * 60 + 30),
);
// rounds down
let dur = SignedDuration::from_secs(4 * 60 * 60 + 50 * 60 + 14);
assert_eq!(
dur.round(options)?,
SignedDuration::from_secs(4 * 60 * 60 + 50 * 60),
);
§Example: overflow results in an error
If rounding would result in a value that exceeds a SignedDuration’s
minimum or maximum values, then an error occurs:
use jiff::{SignedDuration, Unit};
assert_eq!(
SignedDuration::MAX.round(Unit::Hour).unwrap_err().to_string(),
"rounding signed duration to nearest hour resulted in a value \
outside the supported range of a `jiff::SignedDuration`: \
parameter 'signed duration seconds' is not in the \
required range of -9223372036854775808..=9223372036854775807",
);
assert_eq!(
SignedDuration::MIN.round(Unit::Hour).unwrap_err().to_string(),
"rounding signed duration to nearest hour resulted in a value \
outside the supported range of a `jiff::SignedDuration`: \
parameter 'signed duration seconds' is not in the \
required range of -9223372036854775808..=9223372036854775807",
);§Example: rounding with a calendar unit results in an error
use jiff::{SignedDuration, Unit};
assert_eq!(
SignedDuration::ZERO.round(Unit::Day).unwrap_err().to_string(),
"rounding `jiff::SignedDuration` failed \
because the smallest unit provided, 'days', \
is a calendar unit \
(to round by calendar units, you must use a `jiff::Span`)",
);impl SignedDuration
Internal helpers used by Jiff.
NOTE: It is sad that some of these helpers can’t really be implemented
as efficiently outside of Jiff. If we exposed a new_unchecked
constructor, then I believe that would be sufficient.
Trait Implementations§
§impl Add for SignedDuration
impl Add for SignedDuration
§type Output = SignedDuration
type Output = SignedDuration
+ operator.§fn add(self, rhs: SignedDuration) -> SignedDuration
fn add(self, rhs: SignedDuration) -> SignedDuration
+ operation. Read more§impl AddAssign for SignedDuration
impl AddAssign for SignedDuration
§fn add_assign(&mut self, rhs: SignedDuration)
fn add_assign(&mut self, rhs: SignedDuration)
+= operation. Read more§impl Clone for SignedDuration
impl Clone for SignedDuration
§fn clone(&self) -> SignedDuration
fn clone(&self) -> SignedDuration
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more§impl Debug for SignedDuration
impl Debug for SignedDuration
§impl Default for SignedDuration
impl Default for SignedDuration
§fn default() -> SignedDuration
fn default() -> SignedDuration
§impl<'de> Deserialize<'de> for SignedDuration
Available on crate feature serde only.
impl<'de> Deserialize<'de> for SignedDuration
serde only.§fn deserialize<D>(
deserializer: D,
) -> Result<SignedDuration, <D as Deserializer<'de>>::Error>where
D: Deserializer<'de>,
fn deserialize<D>(
deserializer: D,
) -> Result<SignedDuration, <D as Deserializer<'de>>::Error>where
D: Deserializer<'de>,
§impl Display for SignedDuration
impl Display for SignedDuration
§impl Div<i32> for SignedDuration
impl Div<i32> for SignedDuration
§type Output = SignedDuration
type Output = SignedDuration
/ operator.§fn div(self, rhs: i32) -> SignedDuration
fn div(self, rhs: i32) -> SignedDuration
/ operation. Read more§impl DivAssign<i32> for SignedDuration
impl DivAssign<i32> for SignedDuration
§fn div_assign(&mut self, rhs: i32)
fn div_assign(&mut self, rhs: i32)
/= operation. Read more§impl From<Offset> for SignedDuration
impl From<Offset> for SignedDuration
§fn from(offset: Offset) -> SignedDuration
fn from(offset: Offset) -> SignedDuration
§impl FromStr for SignedDuration
impl FromStr for SignedDuration
§impl Hash for SignedDuration
impl Hash for SignedDuration
§impl Mul<i32> for SignedDuration
impl Mul<i32> for SignedDuration
§type Output = SignedDuration
type Output = SignedDuration
* operator.§fn mul(self, rhs: i32) -> SignedDuration
fn mul(self, rhs: i32) -> SignedDuration
* operation. Read more§impl MulAssign<i32> for SignedDuration
impl MulAssign<i32> for SignedDuration
§fn mul_assign(&mut self, rhs: i32)
fn mul_assign(&mut self, rhs: i32)
*= operation. Read more§impl Neg for SignedDuration
impl Neg for SignedDuration
§type Output = SignedDuration
type Output = SignedDuration
- operator.§fn neg(self) -> SignedDuration
fn neg(self) -> SignedDuration
- operation. Read more§impl Ord for SignedDuration
impl Ord for SignedDuration
§impl PartialEq for SignedDuration
impl PartialEq for SignedDuration
§impl PartialOrd for SignedDuration
impl PartialOrd for SignedDuration
§impl Serialize for SignedDuration
Available on crate feature serde only.
impl Serialize for SignedDuration
serde only.§fn serialize<S>(
&self,
serializer: S,
) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>where
S: Serializer,
fn serialize<S>(
&self,
serializer: S,
) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>where
S: Serializer,
§impl Sub for SignedDuration
impl Sub for SignedDuration
§type Output = SignedDuration
type Output = SignedDuration
- operator.§fn sub(self, rhs: SignedDuration) -> SignedDuration
fn sub(self, rhs: SignedDuration) -> SignedDuration
- operation. Read more§impl SubAssign for SignedDuration
impl SubAssign for SignedDuration
§fn sub_assign(&mut self, rhs: SignedDuration)
fn sub_assign(&mut self, rhs: SignedDuration)
-= operation. Read more§impl<'a> Sum<&'a SignedDuration> for SignedDuration
impl<'a> Sum<&'a SignedDuration> for SignedDuration
§fn sum<I>(iter: I) -> SignedDurationwhere
I: Iterator<Item = &'a SignedDuration>,
fn sum<I>(iter: I) -> SignedDurationwhere
I: Iterator<Item = &'a SignedDuration>,
Self from the elements by “summing up”
the items.§impl Sum for SignedDuration
impl Sum for SignedDuration
§fn sum<I>(iter: I) -> SignedDurationwhere
I: Iterator<Item = SignedDuration>,
fn sum<I>(iter: I) -> SignedDurationwhere
I: Iterator<Item = SignedDuration>,
Self from the elements by “summing up”
the items.§impl TryFrom<Duration> for SignedDuration
Fallibly converts a std::time::Duration to a SignedDuration.
impl TryFrom<Duration> for SignedDuration
Fallibly converts a std::time::Duration to a SignedDuration.
§Errors
This fails when the duration’s second component exceeds i64::MAX.
§Examples
use std::time::Duration;
use jiff::SignedDuration;
let dur = Duration::new(5, 123_000_000);
let sdur = SignedDuration::try_from(dur)?;
assert_eq!(sdur, SignedDuration::new(5, 123_000_000));
let dur = Duration::new(i64::MAX as u64, 999_999_999);
let sdur = SignedDuration::try_from(dur)?;
assert_eq!(sdur, SignedDuration::new(i64::MAX, 999_999_999));
// Some failure cases:
assert!(SignedDuration::try_from(Duration::new(i64::MAX as u64 + 1, 0)).is_err());
assert!(SignedDuration::try_from(Duration::new(u64::MAX, 0)).is_err());
§impl TryFrom<SignedDuration> for Duration
Fallibly converts a SignedDuration to a std::time::Duration.
impl TryFrom<SignedDuration> for Duration
Fallibly converts a SignedDuration to a std::time::Duration.
§Errors
This fails when the signed duration is negative.
§Examples
use std::time::Duration;
use jiff::SignedDuration;
let sdur = SignedDuration::new(5, 123_000_000);
let dur = Duration::try_from(sdur)?;
assert_eq!(dur, Duration::new(5, 123_000_000));
// Some failure cases:
assert!(Duration::try_from(SignedDuration::new(-5, 0)).is_err());
assert!(Duration::try_from(SignedDuration::new(-5, -1)).is_err());
assert!(Duration::try_from(SignedDuration::new(0, -1)).is_err());
§impl TryFrom<Span> for SignedDuration
Converts a Span to a SignedDuration.
impl TryFrom<Span> for SignedDuration
Converts a Span to a SignedDuration.
§Errors
This can fail for only when the span has any non-zero units greater than hours. This is an error because it’s impossible to determine the length of, e.g., a month without a reference date.
This can never result in overflow because a SignedDuration can represent
a bigger span of time than Span when limited to units of hours or lower.
If you need to convert a Span to a SignedDuration that has non-zero
units bigger than hours, then please use [Span::to_duration] with a
corresponding relative date.
§Example: maximal span
This example shows the maximum possible span using units of hours or
smaller, and the corresponding SignedDuration value:
use jiff::{SignedDuration, Span};
let sp = Span::new()
.hours(175_307_616)
.minutes(10_518_456_960i64)
.seconds(631_107_417_600i64)
.milliseconds(631_107_417_600_000i64)
.microseconds(631_107_417_600_000_000i64)
.nanoseconds(9_223_372_036_854_775_807i64);
let duration = SignedDuration::try_from(sp)?;
assert_eq!(duration, SignedDuration::new(3_164_760_460_036, 854_775_807));
impl Copy for SignedDuration
impl Eq for SignedDuration
impl StructuralPartialEq for SignedDuration
Auto Trait Implementations§
impl Freeze for SignedDuration
impl RefUnwindSafe for SignedDuration
impl Send for SignedDuration
impl Sync for SignedDuration
impl Unpin for SignedDuration
impl UnsafeUnpin for SignedDuration
impl UnwindSafe for SignedDuration
Blanket Implementations§
§impl<U> As for U
impl<U> As for U
§fn as_<T>(self) -> Twhere
T: CastFrom<U>,
fn as_<T>(self) -> Twhere
T: CastFrom<U>,
self to type T. The semantics of numeric casting with the as operator are followed, so <T as As>::as_::<U> can be used in the same way as T as U for numeric conversions. Read moreSource§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
§impl<T> Conv for T
impl<T> Conv for T
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::RequestSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
§impl<T> SampleLatinHyperCube for T
impl<T> SampleLatinHyperCube for T
§impl<T> Scope for T
impl<T> Scope for T
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.§impl<T> ToRootSpan for Twhere
T: Display,
impl<T> ToRootSpan for Twhere
T: Display,
§fn to_root_span(&self) -> Span
fn to_root_span(&self) -> Span
Span] that can be used as the root of an await-tree.