// This is a part of Chrono. // See README.md and LICENSE.txt for details.
use core::cmp::Ordering; use core::fmt; use core::marker::Sized; use core::ops::{Add, Sub}; use datetime::DateTime; use oldtime::Duration; #[cfg(any(feature = "std", test))] use std; use TimeZone; use Timelike;
/// Extension trait for subsecond rounding or truncation to a maximum number /// of digits. Rounding can be used to decrease the error variance when /// serializing/persisting to lower precision. Truncation is the default /// behavior in Chrono display formatting. Either can be used to guarantee /// equality (e.g. for testing) when round-tripping through a lower precision /// format. pubtrait SubsecRound { /// Return a copy rounded to the specified number of subsecond digits. With /// 9 or more digits, self is returned unmodified. Halfway values are /// rounded up (away from zero). /// /// # Example /// ``` rust /// # use chrono::{DateTime, SubsecRound, Timelike, TimeZone, Utc}; /// let dt = Utc.ymd(2018, 1, 11).and_hms_milli(12, 0, 0, 154); /// assert_eq!(dt.round_subsecs(2).nanosecond(), 150_000_000); /// assert_eq!(dt.round_subsecs(1).nanosecond(), 200_000_000); /// ``` fn round_subsecs(self, digits: u16) -> Self;
/// Return a copy truncated to the specified number of subsecond /// digits. With 9 or more digits, self is returned unmodified. /// /// # Example /// ``` rust /// # use chrono::{DateTime, SubsecRound, Timelike, TimeZone, Utc}; /// let dt = Utc.ymd(2018, 1, 11).and_hms_milli(12, 0, 0, 154); /// assert_eq!(dt.trunc_subsecs(2).nanosecond(), 150_000_000); /// assert_eq!(dt.trunc_subsecs(1).nanosecond(), 100_000_000); /// ``` fn trunc_subsecs(self, digits: u16) -> Self;
}
impl<T> SubsecRound for T where
T: Timelike + Add<Duration, Output = T> + Sub<Duration, Output = T>,
{ fn round_subsecs(self, digits: u16) -> T { let span = span_for_digits(digits); let delta_down = self.nanosecond() % span; if delta_down > 0 { let delta_up = span - delta_down; if delta_up <= delta_down { self + Duration::nanoseconds(delta_up.into())
} else { self - Duration::nanoseconds(delta_down.into())
}
} else { self// unchanged
}
}
fn trunc_subsecs(self, digits: u16) -> T { let span = span_for_digits(digits); let delta_down = self.nanosecond() % span; if delta_down > 0 { self - Duration::nanoseconds(delta_down.into())
} else { self// unchanged
}
}
}
// Return the maximum span in nanoseconds for the target number of digits. fn span_for_digits(digits: u16) -> u32 { // fast lookup form of: 10^(9-min(9,digits)) match digits { 0 => 1_000_000_000, 1 => 100_000_000, 2 => 10_000_000, 3 => 1_000_000, 4 => 100_000, 5 => 10_000, 6 => 1_000, 7 => 100, 8 => 10,
_ => 1,
}
}
/// Extension trait for rounding or truncating a DateTime by a Duration. /// /// # Limitations /// Both rounding and truncating are done via [`Duration::num_nanoseconds`] and /// [`DateTime::timestamp_nanos`]. This means that they will fail if either the /// `Duration` or the `DateTime` are too big to represented as nanoseconds. They /// will also fail if the `Duration` is bigger than the timestamp. pubtrait DurationRound: Sized { /// Error that can occur in rounding or truncating #[cfg(any(feature = "std", test))] type Err: std::error::Error;
/// Error that can occur in rounding or truncating #[cfg(not(any(feature = "std", test)))] type Err: fmt::Debug + fmt::Display;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.