Skip to content

Commit 91ec859

Browse files
committed
time: Implement SystemTime::{MIN, MAX}
This commit introduces two new constants to SystemTime: `MIN` and `MAX`, whose value represent the maximum values for the respective data type, depending upon the platform. Technically, this value is already obtainable during runtime with the following algorithm: Use `SystemTime::UNIX_EPOCH` and call `checked_add` (or `checked_sub`) repeatedly with `Duration::new(0, 1)` on it, until it returns None. Mathematically speaking, this algorithm will terminate after a finite amount of steps, yet it is impractical to run it, as it takes practically forever. Besides, this commit also adds a unit test. Concrete implementation depending upon the platform is done in later commits. In the future, the hope of the authors lies within the creation of a `SystemTime::saturating_add` and `SystemTime::saturating_sub`, similar to the functions already present in `std::time::Duration`. However, for those, these constants are crucially required, thereby this should be seen as the initial step towards this direction. This feature (and a related saturating version of `checked_{add, sub}` has been requested multiple times over the course of the past few years, most notably: * #100141 * #133525 * #105762 * #71224 * #45448 * #52555
1 parent a7b3715 commit 91ec859

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

library/std/src/time.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,46 @@ impl SystemTime {
511511
#[stable(feature = "assoc_unix_epoch", since = "1.28.0")]
512512
pub const UNIX_EPOCH: SystemTime = UNIX_EPOCH;
513513

514+
/// Represents the maximum value representable by [`SystemTime`] on this platform.
515+
///
516+
/// This value differs a lot between platforms, but it is always the case
517+
/// that any positive addition to [`SystemTime::MAX`] will fail.
518+
///
519+
/// # Examples
520+
///
521+
/// ```no_run
522+
/// #![feature(time_systemtime_limits)]
523+
/// use std::time::{Duration, SystemTime};
524+
///
525+
/// // Adding zero will change nothing.
526+
/// assert_eq!(SystemTime::MAX.checked_add(Duration::ZERO), Some(SystemTime::MAX));
527+
///
528+
/// // But adding just 1ns will already fail.
529+
/// assert_eq!(SystemTime::MAX.checked_add(Duration::new(0, 1)), None);
530+
/// ```
531+
#[unstable(feature = "time_systemtime_limits", issue = "none")]
532+
pub const MAX: SystemTime = SystemTime(time::SystemTime::MAX);
533+
534+
/// Represents the minimum value representable by [`SystemTime`] on this platform.
535+
///
536+
/// This value differs a lot between platforms, but it is always the case
537+
/// that any positive subtraction from [`SystemTime::MIN`] will fail.
538+
///
539+
/// # Examples
540+
///
541+
/// ```
542+
/// #![feature(time_systemtime_limits)]
543+
/// use std::time::{Duration, SystemTime};
544+
///
545+
/// // Subtracting zero will change nothing.
546+
/// assert_eq!(SystemTime::MIN.checked_sub(Duration::ZERO), Some(SystemTime::MIN));
547+
///
548+
/// // But subtracting just 1ns will already fail.
549+
/// assert_eq!(SystemTime::MIN.checked_sub(Duration::new(0, 1)), None);
550+
/// ```
551+
#[unstable(feature = "time_systemtime_limits", issue = "none")]
552+
pub const MIN: SystemTime = SystemTime(time::SystemTime::MIN);
553+
514554
/// Returns the system time corresponding to "now".
515555
///
516556
/// # Examples

library/std/tests/time.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![feature(duration_constants)]
2+
#![feature(time_systemtime_limits)]
23

34
use std::fmt::Debug;
45
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
@@ -237,9 +238,27 @@ fn system_time_duration_since_max_range_on_unix() {
237238
let min = SystemTime::UNIX_EPOCH - (Duration::new(i64::MAX as u64 + 1, 0));
238239
let max = SystemTime::UNIX_EPOCH + (Duration::new(i64::MAX as u64, 999_999_999));
239240

241+
assert_eq!(min, SystemTime::MIN);
242+
assert_eq!(max, SystemTime::MAX);
243+
240244
let delta_a = max.duration_since(min).expect("duration_since overflow");
241245
let delta_b = min.duration_since(max).expect_err("duration_since overflow").duration();
242246

243247
assert_eq!(Duration::MAX, delta_a);
244248
assert_eq!(Duration::MAX, delta_b);
245249
}
250+
251+
#[test]
252+
fn system_time_max_min() {
253+
// First, test everything with checked_* and Duration::ZERO.
254+
assert_eq!(SystemTime::MAX.checked_add(Duration::ZERO), Some(SystemTime::MAX));
255+
assert_eq!(SystemTime::MAX.checked_sub(Duration::ZERO), Some(SystemTime::MAX));
256+
assert_eq!(SystemTime::MIN.checked_add(Duration::ZERO), Some(SystemTime::MIN));
257+
assert_eq!(SystemTime::MIN.checked_sub(Duration::ZERO), Some(SystemTime::MIN));
258+
259+
// Now do the same again with checked_* but try by ± a single nanosecond.
260+
assert!(SystemTime::MAX.checked_add(Duration::new(0, 1)).is_none());
261+
assert!(SystemTime::MAX.checked_sub(Duration::new(0, 1)).is_some());
262+
assert!(SystemTime::MIN.checked_add(Duration::new(0, 1)).is_some());
263+
assert!(SystemTime::MIN.checked_sub(Duration::new(0, 1)).is_none());
264+
}

0 commit comments

Comments
 (0)