Try arbitrary leap seconds

This commit is contained in:
teor 2021-05-25 13:42:45 +10:00 committed by Deirdre Connolly
parent 227757ae68
commit be7d69c3cb
1 changed files with 14 additions and 6 deletions

View File

@ -4,19 +4,27 @@ use proptest::{arbitrary::any, prelude::*};
/// Returns a strategy that produces an arbitrary [`chrono::DateTime<Utc>`], /// Returns a strategy that produces an arbitrary [`chrono::DateTime<Utc>`],
/// based on the full valid range of the type. /// based on the full valid range of the type.
/// ///
/// Both the seconds and nanoseconds values are randomised. But leap nanoseconds /// Both the seconds and nanoseconds values are randomised, including leap seconds:
/// are never present. /// https://docs.rs/chrono/0.4.19/chrono/naive/struct.NaiveTime.html#leap-second-handling
/// https://docs.rs/chrono/0.4.19/chrono/struct.DateTime.html#method.timestamp_subsec_nanos
/// ///
/// Zebra uses these times internally, via [`Utc::now`]. /// Wherever possible, Zebra should handle leap seconds by:
/// - making durations and intervals 3 seconds or longer,
/// - avoiding complex time-based calculations, and
/// - avoiding relying on subsecond precision or time order.
/// When monotonic times are needed, use the opaque `std::time::Instant` type.
///
/// # Usage
///
/// Zebra uses these times internally, typically via [`Utc::now`].
/// ///
/// Some parts of the Zcash network protocol ([`Version`] messages) also use times /// Some parts of the Zcash network protocol ([`Version`] messages) also use times
/// with an 8-byte seconds value. Unlike this function, they have zero /// with an 8-byte seconds value. Unlike this function, they have zero
/// nanoseconds values. /// nanoseconds values. (So they never have `chrono` leap seconds.)
pub fn datetime_full() -> impl Strategy<Value = chrono::DateTime<Utc>> { pub fn datetime_full() -> impl Strategy<Value = chrono::DateTime<Utc>> {
( (
// TODO: should we be subtracting 1 from the maximum timestamp?
MIN_DATETIME.timestamp()..=MAX_DATETIME.timestamp(), MIN_DATETIME.timestamp()..=MAX_DATETIME.timestamp(),
0..1_000_000_000_u32, 0..2_000_000_000_u32,
) )
.prop_map(|(secs, nsecs)| Utc.timestamp(secs, nsecs)) .prop_map(|(secs, nsecs)| Utc.timestamp(secs, nsecs))
} }