#[repr(C)]pub struct Duration { /* private fields */ }
Expand description
Defines generally usable durations for nanosecond precision valid for 32,768 centuries in either direction, and only on 80 bits / 10 octets.
Important conventions:
- The negative durations can be mentally modeled “BC” years. One hours before 01 Jan 0000, it was “-1” years but 365 days and 23h into the current day. It was decided that the nanoseconds corresponds to the nanoseconds into the current century. In other words, a duration with centuries = -1 and nanoseconds = 0 is a greater duration (further from zero) than centuries = -1 and nanoseconds = 1. Duration zero minus one nanosecond returns a century of -1 and a nanosecond set to the number of nanoseconds in one century minus one. That difference is exactly 1 nanoseconds, where the former duration is “closer to zero” than the latter. As such, the largest negative duration that can be represented sets the centuries to i16::MAX and its nanoseconds to NANOSECONDS_PER_CENTURY.
- It was also decided that opposite durations are equal, e.g. -15 minutes == 15 minutes. If the direction of time matters, use the signum function.
Implementations§
source§impl Duration
impl Duration
sourcepub fn new(centuries: i16, nanoseconds: u64) -> Self
👎Deprecated since 3.6.0: Prefer from_parts()
pub fn new(centuries: i16, nanoseconds: u64) -> Self
Builds a new duration from the number of centuries and the number of nanoseconds
sourcepub fn from_parts(centuries: i16, nanoseconds: u64) -> Self
pub fn from_parts(centuries: i16, nanoseconds: u64) -> Self
Create a normalized duration from its parts
sourcepub fn from_total_nanoseconds(nanos: i128) -> Self
pub fn from_total_nanoseconds(nanos: i128) -> Self
Converts the total nanoseconds as i128 into this Duration (saving 48 bits)
sourcepub fn from_truncated_nanoseconds(nanos: i64) -> Self
pub fn from_truncated_nanoseconds(nanos: i64) -> Self
Create a new duration from the truncated nanoseconds (+/- 2927.1 years of duration)
sourcepub fn from_hours(value: f64) -> Self
pub fn from_hours(value: f64) -> Self
Creates a new duration from the provided number of hours
sourcepub fn from_seconds(value: f64) -> Self
pub fn from_seconds(value: f64) -> Self
Creates a new duration from the provided number of seconds
sourcepub fn from_milliseconds(value: f64) -> Self
pub fn from_milliseconds(value: f64) -> Self
Creates a new duration from the provided number of milliseconds
sourcepub fn from_microseconds(value: f64) -> Self
pub fn from_microseconds(value: f64) -> Self
Creates a new duration from the provided number of microsecond
sourcepub fn from_nanoseconds(value: f64) -> Self
pub fn from_nanoseconds(value: f64) -> Self
Creates a new duration from the provided number of nanoseconds
sourcepub fn compose(
sign: i8,
days: u64,
hours: u64,
minutes: u64,
seconds: u64,
milliseconds: u64,
microseconds: u64,
nanoseconds: u64
) -> Self
pub fn compose( sign: i8, days: u64, hours: u64, minutes: u64, seconds: u64, milliseconds: u64, microseconds: u64, nanoseconds: u64 ) -> Self
Creates a new duration from its parts. Set the sign to a negative number for the duration to be negative.
sourcepub fn compose_f64(
sign: i8,
days: f64,
hours: f64,
minutes: f64,
seconds: f64,
milliseconds: f64,
microseconds: f64,
nanoseconds: f64
) -> Self
pub fn compose_f64( sign: i8, days: f64, hours: f64, minutes: f64, seconds: f64, milliseconds: f64, microseconds: f64, nanoseconds: f64 ) -> Self
Creates a new duration from its parts. Set the sign to a negative number for the duration to be negative.
sourcepub fn from_tz_offset(sign: i8, hours: i64, minutes: i64) -> Self
pub fn from_tz_offset(sign: i8, hours: i64, minutes: i64) -> Self
Initializes a Duration from a timezone offset
source§impl Duration
impl Duration
sourcepub const fn to_parts(&self) -> (i16, u64)
pub const fn to_parts(&self) -> (i16, u64)
Returns the centuries and nanoseconds of this duration NOTE: These items are not public to prevent incorrect durations from being created by modifying the values of the structure directly.
sourcepub fn total_nanoseconds(&self) -> i128
pub fn total_nanoseconds(&self) -> i128
Returns the total nanoseconds in a signed 128 bit integer
sourcepub fn try_truncated_nanoseconds(&self) -> Result<i64, Errors>
pub fn try_truncated_nanoseconds(&self) -> Result<i64, Errors>
Returns the truncated nanoseconds in a signed 64 bit integer, if the duration fits.
sourcepub fn truncated_nanoseconds(&self) -> i64
pub fn truncated_nanoseconds(&self) -> i64
Returns the truncated nanoseconds in a signed 64 bit integer, if the duration fits. WARNING: This function will NOT fail and will return the i64::MIN or i64::MAX depending on the sign of the centuries if the Duration does not fit on aa i64
sourcepub fn to_seconds(&self) -> f64
pub fn to_seconds(&self) -> f64
Returns this duration in seconds f64. For high fidelity comparisons, it is recommended to keep using the Duration structure.
pub fn to_unit(&self, unit: Unit) -> f64
sourcepub const fn signum(&self) -> i8
pub const fn signum(&self) -> i8
Returns the sign of this duration
- 0 if the number is zero
- 1 if the number is positive
- -1 if the number is negative
sourcepub fn decompose(&self) -> (i8, u64, u64, u64, u64, u64, u64, u64)
pub fn decompose(&self) -> (i8, u64, u64, u64, u64, u64, u64, u64)
Decomposes a Duration in its sign, days, hours, minutes, seconds, ms, us, ns
sourcepub fn floor(&self, duration: Self) -> Self
pub fn floor(&self, duration: Self) -> Self
Floors this duration to the closest duration from the bottom
Example
use hifitime::{Duration, TimeUnits};
let two_hours_three_min = 2.hours() + 3.minutes();
assert_eq!(two_hours_three_min.floor(1.hours()), 2.hours());
assert_eq!(two_hours_three_min.floor(30.minutes()), 2.hours());
// This is zero because we floor by a duration longer than the current duration, rounding it down
assert_eq!(two_hours_three_min.floor(4.hours()), 0.hours());
assert_eq!(two_hours_three_min.floor(1.seconds()), two_hours_three_min);
assert_eq!(two_hours_three_min.floor(1.hours() + 1.minutes()), 2.hours() + 2.minutes());
assert_eq!(two_hours_three_min.floor(1.hours() + 5.minutes()), 1.hours() + 5.minutes());
sourcepub fn ceil(&self, duration: Self) -> Self
pub fn ceil(&self, duration: Self) -> Self
Ceils this duration to the closest provided duration
This simply floors then adds the requested duration
Example
use hifitime::{Duration, TimeUnits};
let two_hours_three_min = 2.hours() + 3.minutes();
assert_eq!(two_hours_three_min.ceil(1.hours()), 3.hours());
assert_eq!(two_hours_three_min.ceil(30.minutes()), 2.hours() + 30.minutes());
assert_eq!(two_hours_three_min.ceil(4.hours()), 4.hours());
assert_eq!(two_hours_three_min.ceil(1.seconds()), two_hours_three_min + 1.seconds());
assert_eq!(two_hours_three_min.ceil(1.hours() + 5.minutes()), 2.hours() + 10.minutes());
sourcepub fn round(&self, duration: Self) -> Self
pub fn round(&self, duration: Self) -> Self
Rounds this duration to the closest provided duration
This performs both a ceil
and floor
and returns the value which is the closest to current one.
Example
use hifitime::{Duration, TimeUnits};
let two_hours_three_min = 2.hours() + 3.minutes();
assert_eq!(two_hours_three_min.round(1.hours()), 2.hours());
assert_eq!(two_hours_three_min.round(30.minutes()), 2.hours());
assert_eq!(two_hours_three_min.round(4.hours()), 4.hours());
assert_eq!(two_hours_three_min.round(1.seconds()), two_hours_three_min);
assert_eq!(two_hours_three_min.round(1.hours() + 5.minutes()), 2.hours() + 10.minutes());
sourcepub fn approx(&self) -> Self
pub fn approx(&self) -> Self
Rounds this duration to the largest units represented in this duration.
This is useful to provide an approximate human duration. Under the hood, this function uses round
,
so the “tipping point” of the rounding is half way to the next increment of the greatest unit.
As shown below, one example is that 35 hours and 59 minutes rounds to 1 day, but 36 hours and 1 minute rounds
to 2 days because 2 days is closer to 36h 1 min than 36h 1 min is to 1 day.
Example
use hifitime::{Duration, TimeUnits};
assert_eq!((2.hours() + 3.minutes()).approx(), 2.hours());
assert_eq!((24.hours() + 3.minutes()).approx(), 1.days());
assert_eq!((35.hours() + 59.minutes()).approx(), 1.days());
assert_eq!((36.hours() + 1.minutes()).approx(), 2.days());
assert_eq!((47.hours() + 3.minutes()).approx(), 2.days());
assert_eq!((49.hours() + 3.minutes()).approx(), 2.days());
sourcepub fn min(&self, other: Self) -> Self
pub fn min(&self, other: Self) -> Self
Returns the minimum of the two durations.
use hifitime::TimeUnits;
let d0 = 20.seconds();
let d1 = 21.seconds();
assert_eq!(d0, d1.min(d0));
assert_eq!(d0, d0.min(d1));
Note: this uses a pointer to self
which will be copied immediately because Python requires a pointer.
sourcepub fn max(&self, other: Self) -> Self
pub fn max(&self, other: Self) -> Self
Returns the maximum of the two durations.
use hifitime::TimeUnits;
let d0 = 20.seconds();
let d1 = 21.seconds();
assert_eq!(d1, d1.max(d0));
assert_eq!(d1, d0.max(d1));
Note: this uses a pointer to self
which will be copied immediately because Python requires a pointer.
sourcepub const fn is_negative(&self) -> bool
pub const fn is_negative(&self) -> bool
Returns whether this is a negative or positive duration.
sourcepub const MIN_POSITIVE: Self = Self::EPSILON
pub const MIN_POSITIVE: Self = Self::EPSILON
Minimum positive duration is one nanoseconds
sourcepub const MIN_NEGATIVE: Self = _
pub const MIN_NEGATIVE: Self = _
Minimum negative duration is minus one nanosecond
Trait Implementations§
source§impl Add for Duration
impl Add for Duration
source§fn add(self, rhs: Self) -> Duration
fn add(self, rhs: Self) -> Duration
Addition of Durations
Durations are centered on zero duration. Of the tuple, only the centuries may be negative, the nanoseconds are always positive and represent the nanoseconds into the current centuries.
Examples
Duration { centuries: 0, nanoseconds: 1 }
is a positive duration of zero centuries and one nanosecond.Duration { centuries: -1, nanoseconds: 1 }
is a negative duration representing “one century before zero minus one nanosecond”
source§impl AddAssign<Duration> for Epoch
impl AddAssign<Duration> for Epoch
source§fn add_assign(&mut self, duration: Duration)
fn add_assign(&mut self, duration: Duration)
+=
operation. Read moresource§impl AddAssign<Unit> for Duration
impl AddAssign<Unit> for Duration
source§fn add_assign(&mut self, rhs: Unit)
fn add_assign(&mut self, rhs: Unit)
+=
operation. Read moresource§impl AddAssign for Duration
impl AddAssign for Duration
source§fn add_assign(&mut self, rhs: Duration)
fn add_assign(&mut self, rhs: Duration)
+=
operation. Read moresource§impl<'de> Deserialize<'de> for Duration
impl<'de> Deserialize<'de> for Duration
source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
source§impl From<Duration> for Duration
impl From<Duration> for Duration
source§fn from(std_duration: Duration) -> Self
fn from(std_duration: Duration) -> Self
Converts a duration into an std::time::Duration
Limitations
- If the duration is negative, this will return a std::time::Duration::ZERO.
- If the duration larger than the MAX duration, this will return std::time::Duration::MAX
source§impl From<Duration> for Duration
impl From<Duration> for Duration
source§fn from(hf_duration: Duration) -> Self
fn from(hf_duration: Duration) -> Self
Converts a duration into an std::time::Duration
Limitations
- If the duration is negative, this will return a std::time::Duration::ZERO.
- If the duration larger than the MAX duration, this will return std::time::Duration::MAX
source§impl FromStr for Duration
impl FromStr for Duration
source§fn from_str(s_in: &str) -> Result<Self, Self::Err>
fn from_str(s_in: &str) -> Result<Self, Self::Err>
Attempts to convert a simple string to a Duration. Does not yet support complicated durations.
Identifiers:
- d, days, day
- h, hours, hour
- min, mins, minute
- s, second, seconds
- ms, millisecond, milliseconds
- us, microsecond, microseconds
- ns, nanosecond, nanoseconds
+
or-
indicates a timezone offset
Example
use hifitime::{Duration, Unit};
use std::str::FromStr;
assert_eq!(Duration::from_str("1 d").unwrap(), Unit::Day * 1);
assert_eq!(Duration::from_str("10.598 days").unwrap(), Unit::Day * 10.598);
assert_eq!(Duration::from_str("10.598 min").unwrap(), Unit::Minute * 10.598);
assert_eq!(Duration::from_str("10.598 us").unwrap(), Unit::Microsecond * 10.598);
assert_eq!(Duration::from_str("10.598 seconds").unwrap(), Unit::Second * 10.598);
assert_eq!(Duration::from_str("10.598 nanosecond").unwrap(), Unit::Nanosecond * 10.598);
assert_eq!(Duration::from_str("5 h 256 ms 1 ns").unwrap(), 5 * Unit::Hour + 256 * Unit::Millisecond + Unit::Nanosecond);
assert_eq!(Duration::from_str("-01:15:30").unwrap(), -(1 * Unit::Hour + 15 * Unit::Minute + 30 * Unit::Second));
assert_eq!(Duration::from_str("+3615").unwrap(), 36 * Unit::Hour + 15 * Unit::Minute);
source§impl Ord for Duration
impl Ord for Duration
source§impl PartialEq for Duration
impl PartialEq for Duration
source§impl PartialOrd<Unit> for Duration
impl PartialOrd<Unit> for Duration
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self
and other
) and is used by the <=
operator. Read moresource§impl PartialOrd for Duration
impl PartialOrd for Duration
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self
and other
) and is used by the <=
operator. Read moresource§impl Sub for Duration
impl Sub for Duration
source§fn sub(self, rhs: Self) -> Self
fn sub(self, rhs: Self) -> Self
Subtraction
This operation is a notch confusing with negative durations.
As described in the Duration
structure, a Duration of (-1, NANOSECONDS_PER_CENTURY-1) is closer to zero
than (-1, 0).
Algorithm
A > B, and both are positive
If A > B, then A.centuries is subtracted by B.centuries, and A.nanoseconds is subtracted by B.nanoseconds. If an overflow occurs, e.g. A.nanoseconds < B.nanoseconds, the number of nanoseconds is increased by the number of nanoseconds per century, and the number of centuries is decreased by one.
use hifitime::{Duration, NANOSECONDS_PER_CENTURY};
let a = Duration::from_parts(1, 1);
let b = Duration::from_parts(0, 10);
let c = Duration::from_parts(0, NANOSECONDS_PER_CENTURY - 9);
assert_eq!(a - b, c);
A < B, and both are positive
In this case, the resulting duration will be negative. The number of centuries is a signed integer, so it is set to the difference of A.centuries - B.centuries. The number of nanoseconds however must be wrapped by the number of nanoseconds per century. For example:, let A = (0, 1) and B = (1, 10), then the resulting duration will be (-2, NANOSECONDS_PER_CENTURY - (10 - 1)). In this case, the centuries are set to -2 because B is two centuries into the future (the number of centuries into the future is zero-indexed).
use hifitime::{Duration, NANOSECONDS_PER_CENTURY};
let a = Duration::from_parts(0, 1);
let b = Duration::from_parts(1, 10);
let c = Duration::from_parts(-2, NANOSECONDS_PER_CENTURY - 9);
assert_eq!(a - b, c);
A > B, both are negative
In this case, we try to stick to normal arithmatics: (-9 - -10) = (-9 + 10) = +1. In this case, we can simply add the components of the duration together. For example, let A = (-1, NANOSECONDS_PER_CENTURY - 2), and B = (-1, NANOSECONDS_PER_CENTURY - 1). Respectively, A is two nanoseconds before Duration::ZERO and B is one nanosecond before Duration::ZERO. Then, A-B should be one nanoseconds before zero, i.e. (-1, NANOSECONDS_PER_CENTURY - 1). This is because we subtract “negative one nanosecond” from a “negative minus two nanoseconds”, which corresponds to adding the opposite, and the opposite of “negative one nanosecond” is “positive one nanosecond”.
use hifitime::{Duration, NANOSECONDS_PER_CENTURY};
let a = Duration::from_parts(-1, NANOSECONDS_PER_CENTURY - 9);
let b = Duration::from_parts(-1, NANOSECONDS_PER_CENTURY - 10);
let c = Duration::from_parts(0, 1);
assert_eq!(a - b, c);
A < B, both are negative
Just like in the prior case, we try to stick to normal arithmatics: (-10 - -9) = (-10 + 9) = -1.
use hifitime::{Duration, NANOSECONDS_PER_CENTURY};
let a = Duration::from_parts(-1, NANOSECONDS_PER_CENTURY - 10);
let b = Duration::from_parts(-1, NANOSECONDS_PER_CENTURY - 9);
let c = Duration::from_parts(-1, NANOSECONDS_PER_CENTURY - 1);
assert_eq!(a - b, c);
MIN is the minimum
One cannot subtract anything from the MIN.
use hifitime::Duration;
let one_ns = Duration::from_parts(0, 1);
assert_eq!(Duration::MIN - one_ns, Duration::MIN);
source§impl SubAssign<Duration> for Epoch
impl SubAssign<Duration> for Epoch
source§fn sub_assign(&mut self, duration: Duration)
fn sub_assign(&mut self, duration: Duration)
-=
operation. Read moresource§impl SubAssign<Unit> for Duration
impl SubAssign<Unit> for Duration
source§fn sub_assign(&mut self, rhs: Unit)
fn sub_assign(&mut self, rhs: Unit)
-=
operation. Read moresource§impl SubAssign for Duration
impl SubAssign for Duration
source§fn sub_assign(&mut self, rhs: Self)
fn sub_assign(&mut self, rhs: Self)
-=
operation. Read more