]> git.lizzy.rs Git - rust.git/blob - src/libstd/time.rs
Fix test
[rust.git] / src / libstd / time.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 core::time::Duration;
33
34 /// A measurement of a monotonically nondecreasing clock.
35 /// Opaque and useful only with `Duration`.
36 ///
37 /// Instants are always guaranteed to be no less than any previously measured
38 /// instant when created, and are often useful for tasks such as measuring
39 /// benchmarks or timing how long an operation takes.
40 ///
41 /// Note, however, that instants are not guaranteed to be **steady**.  In other
42 /// words, each tick of the underlying clock may not be the same length (e.g.
43 /// some seconds may be longer than others). An instant may jump forwards or
44 /// experience time dilation (slow down or speed up), but it will never go
45 /// backwards.
46 ///
47 /// Instants are opaque types that can only be compared to one another. There is
48 /// no method to get "the number of seconds" from an instant. Instead, it only
49 /// allows measuring the duration between two instants (or comparing two
50 /// instants).
51 ///
52 /// Example:
53 ///
54 /// ```no_run
55 /// use std::time::{Duration, Instant};
56 /// use std::thread::sleep;
57 ///
58 /// fn main() {
59 ///    let now = Instant::now();
60 ///
61 ///    // we sleep for 2 seconds
62 ///    sleep(Duration::new(2, 0));
63 ///    // it prints '2'
64 ///    println!("{}", now.elapsed().as_secs());
65 /// }
66 /// ```
67 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
68 #[stable(feature = "time2", since = "1.8.0")]
69 pub struct Instant(time::Instant);
70
71 /// A measurement of the system clock, useful for talking to
72 /// external entities like the file system or other processes.
73 ///
74 /// Distinct from the [`Instant`] type, this time measurement **is not
75 /// monotonic**. This means that you can save a file to the file system, then
76 /// save another file to the file system, **and the second file has a
77 /// `SystemTime` measurement earlier than the first**. In other words, an
78 /// operation that happens after another operation in real time may have an
79 /// earlier `SystemTime`!
80 ///
81 /// Consequently, comparing two `SystemTime` instances to learn about the
82 /// duration between them returns a [`Result`] instead of an infallible [`Duration`]
83 /// to indicate that this sort of time drift may happen and needs to be handled.
84 ///
85 /// Although a `SystemTime` cannot be directly inspected, the [`UNIX_EPOCH`]
86 /// constant is provided in this module as an anchor in time to learn
87 /// information about a `SystemTime`. By calculating the duration from this
88 /// fixed point in time, a `SystemTime` can be converted to a human-readable time,
89 /// or perhaps some other string representation.
90 ///
91 /// [`Instant`]: ../../std/time/struct.Instant.html
92 /// [`Result`]: ../../std/result/enum.Result.html
93 /// [`Duration`]: ../../std/time/struct.Duration.html
94 /// [`UNIX_EPOCH`]: ../../std/time/constant.UNIX_EPOCH.html
95 ///
96 /// Example:
97 ///
98 /// ```no_run
99 /// use std::time::{Duration, SystemTime};
100 /// use std::thread::sleep;
101 ///
102 /// fn main() {
103 ///    let now = SystemTime::now();
104 ///
105 ///    // we sleep for 2 seconds
106 ///    sleep(Duration::new(2, 0));
107 ///    match now.elapsed() {
108 ///        Ok(elapsed) => {
109 ///            // it prints '2'
110 ///            println!("{}", elapsed.as_secs());
111 ///        }
112 ///        Err(e) => {
113 ///            // an error occurred!
114 ///            println!("Error: {:?}", e);
115 ///        }
116 ///    }
117 /// }
118 /// ```
119 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
120 #[stable(feature = "time2", since = "1.8.0")]
121 pub struct SystemTime(time::SystemTime);
122
123 /// An error returned from the `duration_since` and `elapsed` methods on
124 /// `SystemTime`, used to learn how far in the opposite direction a system time
125 /// lies.
126 ///
127 /// # Examples
128 ///
129 /// ```no_run
130 /// use std::thread::sleep;
131 /// use std::time::{Duration, SystemTime};
132 ///
133 /// let sys_time = SystemTime::now();
134 /// sleep(Duration::from_secs(1));
135 /// let new_sys_time = SystemTime::now();
136 /// match sys_time.duration_since(new_sys_time) {
137 ///     Ok(_) => {}
138 ///     Err(e) => println!("SystemTimeError difference: {:?}", e.duration()),
139 /// }
140 /// ```
141 #[derive(Clone, Debug)]
142 #[stable(feature = "time2", since = "1.8.0")]
143 pub struct SystemTimeError(Duration);
144
145 impl Instant {
146     /// Returns an instant corresponding to "now".
147     ///
148     /// # Examples
149     ///
150     /// ```
151     /// use std::time::Instant;
152     ///
153     /// let now = Instant::now();
154     /// ```
155     #[stable(feature = "time2", since = "1.8.0")]
156     pub fn now() -> Instant {
157         Instant(time::Instant::now())
158     }
159
160     /// Returns the amount of time elapsed from another instant to this one.
161     ///
162     /// # Panics
163     ///
164     /// This function will panic if `earlier` is later than `self`.
165     ///
166     /// # Examples
167     ///
168     /// ```no_run
169     /// use std::time::{Duration, Instant};
170     /// use std::thread::sleep;
171     ///
172     /// let now = Instant::now();
173     /// sleep(Duration::new(1, 0));
174     /// let new_now = Instant::now();
175     /// println!("{:?}", new_now.duration_since(now));
176     /// ```
177     #[stable(feature = "time2", since = "1.8.0")]
178     pub fn duration_since(&self, earlier: Instant) -> Duration {
179         self.0.sub_instant(&earlier.0)
180     }
181
182     /// Returns the amount of time elapsed since this instant was created.
183     ///
184     /// # Panics
185     ///
186     /// This function may panic if the current time is earlier than this
187     /// instant, which is something that can happen if an `Instant` is
188     /// produced synthetically.
189     ///
190     /// # Examples
191     ///
192     /// ```no_run
193     /// use std::thread::sleep;
194     /// use std::time::{Duration, Instant};
195     ///
196     /// let instant = Instant::now();
197     /// let three_secs = Duration::from_secs(3);
198     /// sleep(three_secs);
199     /// assert!(instant.elapsed() >= three_secs);
200     /// ```
201     #[stable(feature = "time2", since = "1.8.0")]
202     pub fn elapsed(&self) -> Duration {
203         Instant::now() - *self
204     }
205 }
206
207 #[stable(feature = "time2", since = "1.8.0")]
208 impl Add<Duration> for Instant {
209     type Output = Instant;
210
211     fn add(self, other: Duration) -> Instant {
212         Instant(self.0.add_duration(&other))
213     }
214 }
215
216 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
217 impl AddAssign<Duration> for Instant {
218     fn add_assign(&mut self, other: Duration) {
219         *self = *self + other;
220     }
221 }
222
223 #[stable(feature = "time2", since = "1.8.0")]
224 impl Sub<Duration> for Instant {
225     type Output = Instant;
226
227     fn sub(self, other: Duration) -> Instant {
228         Instant(self.0.sub_duration(&other))
229     }
230 }
231
232 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
233 impl SubAssign<Duration> for Instant {
234     fn sub_assign(&mut self, other: Duration) {
235         *self = *self - other;
236     }
237 }
238
239 #[stable(feature = "time2", since = "1.8.0")]
240 impl Sub<Instant> for Instant {
241     type Output = Duration;
242
243     fn sub(self, other: Instant) -> Duration {
244         self.duration_since(other)
245     }
246 }
247
248 #[stable(feature = "time2", since = "1.8.0")]
249 impl fmt::Debug for Instant {
250     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
251         self.0.fmt(f)
252     }
253 }
254
255 impl SystemTime {
256     /// Returns the system time corresponding to "now".
257     ///
258     /// # Examples
259     ///
260     /// ```
261     /// use std::time::SystemTime;
262     ///
263     /// let sys_time = SystemTime::now();
264     /// ```
265     #[stable(feature = "time2", since = "1.8.0")]
266     pub fn now() -> SystemTime {
267         SystemTime(time::SystemTime::now())
268     }
269
270     /// Returns the amount of time elapsed from an earlier point in time.
271     ///
272     /// This function may fail because measurements taken earlier are not
273     /// guaranteed to always be before later measurements (due to anomalies such
274     /// as the system clock being adjusted either forwards or backwards).
275     ///
276     /// If successful, [`Ok`]`(`[`Duration`]`)` is returned where the duration represents
277     /// the amount of time elapsed from the specified measurement to this one.
278     ///
279     /// Returns an [`Err`] if `earlier` is later than `self`, and the error
280     /// contains how far from `self` the time is.
281     ///
282     /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok
283     /// [`Duration`]: ../../std/time/struct.Duration.html
284     /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
285     ///
286     /// # Examples
287     ///
288     /// ```
289     /// use std::time::SystemTime;
290     ///
291     /// let sys_time = SystemTime::now();
292     /// let difference = sys_time.duration_since(sys_time)
293     ///                          .expect("SystemTime::duration_since failed");
294     /// println!("{:?}", difference);
295     /// ```
296     #[stable(feature = "time2", since = "1.8.0")]
297     pub fn duration_since(&self, earlier: SystemTime)
298                           -> Result<Duration, SystemTimeError> {
299         self.0.sub_time(&earlier.0).map_err(SystemTimeError)
300     }
301
302     /// Returns the amount of time elapsed since this system time was created.
303     ///
304     /// This function may fail as the underlying system clock is susceptible to
305     /// drift and updates (e.g. the system clock could go backwards), so this
306     /// function may not always succeed. If successful, [`Ok`]`(`[`Duration`]`)` is
307     /// returned where the duration represents the amount of time elapsed from
308     /// this time measurement to the current time.
309     ///
310     /// Returns an [`Err`] if `self` is later than the current system time, and
311     /// the error contains how far from the current system time `self` is.
312     ///
313     /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok
314     /// [`Duration`]: ../../std/time/struct.Duration.html
315     /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
316     ///
317     /// # Examples
318     ///
319     /// ```no_run
320     /// use std::thread::sleep;
321     /// use std::time::{Duration, SystemTime};
322     ///
323     /// let sys_time = SystemTime::now();
324     /// let one_sec = Duration::from_secs(1);
325     /// sleep(one_sec);
326     /// assert!(sys_time.elapsed().unwrap() >= one_sec);
327     /// ```
328     #[stable(feature = "time2", since = "1.8.0")]
329     pub fn elapsed(&self) -> Result<Duration, SystemTimeError> {
330         SystemTime::now().duration_since(*self)
331     }
332 }
333
334 #[stable(feature = "time2", since = "1.8.0")]
335 impl Add<Duration> for SystemTime {
336     type Output = SystemTime;
337
338     fn add(self, dur: Duration) -> SystemTime {
339         SystemTime(self.0.add_duration(&dur))
340     }
341 }
342
343 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
344 impl AddAssign<Duration> for SystemTime {
345     fn add_assign(&mut self, other: Duration) {
346         *self = *self + other;
347     }
348 }
349
350 #[stable(feature = "time2", since = "1.8.0")]
351 impl Sub<Duration> for SystemTime {
352     type Output = SystemTime;
353
354     fn sub(self, dur: Duration) -> SystemTime {
355         SystemTime(self.0.sub_duration(&dur))
356     }
357 }
358
359 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
360 impl SubAssign<Duration> for SystemTime {
361     fn sub_assign(&mut self, other: Duration) {
362         *self = *self - other;
363     }
364 }
365
366 #[stable(feature = "time2", since = "1.8.0")]
367 impl fmt::Debug for SystemTime {
368     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
369         self.0.fmt(f)
370     }
371 }
372
373 /// An anchor in time which can be used to create new `SystemTime` instances or
374 /// learn about where in time a `SystemTime` lies.
375 ///
376 /// This constant is defined to be "1970-01-01 00:00:00 UTC" on all systems with
377 /// respect to the system clock. Using `duration_since` on an existing
378 /// [`SystemTime`] instance can tell how far away from this point in time a
379 /// measurement lies, and using `UNIX_EPOCH + duration` can be used to create a
380 /// [`SystemTime`] instance to represent another fixed point in time.
381 ///
382 /// [`SystemTime`]: ../../std/time/struct.SystemTime.html
383 ///
384 /// # Examples
385 ///
386 /// ```no_run
387 /// use std::time::{SystemTime, UNIX_EPOCH};
388 ///
389 /// match SystemTime::now().duration_since(UNIX_EPOCH) {
390 ///     Ok(n) => println!("1970-01-01 00:00:00 UTC was {} seconds ago!", n.as_secs()),
391 ///     Err(_) => panic!("SystemTime before UNIX EPOCH!"),
392 /// }
393 /// ```
394 #[stable(feature = "time2", since = "1.8.0")]
395 pub const UNIX_EPOCH: SystemTime = SystemTime(time::UNIX_EPOCH);
396
397 impl SystemTimeError {
398     /// Returns the positive duration which represents how far forward the
399     /// second system time was from the first.
400     ///
401     /// A `SystemTimeError` is returned from the [`duration_since`] and [`elapsed`]
402     /// methods of [`SystemTime`] whenever the second system time represents a point later
403     /// in time than the `self` of the method call.
404     ///
405     /// [`duration_since`]: ../../std/time/struct.SystemTime.html#method.duration_since
406     /// [`elapsed`]: ../../std/time/struct.SystemTime.html#method.elapsed
407     /// [`SystemTime`]: ../../std/time/struct.SystemTime.html
408     ///
409     /// # Examples
410     ///
411     /// ```no_run
412     /// use std::thread::sleep;
413     /// use std::time::{Duration, SystemTime};
414     ///
415     /// let sys_time = SystemTime::now();
416     /// sleep(Duration::from_secs(1));
417     /// let new_sys_time = SystemTime::now();
418     /// match sys_time.duration_since(new_sys_time) {
419     ///     Ok(_) => {}
420     ///     Err(e) => println!("SystemTimeError difference: {:?}", e.duration()),
421     /// }
422     /// ```
423     #[stable(feature = "time2", since = "1.8.0")]
424     pub fn duration(&self) -> Duration {
425         self.0
426     }
427 }
428
429 #[stable(feature = "time2", since = "1.8.0")]
430 impl Error for SystemTimeError {
431     fn description(&self) -> &str { "other time was not earlier than self" }
432 }
433
434 #[stable(feature = "time2", since = "1.8.0")]
435 impl fmt::Display for SystemTimeError {
436     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
437         write!(f, "second time provided was later than self")
438     }
439 }
440
441 impl FromInner<time::SystemTime> for SystemTime {
442     fn from_inner(time: time::SystemTime) -> SystemTime {
443         SystemTime(time)
444     }
445 }
446
447 #[cfg(test)]
448 mod tests {
449     use super::{Instant, SystemTime, Duration, UNIX_EPOCH};
450
451     macro_rules! assert_almost_eq {
452         ($a:expr, $b:expr) => ({
453             let (a, b) = ($a, $b);
454             if a != b {
455                 let (a, b) = if a > b {(a, b)} else {(b, a)};
456                 assert!(a - Duration::new(0, 100) <= b);
457             }
458         })
459     }
460
461     #[test]
462     fn instant_monotonic() {
463         let a = Instant::now();
464         let b = Instant::now();
465         assert!(b >= a);
466     }
467
468     #[test]
469     fn instant_elapsed() {
470         let a = Instant::now();
471         a.elapsed();
472     }
473
474     #[test]
475     fn instant_math() {
476         let a = Instant::now();
477         let b = Instant::now();
478         let dur = b.duration_since(a);
479         assert_almost_eq!(b - dur, a);
480         assert_almost_eq!(a + dur, b);
481
482         let second = Duration::new(1, 0);
483         assert_almost_eq!(a - second + second, a);
484     }
485
486     #[test]
487     #[should_panic]
488     fn instant_duration_panic() {
489         let a = Instant::now();
490         (a - Duration::new(1, 0)).duration_since(a);
491     }
492
493     #[test]
494     fn system_time_math() {
495         let a = SystemTime::now();
496         let b = SystemTime::now();
497         match b.duration_since(a) {
498             Ok(dur) if dur == Duration::new(0, 0) => {
499                 assert_almost_eq!(a, b);
500             }
501             Ok(dur) => {
502                 assert!(b > a);
503                 assert_almost_eq!(b - dur, a);
504                 assert_almost_eq!(a + dur, b);
505             }
506             Err(dur) => {
507                 let dur = dur.duration();
508                 assert!(a > b);
509                 assert_almost_eq!(b + dur, a);
510                 assert_almost_eq!(a - dur, b);
511             }
512         }
513
514         let second = Duration::new(1, 0);
515         assert_almost_eq!(a.duration_since(a - second).unwrap(), second);
516         assert_almost_eq!(a.duration_since(a + second).unwrap_err()
517                            .duration(), second);
518
519         assert_almost_eq!(a - second + second, a);
520
521         // A difference of 80 and 800 years cannot fit inside a 32-bit time_t
522         if !(cfg!(unix) && ::mem::size_of::<::libc::time_t>() <= 4) {
523             let eighty_years = second * 60 * 60 * 24 * 365 * 80;
524             assert_almost_eq!(a - eighty_years + eighty_years, a);
525             assert_almost_eq!(a - (eighty_years * 10) + (eighty_years * 10), a);
526         }
527
528         let one_second_from_epoch = UNIX_EPOCH + Duration::new(1, 0);
529         let one_second_from_epoch2 = UNIX_EPOCH + Duration::new(0, 500_000_000)
530             + Duration::new(0, 500_000_000);
531         assert_eq!(one_second_from_epoch, one_second_from_epoch2);
532     }
533
534     #[test]
535     fn system_time_elapsed() {
536         let a = SystemTime::now();
537         drop(a.elapsed());
538     }
539
540     #[test]
541     fn since_epoch() {
542         let ts = SystemTime::now();
543         let a = ts.duration_since(UNIX_EPOCH).unwrap();
544         let b = ts.duration_since(UNIX_EPOCH - Duration::new(1, 0)).unwrap();
545         assert!(b > a);
546         assert_eq!(b - a, Duration::new(1, 0));
547
548         let thirty_years = Duration::new(1, 0) * 60 * 60 * 24 * 365 * 30;
549
550         // Right now for CI this test is run in an emulator, and apparently the
551         // aarch64 emulator's sense of time is that we're still living in the
552         // 70s.
553         //
554         // Otherwise let's assume that we're all running computers later than
555         // 2000.
556         if !cfg!(target_arch = "aarch64") {
557             assert!(a > thirty_years);
558         }
559
560         // let's assume that we're all running computers earlier than 2090.
561         // Should give us ~70 years to fix this!
562         let hundred_twenty_years = thirty_years * 4;
563         assert!(a < hundred_twenty_years);
564     }
565 }