1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Temporal quantification.
13 #![stable(feature = "time", since = "1.3.0")]
20 #[stable(feature = "time", since = "1.3.0")]
21 pub use self::duration
::Duration
;
25 /// A measurement of a monotonically increasing clock.
27 /// Instants are always guaranteed to be greater than any previously measured
28 /// instant when created, and are often useful for tasks such as measuring
29 /// benchmarks or timing how long an operation takes.
31 /// Note, however, that instants are not guaranteed to be **steady**. In other
32 /// words, each tick of the underlying clock may not be the same length (e.g.
33 /// some seconds may be longer than others). An instant may jump forwards or
34 /// experience time dilation (slow down or speed up), but it will never go
37 /// Instants are opaque types that can only be compared to one another. There is
38 /// no method to get "the number of seconds" from an instant. Instead, it only
39 /// allows measuring the duration between two instants (or comparing two
41 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
42 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
43 pub struct Instant(time
::Instant
);
45 /// A measurement of the system clock appropriate for timestamps such as those
46 /// on files on the filesystem.
48 /// Distinct from the `Instant` type, this time measurement **is not
49 /// monotonic**. This means that you can save a file to the file system, then
50 /// save another file to the file system, **and the second file has a
51 /// `SystemTime` measurement earlier than the second**. In other words, an
52 /// operation that happens after another operation in real time may have an
53 /// earlier `SystemTime`!
55 /// Consequently, comparing two `SystemTime` instances to learn about the
56 /// duration between them returns a `Result` instead of an infallible `Duration`
57 /// to indicate that this sort of time drift may happen and needs to be handled.
59 /// Although a `SystemTime` cannot be directly inspected, the `UNIX_EPOCH`
60 /// constant is provided in this module as an anchor in time to learn
61 /// information about a `SystemTime`. By calculating the duration from this
62 /// fixed point in time, a `SystemTime` can be converted to a human-readable time,
63 /// or perhaps some other string representation.
64 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
65 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
66 pub struct SystemTime(time
::SystemTime
);
68 /// An error returned from the `duration_from_earlier` method on `SystemTime`,
69 /// used to learn about why how far in the opposite direction a timestamp lies.
70 #[derive(Clone, Debug)]
71 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
72 pub struct SystemTimeError(Duration
);
74 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
76 /// Returns an instant corresponding to "now".
77 pub fn now() -> Instant
{
78 Instant(time
::Instant
::now())
81 /// Returns the amount of time elapsed from another instant to this one.
85 /// This function will panic if `earlier` is later than `self`, which should
86 /// only be possible if `earlier` was created after `self`. Because
87 /// `Instant` is monotonic, the only time that this should happen should be
89 pub fn duration_from_earlier(&self, earlier
: Instant
) -> Duration
{
90 self.0.sub_instant(&earlier
.0)
93 /// Returns the amount of time elapsed since this instant was created.
97 /// This function may panic if the current time is earlier than this
98 /// instant, which is something that can happen if an `Instant` is
99 /// produced synthetically.
100 pub fn elapsed(&self) -> Duration
{
101 Instant
::now().duration_from_earlier(*self)
105 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
106 impl Add
<Duration
> for Instant
{
107 type Output
= Instant
;
109 fn add(self, other
: Duration
) -> Instant
{
110 Instant(self.0.add_duration(&other
))
114 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
115 impl Sub
<Duration
> for Instant
{
116 type Output
= Instant
;
118 fn sub(self, other
: Duration
) -> Instant
{
119 Instant(self.0.sub_duration(&other
))
123 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
124 impl fmt
::Debug
for Instant
{
125 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
130 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
132 /// Returns the system time corresponding to "now".
133 pub fn now() -> SystemTime
{
134 SystemTime(time
::SystemTime
::now())
137 /// Returns the amount of time elapsed from an earlier point in time.
139 /// This function may fail because measurements taken earlier are not
140 /// guaranteed to always be before later measurements (due to anomalies such
141 /// as the system clock being adjusted either forwards or backwards).
143 /// If successful, `Ok(Duration)` is returned where the duration represents
144 /// the amount of time elapsed from the specified measurement to this one.
146 /// Returns an `Err` if `earlier` is later than `self`, and the error
147 /// contains how far from `self` the time is.
148 pub fn duration_from_earlier(&self, earlier
: SystemTime
)
149 -> Result
<Duration
, SystemTimeError
> {
150 self.0.sub_time(&earlier
.0).map_err(SystemTimeError
)
153 /// Returns the amount of time elapsed since this system time was created.
155 /// This function may fail as the underlying system clock is susceptible to
156 /// drift and updates (e.g. the system clock could go backwards), so this
157 /// function may not always succeed. If successful, `Ok(duration)` is
158 /// returned where the duration represents the amount of time elapsed from
159 /// this time measurement to the current time.
161 /// Returns an `Err` if `self` is later than the current system time, and
162 /// the error contains how far from the current system time `self` is.
163 pub fn elapsed(&self) -> Result
<Duration
, SystemTimeError
> {
164 SystemTime
::now().duration_from_earlier(*self)
168 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
169 impl Add
<Duration
> for SystemTime
{
170 type Output
= SystemTime
;
172 fn add(self, dur
: Duration
) -> SystemTime
{
173 SystemTime(self.0.add_duration(&dur
))
177 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
178 impl Sub
<Duration
> for SystemTime
{
179 type Output
= SystemTime
;
181 fn sub(self, dur
: Duration
) -> SystemTime
{
182 SystemTime(self.0.sub_duration(&dur
))
186 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
187 impl fmt
::Debug
for SystemTime
{
188 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
193 /// An anchor in time which can be used to create new `SystemTime` instances or
194 /// learn about where in time a `SystemTime` lies.
196 /// This constant is defined to be "1970-01-01 00:00:00 UTC" on all systems with
197 /// respect to the system clock. Using `duration_from_earlier` on an existing
198 /// `SystemTime` instance can tell how far away from this point in time a
199 /// measurement lies, and using `UNIX_EPOCH + duration` can be used to create a
200 /// `SystemTime` instance to represent another fixed point in time.
201 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
202 pub const UNIX_EPOCH
: SystemTime
= SystemTime(time
::UNIX_EPOCH
);
204 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
205 impl SystemTimeError
{
206 /// Returns the positive duration which represents how far forward the
207 /// second system time was from the first.
209 /// A `SystemTimeError` is returned from the `duration_from_earlier`
210 /// operation whenever the second system time represents a point later
211 /// in time than the `self` of the method call.
212 pub fn duration(&self) -> Duration
{
217 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
218 impl Error
for SystemTimeError
{
219 fn description(&self) -> &str { "other time was not earlier than self" }
222 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
223 impl fmt
::Display
for SystemTimeError
{
224 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
225 write
!(f
, "second time provided was later than self")
231 use super::{Instant, SystemTime, Duration, UNIX_EPOCH}
;
233 macro_rules
! assert_almost_eq
{
234 ($a
:expr
, $b
:expr
) => ({
235 let (a
, b
) = ($a
, $b
);
237 let (a
, b
) = if a
> b {(a, b)}
else {(b, a)}
;
238 assert
!(a
- Duration
::new(0, 100) <= b
);
244 fn instant_monotonic() {
245 let a
= Instant
::now();
246 let b
= Instant
::now();
251 fn instant_elapsed() {
252 let a
= Instant
::now();
258 let a
= Instant
::now();
259 let b
= Instant
::now();
260 let dur
= b
.duration_from_earlier(a
);
261 assert_almost_eq
!(b
- dur
, a
);
262 assert_almost_eq
!(a
+ dur
, b
);
264 let second
= Duration
::new(1, 0);
265 assert_almost_eq
!(a
- second
+ second
, a
);
270 fn instant_duration_panic() {
271 let a
= Instant
::now();
272 (a
- Duration
::new(1, 0)).duration_from_earlier(a
);
276 fn system_time_math() {
277 let a
= SystemTime
::now();
278 let b
= SystemTime
::now();
279 match b
.duration_from_earlier(a
) {
280 Ok(dur
) if dur
== Duration
::new(0, 0) => {
281 assert_almost_eq
!(a
, b
);
285 assert_almost_eq
!(b
- dur
, a
);
286 assert_almost_eq
!(a
+ dur
, b
);
289 let dur
= dur
.duration();
291 assert_almost_eq
!(b
+ dur
, a
);
292 assert_almost_eq
!(b
- dur
, a
);
296 let second
= Duration
::new(1, 0);
297 assert_almost_eq
!(a
.duration_from_earlier(a
- second
).unwrap(), second
);
298 assert_almost_eq
!(a
.duration_from_earlier(a
+ second
).unwrap_err()
299 .duration(), second
);
301 assert_almost_eq
!(a
- second
+ second
, a
);
303 let eighty_years
= second
* 60 * 60 * 24 * 365 * 80;
304 assert_almost_eq
!(a
- eighty_years
+ eighty_years
, a
);
305 assert_almost_eq
!(a
- (eighty_years
* 10) + (eighty_years
* 10), a
);
307 let one_second_from_epoch
= UNIX_EPOCH
+ Duration
::new(1, 0);
308 let one_second_from_epoch2
= UNIX_EPOCH
+ Duration
::new(0, 500_000_000)
309 + Duration
::new(0, 500_000_000);
310 assert_eq
!(one_second_from_epoch
, one_second_from_epoch2
);
314 fn system_time_elapsed() {
315 let a
= SystemTime
::now();
321 let ts
= SystemTime
::now();
322 let a
= ts
.duration_from_earlier(UNIX_EPOCH
).unwrap();
323 let b
= ts
.duration_from_earlier(UNIX_EPOCH
- Duration
::new(1, 0)).unwrap();
325 assert_eq
!(b
- a
, Duration
::new(1, 0));
327 // let's assume that we're all running computers later than 2000
328 let thirty_years
= Duration
::new(1, 0) * 60 * 60 * 24 * 365 * 30;
329 assert
!(a
> thirty_years
);
331 // let's assume that we're all running computers earlier than 2090.
332 // Should give us ~70 years to fix this!
333 let hundred_twenty_years
= thirty_years
* 4;
334 assert
!(a
< hundred_twenty_years
);