]> git.lizzy.rs Git - rust.git/blob - src/libstd/time/mod.rs
154f603c84f162f591c7fd75b8b8541676ca6024
[rust.git] / src / libstd / time / mod.rs
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.
4 //
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.
10
11 //! Temporal quantification.
12 //!
13 //! Example:
14 //!
15 //! ```
16 //! use std::time::Duration;
17 //!
18 //! let five_seconds = Duration::new(5, 0);
19 //! // both declarations are equivalent
20 //! assert_eq!(Duration::new(5, 0), Duration::from_secs(5));
21 //! ```
22
23 #![stable(feature = "time", since = "1.3.0")]
24
25 use error::Error;
26 use fmt;
27 use ops::{Add, Sub, AddAssign, SubAssign};
28 use sys::time;
29 use sys_common::FromInner;
30
31 #[stable(feature = "time", since = "1.3.0")]
32 pub use self::duration::Duration;
33
34 mod duration;
35
36 /// A measurement of a monotonically increasing clock.
37 ///  Opaque and useful only with `Duration`.
38 ///
39 /// Instants are always guaranteed to be greater than any previously measured
40 /// instant when created, and are often useful for tasks such as measuring
41 /// benchmarks or timing how long an operation takes.
42 ///
43 /// Note, however, that instants are not guaranteed to be **steady**.  In other
44 /// words, each tick of the underlying clock may not be the same length (e.g.
45 /// some seconds may be longer than others). An instant may jump forwards or
46 /// experience time dilation (slow down or speed up), but it will never go
47 /// backwards.
48 ///
49 /// Instants are opaque types that can only be compared to one another. There is
50 /// no method to get "the number of seconds" from an instant. Instead, it only
51 /// allows measuring the duration between two instants (or comparing two
52 /// instants).
53 ///
54 /// Example:
55 ///
56 /// ```no_run
57 /// use std::time::{Duration, Instant};
58 /// use std::thread::sleep;
59 ///
60 /// fn main() {
61 ///    let now = Instant::now();
62 ///
63 ///    // we sleep for 2 seconds
64 ///    sleep(Duration::new(2, 0));
65 ///    // it prints '2'
66 ///    println!("{}", now.elapsed().as_secs());
67 /// }
68 /// ```
69 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
70 #[stable(feature = "time2", since = "1.8.0")]
71 pub struct Instant(time::Instant);
72
73 /// A measurement of the system clock, useful for talking to
74 /// external entities like the file system or other processes.
75 ///
76 /// Distinct from the `Instant` type, this time measurement **is not
77 /// monotonic**. This means that you can save a file to the file system, then
78 /// save another file to the file system, **and the second file has a
79 /// `SystemTime` measurement earlier than the first**. In other words, an
80 /// operation that happens after another operation in real time may have an
81 /// earlier `SystemTime`!
82 ///
83 /// Consequently, comparing two `SystemTime` instances to learn about the
84 /// duration between them returns a `Result` instead of an infallible `Duration`
85 /// to indicate that this sort of time drift may happen and needs to be handled.
86 ///
87 /// Although a `SystemTime` cannot be directly inspected, the `UNIX_EPOCH`
88 /// constant is provided in this module as an anchor in time to learn
89 /// information about a `SystemTime`. By calculating the duration from this
90 /// fixed point in time, a `SystemTime` can be converted to a human-readable time,
91 /// or perhaps some other string representation.
92 ///
93 /// Example:
94 ///
95 /// ```no_run
96 /// use std::time::{Duration, SystemTime};
97 /// use std::thread::sleep;
98 ///
99 /// fn main() {
100 ///    let now = SystemTime::now();
101 ///
102 ///    // we sleep for 2 seconds
103 ///    sleep(Duration::new(2, 0));
104 ///    match now.elapsed() {
105 ///        Ok(elapsed) => {
106 ///            // it prints '2'
107 ///            println!("{}", elapsed.as_secs());
108 ///        }
109 ///        Err(e) => {
110 ///            // an error occured!
111 ///            println!("Error: {:?}", e);
112 ///        }
113 ///    }
114 /// }
115 /// ```
116 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
117 #[stable(feature = "time2", since = "1.8.0")]
118 pub struct SystemTime(time::SystemTime);
119
120 /// An error returned from the `duration_since` method on `SystemTime`,
121 /// used to learn about why how far in the opposite direction a timestamp lies.
122 #[derive(Clone, Debug)]
123 #[stable(feature = "time2", since = "1.8.0")]
124 pub struct SystemTimeError(Duration);
125
126 impl Instant {
127     /// Returns an instant corresponding to "now".
128     #[stable(feature = "time2", since = "1.8.0")]
129     pub fn now() -> Instant {
130         Instant(time::Instant::now())
131     }
132
133     /// Returns the amount of time elapsed from another instant to this one.
134     ///
135     /// # Panics
136     ///
137     /// This function will panic if `earlier` is later than `self`, which should
138     /// only be possible if `earlier` was created after `self`. Because
139     /// `Instant` is monotonic, the only time that this should happen should be
140     /// a bug.
141     #[stable(feature = "time2", since = "1.8.0")]
142     pub fn duration_since(&self, earlier: Instant) -> Duration {
143         self.0.sub_instant(&earlier.0)
144     }
145
146     /// Returns the amount of time elapsed since this instant was created.
147     ///
148     /// # Panics
149     ///
150     /// This function may panic if the current time is earlier than this
151     /// instant, which is something that can happen if an `Instant` is
152     /// produced synthetically.
153     ///
154     /// # Examples
155     ///
156     /// ```no_run
157     /// use std::thread::sleep;
158     /// use std::time::{Duration, Instant};
159     ///
160     /// let instant = Instant::now();
161     /// let three_secs = Duration::from_secs(3);
162     /// sleep(three_secs);
163     /// assert!(instant.elapsed() >= three_secs);
164     /// ```
165     #[stable(feature = "time2", since = "1.8.0")]
166     pub fn elapsed(&self) -> Duration {
167         Instant::now() - *self
168     }
169 }
170
171 #[stable(feature = "time2", since = "1.8.0")]
172 impl Add<Duration> for Instant {
173     type Output = Instant;
174
175     fn add(self, other: Duration) -> Instant {
176         Instant(self.0.add_duration(&other))
177     }
178 }
179
180 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
181 impl AddAssign<Duration> for Instant {
182     fn add_assign(&mut self, other: Duration) {
183         *self = *self + other;
184     }
185 }
186
187 #[stable(feature = "time2", since = "1.8.0")]
188 impl Sub<Duration> for Instant {
189     type Output = Instant;
190
191     fn sub(self, other: Duration) -> Instant {
192         Instant(self.0.sub_duration(&other))
193     }
194 }
195
196 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
197 impl SubAssign<Duration> for Instant {
198     fn sub_assign(&mut self, other: Duration) {
199         *self = *self - other;
200     }
201 }
202
203 #[stable(feature = "time2", since = "1.8.0")]
204 impl Sub<Instant> for Instant {
205     type Output = Duration;
206
207     fn sub(self, other: Instant) -> Duration {
208         self.duration_since(other)
209     }
210 }
211
212 #[stable(feature = "time2", since = "1.8.0")]
213 impl fmt::Debug for Instant {
214     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
215         self.0.fmt(f)
216     }
217 }
218
219 impl SystemTime {
220     /// Returns the system time corresponding to "now".
221     #[stable(feature = "time2", since = "1.8.0")]
222     pub fn now() -> SystemTime {
223         SystemTime(time::SystemTime::now())
224     }
225
226     /// Returns the amount of time elapsed from an earlier point in time.
227     ///
228     /// This function may fail because measurements taken earlier are not
229     /// guaranteed to always be before later measurements (due to anomalies such
230     /// as the system clock being adjusted either forwards or backwards).
231     ///
232     /// If successful, `Ok(Duration)` is returned where the duration represents
233     /// the amount of time elapsed from the specified measurement to this one.
234     ///
235     /// Returns an `Err` if `earlier` is later than `self`, and the error
236     /// contains how far from `self` the time is.
237     #[stable(feature = "time2", since = "1.8.0")]
238     pub fn duration_since(&self, earlier: SystemTime)
239                           -> Result<Duration, SystemTimeError> {
240         self.0.sub_time(&earlier.0).map_err(SystemTimeError)
241     }
242
243     /// Returns the amount of time elapsed since this system time was created.
244     ///
245     /// This function may fail as the underlying system clock is susceptible to
246     /// drift and updates (e.g. the system clock could go backwards), so this
247     /// function may not always succeed. If successful, `Ok(duration)` is
248     /// returned where the duration represents the amount of time elapsed from
249     /// this time measurement to the current time.
250     ///
251     /// Returns an `Err` if `self` is later than the current system time, and
252     /// the error contains how far from the current system time `self` is.
253     #[stable(feature = "time2", since = "1.8.0")]
254     pub fn elapsed(&self) -> Result<Duration, SystemTimeError> {
255         SystemTime::now().duration_since(*self)
256     }
257 }
258
259 #[stable(feature = "time2", since = "1.8.0")]
260 impl Add<Duration> for SystemTime {
261     type Output = SystemTime;
262
263     fn add(self, dur: Duration) -> SystemTime {
264         SystemTime(self.0.add_duration(&dur))
265     }
266 }
267
268 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
269 impl AddAssign<Duration> for SystemTime {
270     fn add_assign(&mut self, other: Duration) {
271         *self = *self + other;
272     }
273 }
274
275 #[stable(feature = "time2", since = "1.8.0")]
276 impl Sub<Duration> for SystemTime {
277     type Output = SystemTime;
278
279     fn sub(self, dur: Duration) -> SystemTime {
280         SystemTime(self.0.sub_duration(&dur))
281     }
282 }
283
284 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
285 impl SubAssign<Duration> for SystemTime {
286     fn sub_assign(&mut self, other: Duration) {
287         *self = *self - other;
288     }
289 }
290
291 #[stable(feature = "time2", since = "1.8.0")]
292 impl fmt::Debug for SystemTime {
293     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
294         self.0.fmt(f)
295     }
296 }
297
298 /// An anchor in time which can be used to create new `SystemTime` instances or
299 /// learn about where in time a `SystemTime` lies.
300 ///
301 /// This constant is defined to be "1970-01-01 00:00:00 UTC" on all systems with
302 /// respect to the system clock. Using `duration_since` on an existing
303 /// `SystemTime` instance can tell how far away from this point in time a
304 /// measurement lies, and using `UNIX_EPOCH + duration` can be used to create a
305 /// `SystemTime` instance to represent another fixed point in time.
306 #[stable(feature = "time2", since = "1.8.0")]
307 pub const UNIX_EPOCH: SystemTime = SystemTime(time::UNIX_EPOCH);
308
309 impl SystemTimeError {
310     /// Returns the positive duration which represents how far forward the
311     /// second system time was from the first.
312     ///
313     /// A `SystemTimeError` is returned from the `duration_since`
314     /// operation whenever the second system time represents a point later
315     /// in time than the `self` of the method call.
316     #[stable(feature = "time2", since = "1.8.0")]
317     pub fn duration(&self) -> Duration {
318         self.0
319     }
320 }
321
322 #[stable(feature = "time2", since = "1.8.0")]
323 impl Error for SystemTimeError {
324     fn description(&self) -> &str { "other time was not earlier than self" }
325 }
326
327 #[stable(feature = "time2", since = "1.8.0")]
328 impl fmt::Display for SystemTimeError {
329     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
330         write!(f, "second time provided was later than self")
331     }
332 }
333
334 impl FromInner<time::SystemTime> for SystemTime {
335     fn from_inner(time: time::SystemTime) -> SystemTime {
336         SystemTime(time)
337     }
338 }
339
340 #[cfg(test)]
341 mod tests {
342     use super::{Instant, SystemTime, Duration, UNIX_EPOCH};
343
344     macro_rules! assert_almost_eq {
345         ($a:expr, $b:expr) => ({
346             let (a, b) = ($a, $b);
347             if a != b {
348                 let (a, b) = if a > b {(a, b)} else {(b, a)};
349                 assert!(a - Duration::new(0, 100) <= b);
350             }
351         })
352     }
353
354     #[test]
355     fn instant_monotonic() {
356         let a = Instant::now();
357         let b = Instant::now();
358         assert!(b >= a);
359     }
360
361     #[test]
362     fn instant_elapsed() {
363         let a = Instant::now();
364         a.elapsed();
365     }
366
367     #[test]
368     fn instant_math() {
369         let a = Instant::now();
370         let b = Instant::now();
371         let dur = b.duration_since(a);
372         assert_almost_eq!(b - dur, a);
373         assert_almost_eq!(a + dur, b);
374
375         let second = Duration::new(1, 0);
376         assert_almost_eq!(a - second + second, a);
377     }
378
379     #[test]
380     #[should_panic]
381     fn instant_duration_panic() {
382         let a = Instant::now();
383         (a - Duration::new(1, 0)).duration_since(a);
384     }
385
386     #[test]
387     fn system_time_math() {
388         let a = SystemTime::now();
389         let b = SystemTime::now();
390         match b.duration_since(a) {
391             Ok(dur) if dur == Duration::new(0, 0) => {
392                 assert_almost_eq!(a, b);
393             }
394             Ok(dur) => {
395                 assert!(b > a);
396                 assert_almost_eq!(b - dur, a);
397                 assert_almost_eq!(a + dur, b);
398             }
399             Err(dur) => {
400                 let dur = dur.duration();
401                 assert!(a > b);
402                 assert_almost_eq!(b + dur, a);
403                 assert_almost_eq!(b - dur, a);
404             }
405         }
406
407         let second = Duration::new(1, 0);
408         assert_almost_eq!(a.duration_since(a - second).unwrap(), second);
409         assert_almost_eq!(a.duration_since(a + second).unwrap_err()
410                            .duration(), second);
411
412         assert_almost_eq!(a - second + second, a);
413
414         let eighty_years = second * 60 * 60 * 24 * 365 * 80;
415         assert_almost_eq!(a - eighty_years + eighty_years, a);
416         assert_almost_eq!(a - (eighty_years * 10) + (eighty_years * 10), a);
417
418         let one_second_from_epoch = UNIX_EPOCH + Duration::new(1, 0);
419         let one_second_from_epoch2 = UNIX_EPOCH + Duration::new(0, 500_000_000)
420             + Duration::new(0, 500_000_000);
421         assert_eq!(one_second_from_epoch, one_second_from_epoch2);
422     }
423
424     #[test]
425     fn system_time_elapsed() {
426         let a = SystemTime::now();
427         drop(a.elapsed());
428     }
429
430     #[test]
431     fn since_epoch() {
432         let ts = SystemTime::now();
433         let a = ts.duration_since(UNIX_EPOCH).unwrap();
434         let b = ts.duration_since(UNIX_EPOCH - Duration::new(1, 0)).unwrap();
435         assert!(b > a);
436         assert_eq!(b - a, Duration::new(1, 0));
437
438         // let's assume that we're all running computers later than 2000
439         let thirty_years = Duration::new(1, 0) * 60 * 60 * 24 * 365 * 30;
440         assert!(a > thirty_years);
441
442         // let's assume that we're all running computers earlier than 2090.
443         // Should give us ~70 years to fix this!
444         let hundred_twenty_years = thirty_years * 4;
445         assert!(a < hundred_twenty_years);
446     }
447 }