This commit implements the following methods:
* `SystemTime::saturating_add`
* `SystemTime::saturating_sub`
* `SystemTime::saturating_duration_since`
The implementation of these methods is rather trivial, as the main logic
lies behind the constants `SystemTime::MIN` and `SystemTime::MAX`.
There is a slight edge case when adding and subtracting a `Duration`
from a `SystemTime`, namely when the duration itself is finer/smaller
than the time precision on the operating systems.
On most (if not all non-Windows) operating systems, the precision of
`Duration` aligns with the `SystemTime`, both being one nanosecond.
However, on Windows, this time precision is 100ns, meaning that adding
or subtracting a `Duration` whose value is `< Duration::new(0, 100)`
will result in that method behaving like an addition/subtracting of
`Duration::ZERO`, due to the `Duration` getting rounded-down to the zero
value.
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.
Below are platform specifc notes:
# Hermit
The HermitOS implementation is more or less identitcal to the Unix one.
# sgx
The implementation uses a `Duration` to store the Unix time, thereby
implying `Duration::ZERO` and `Duration::MAX` as the limits.
# solid
The implementation uses a `time_t` to store the system time within a
single value (i.e. no dual secs/nanosecs handling), thereby implying its
`::MIN` and `::MAX` values as the respective boundaries.
# UEFI
UEFI has a weird way to store times, i.e. a very complicated struct.
The standard proclaims "1900-01-01T00:00:00+0000" to be the lowest
possible value and `MAX_UEFI_TIME` is already present for the upper
limit.
# Windows
Windows is weird. The Win32 documentation makes no statement on a
maximum value here. Next to this, there are two conflicting types:
`SYSTEMTIME` and `FILETIME`. Rust's Standard Library uses `FILETIME`,
whose limit will (probably) be `i64::MAX` packed into two integers.
However, `SYSTEMTIME` has a lower-limit.
# xous
It is similar to sgx in the sense of using a `Duration`.
# unsupported
Unsupported platforms store a `SystemTime` in a `Duration`, just like
sgx, thereby implying `Duration::ZERO` and `Duration::MAX` as the
respective limits.