]> git.proxmox.com Git - rustc.git/blame - src/libstd/time/mod.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / libstd / time / mod.rs
CommitLineData
1a4d82fc
JJ
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.
54a0048b
SL
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//! ```
1a4d82fc 22
c1a9b12d 23#![stable(feature = "time", since = "1.3.0")]
1a4d82fc 24
92a42be0
SL
25use error::Error;
26use fmt;
54a0048b 27use ops::{Add, Sub, AddAssign, SubAssign};
92a42be0 28use sys::time;
7453a54e 29use sys_common::FromInner;
92a42be0
SL
30
31#[stable(feature = "time", since = "1.3.0")]
1a4d82fc
JJ
32pub use self::duration::Duration;
33
d9579d0f 34mod duration;
92a42be0
SL
35
36/// A measurement of a monotonically increasing clock.
9cc50fc6 37/// Opaque and useful only with `Duration`.
92a42be0
SL
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).
54a0048b
SL
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/// ```
92a42be0 69#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
7453a54e 70#[stable(feature = "time2", since = "1.8.0")]
92a42be0
SL
71pub struct Instant(time::Instant);
72
9cc50fc6
SL
73/// A measurement of the system clock, useful for talking to
74/// external entities like the file system or other processes.
92a42be0
SL
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 second**. 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.
54a0048b
SL
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/// ```
92a42be0 116#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
7453a54e 117#[stable(feature = "time2", since = "1.8.0")]
92a42be0
SL
118pub struct SystemTime(time::SystemTime);
119
7453a54e 120/// An error returned from the `duration_since` method on `SystemTime`,
92a42be0
SL
121/// used to learn about why how far in the opposite direction a timestamp lies.
122#[derive(Clone, Debug)]
7453a54e 123#[stable(feature = "time2", since = "1.8.0")]
92a42be0
SL
124pub struct SystemTimeError(Duration);
125
92a42be0
SL
126impl Instant {
127 /// Returns an instant corresponding to "now".
7453a54e 128 #[stable(feature = "time2", since = "1.8.0")]
92a42be0
SL
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.
7453a54e
SL
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 /// Deprecated, renamed to `duration_since`
147 #[unstable(feature = "time2_old", issue = "29866")]
148 #[rustc_deprecated(since = "1.8.0", reason = "renamed to duration_since")]
92a42be0
SL
149 pub fn duration_from_earlier(&self, earlier: Instant) -> Duration {
150 self.0.sub_instant(&earlier.0)
151 }
152
153 /// Returns the amount of time elapsed since this instant was created.
154 ///
155 /// # Panics
156 ///
157 /// This function may panic if the current time is earlier than this
158 /// instant, which is something that can happen if an `Instant` is
159 /// produced synthetically.
7453a54e 160 #[stable(feature = "time2", since = "1.8.0")]
92a42be0 161 pub fn elapsed(&self) -> Duration {
7453a54e 162 Instant::now() - *self
92a42be0
SL
163 }
164}
165
7453a54e 166#[stable(feature = "time2", since = "1.8.0")]
92a42be0
SL
167impl Add<Duration> for Instant {
168 type Output = Instant;
169
170 fn add(self, other: Duration) -> Instant {
171 Instant(self.0.add_duration(&other))
172 }
173}
174
54a0048b
SL
175#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
176impl AddAssign<Duration> for Instant {
177 fn add_assign(&mut self, other: Duration) {
178 *self = *self + other;
179 }
180}
181
7453a54e 182#[stable(feature = "time2", since = "1.8.0")]
92a42be0
SL
183impl Sub<Duration> for Instant {
184 type Output = Instant;
185
186 fn sub(self, other: Duration) -> Instant {
187 Instant(self.0.sub_duration(&other))
188 }
189}
190
54a0048b
SL
191#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
192impl SubAssign<Duration> for Instant {
193 fn sub_assign(&mut self, other: Duration) {
194 *self = *self - other;
195 }
196}
197
7453a54e
SL
198#[stable(feature = "time2", since = "1.8.0")]
199impl Sub<Instant> for Instant {
200 type Output = Duration;
201
202 fn sub(self, other: Instant) -> Duration {
203 self.duration_since(other)
204 }
205}
206
207#[stable(feature = "time2", since = "1.8.0")]
92a42be0
SL
208impl fmt::Debug for Instant {
209 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
210 self.0.fmt(f)
211 }
212}
213
92a42be0
SL
214impl SystemTime {
215 /// Returns the system time corresponding to "now".
7453a54e 216 #[stable(feature = "time2", since = "1.8.0")]
92a42be0
SL
217 pub fn now() -> SystemTime {
218 SystemTime(time::SystemTime::now())
219 }
220
221 /// Returns the amount of time elapsed from an earlier point in time.
222 ///
223 /// This function may fail because measurements taken earlier are not
224 /// guaranteed to always be before later measurements (due to anomalies such
225 /// as the system clock being adjusted either forwards or backwards).
226 ///
227 /// If successful, `Ok(Duration)` is returned where the duration represents
228 /// the amount of time elapsed from the specified measurement to this one.
229 ///
230 /// Returns an `Err` if `earlier` is later than `self`, and the error
231 /// contains how far from `self` the time is.
7453a54e
SL
232 #[stable(feature = "time2", since = "1.8.0")]
233 pub fn duration_since(&self, earlier: SystemTime)
234 -> Result<Duration, SystemTimeError> {
235 self.0.sub_time(&earlier.0).map_err(SystemTimeError)
236 }
237
238 /// Deprecated, renamed to `duration_since`
239 #[unstable(feature = "time2_old", issue = "29866")]
240 #[rustc_deprecated(since = "1.8.0", reason = "renamed to duration_since")]
92a42be0
SL
241 pub fn duration_from_earlier(&self, earlier: SystemTime)
242 -> Result<Duration, SystemTimeError> {
243 self.0.sub_time(&earlier.0).map_err(SystemTimeError)
244 }
245
246 /// Returns the amount of time elapsed since this system time was created.
247 ///
248 /// This function may fail as the underlying system clock is susceptible to
249 /// drift and updates (e.g. the system clock could go backwards), so this
250 /// function may not always succeed. If successful, `Ok(duration)` is
251 /// returned where the duration represents the amount of time elapsed from
252 /// this time measurement to the current time.
253 ///
254 /// Returns an `Err` if `self` is later than the current system time, and
255 /// the error contains how far from the current system time `self` is.
7453a54e 256 #[stable(feature = "time2", since = "1.8.0")]
92a42be0 257 pub fn elapsed(&self) -> Result<Duration, SystemTimeError> {
7453a54e 258 SystemTime::now().duration_since(*self)
92a42be0
SL
259 }
260}
261
7453a54e 262#[stable(feature = "time2", since = "1.8.0")]
92a42be0
SL
263impl Add<Duration> for SystemTime {
264 type Output = SystemTime;
265
266 fn add(self, dur: Duration) -> SystemTime {
267 SystemTime(self.0.add_duration(&dur))
268 }
269}
270
54a0048b
SL
271#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
272impl AddAssign<Duration> for SystemTime {
273 fn add_assign(&mut self, other: Duration) {
274 *self = *self + other;
275 }
276}
277
7453a54e 278#[stable(feature = "time2", since = "1.8.0")]
92a42be0
SL
279impl Sub<Duration> for SystemTime {
280 type Output = SystemTime;
281
282 fn sub(self, dur: Duration) -> SystemTime {
283 SystemTime(self.0.sub_duration(&dur))
284 }
285}
286
54a0048b
SL
287#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
288impl SubAssign<Duration> for SystemTime {
289 fn sub_assign(&mut self, other: Duration) {
290 *self = *self - other;
291 }
292}
293
7453a54e 294#[stable(feature = "time2", since = "1.8.0")]
92a42be0
SL
295impl fmt::Debug for SystemTime {
296 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
297 self.0.fmt(f)
298 }
299}
300
301/// An anchor in time which can be used to create new `SystemTime` instances or
302/// learn about where in time a `SystemTime` lies.
303///
304/// This constant is defined to be "1970-01-01 00:00:00 UTC" on all systems with
7453a54e 305/// respect to the system clock. Using `duration_since` on an existing
92a42be0
SL
306/// `SystemTime` instance can tell how far away from this point in time a
307/// measurement lies, and using `UNIX_EPOCH + duration` can be used to create a
308/// `SystemTime` instance to represent another fixed point in time.
7453a54e 309#[stable(feature = "time2", since = "1.8.0")]
92a42be0
SL
310pub const UNIX_EPOCH: SystemTime = SystemTime(time::UNIX_EPOCH);
311
92a42be0
SL
312impl SystemTimeError {
313 /// Returns the positive duration which represents how far forward the
314 /// second system time was from the first.
315 ///
7453a54e 316 /// A `SystemTimeError` is returned from the `duration_since`
92a42be0
SL
317 /// operation whenever the second system time represents a point later
318 /// in time than the `self` of the method call.
7453a54e 319 #[stable(feature = "time2", since = "1.8.0")]
92a42be0
SL
320 pub fn duration(&self) -> Duration {
321 self.0
322 }
323}
324
7453a54e 325#[stable(feature = "time2", since = "1.8.0")]
92a42be0
SL
326impl Error for SystemTimeError {
327 fn description(&self) -> &str { "other time was not earlier than self" }
328}
329
7453a54e 330#[stable(feature = "time2", since = "1.8.0")]
92a42be0
SL
331impl fmt::Display for SystemTimeError {
332 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
333 write!(f, "second time provided was later than self")
334 }
335}
336
7453a54e
SL
337impl FromInner<time::SystemTime> for SystemTime {
338 fn from_inner(time: time::SystemTime) -> SystemTime {
339 SystemTime(time)
340 }
341}
342
92a42be0
SL
343#[cfg(test)]
344mod tests {
345 use super::{Instant, SystemTime, Duration, UNIX_EPOCH};
346
347 macro_rules! assert_almost_eq {
348 ($a:expr, $b:expr) => ({
349 let (a, b) = ($a, $b);
350 if a != b {
351 let (a, b) = if a > b {(a, b)} else {(b, a)};
352 assert!(a - Duration::new(0, 100) <= b);
353 }
354 })
355 }
356
357 #[test]
358 fn instant_monotonic() {
359 let a = Instant::now();
360 let b = Instant::now();
361 assert!(b >= a);
362 }
363
364 #[test]
365 fn instant_elapsed() {
366 let a = Instant::now();
367 a.elapsed();
368 }
369
370 #[test]
371 fn instant_math() {
372 let a = Instant::now();
373 let b = Instant::now();
7453a54e 374 let dur = b.duration_since(a);
92a42be0
SL
375 assert_almost_eq!(b - dur, a);
376 assert_almost_eq!(a + dur, b);
377
378 let second = Duration::new(1, 0);
379 assert_almost_eq!(a - second + second, a);
380 }
381
382 #[test]
383 #[should_panic]
384 fn instant_duration_panic() {
385 let a = Instant::now();
7453a54e 386 (a - Duration::new(1, 0)).duration_since(a);
92a42be0
SL
387 }
388
389 #[test]
390 fn system_time_math() {
391 let a = SystemTime::now();
392 let b = SystemTime::now();
7453a54e 393 match b.duration_since(a) {
92a42be0
SL
394 Ok(dur) if dur == Duration::new(0, 0) => {
395 assert_almost_eq!(a, b);
396 }
397 Ok(dur) => {
398 assert!(b > a);
399 assert_almost_eq!(b - dur, a);
400 assert_almost_eq!(a + dur, b);
401 }
402 Err(dur) => {
403 let dur = dur.duration();
404 assert!(a > b);
405 assert_almost_eq!(b + dur, a);
406 assert_almost_eq!(b - dur, a);
407 }
408 }
409
410 let second = Duration::new(1, 0);
7453a54e
SL
411 assert_almost_eq!(a.duration_since(a - second).unwrap(), second);
412 assert_almost_eq!(a.duration_since(a + second).unwrap_err()
92a42be0
SL
413 .duration(), second);
414
415 assert_almost_eq!(a - second + second, a);
416
417 let eighty_years = second * 60 * 60 * 24 * 365 * 80;
418 assert_almost_eq!(a - eighty_years + eighty_years, a);
419 assert_almost_eq!(a - (eighty_years * 10) + (eighty_years * 10), a);
420
421 let one_second_from_epoch = UNIX_EPOCH + Duration::new(1, 0);
422 let one_second_from_epoch2 = UNIX_EPOCH + Duration::new(0, 500_000_000)
423 + Duration::new(0, 500_000_000);
424 assert_eq!(one_second_from_epoch, one_second_from_epoch2);
425 }
426
427 #[test]
428 fn system_time_elapsed() {
429 let a = SystemTime::now();
430 drop(a.elapsed());
431 }
432
433 #[test]
434 fn since_epoch() {
435 let ts = SystemTime::now();
7453a54e
SL
436 let a = ts.duration_since(UNIX_EPOCH).unwrap();
437 let b = ts.duration_since(UNIX_EPOCH - Duration::new(1, 0)).unwrap();
92a42be0
SL
438 assert!(b > a);
439 assert_eq!(b - a, Duration::new(1, 0));
440
441 // let's assume that we're all running computers later than 2000
442 let thirty_years = Duration::new(1, 0) * 60 * 60 * 24 * 365 * 30;
443 assert!(a > thirty_years);
444
445 // let's assume that we're all running computers earlier than 2090.
446 // Should give us ~70 years to fix this!
447 let hundred_twenty_years = thirty_years * 4;
448 assert!(a < hundred_twenty_years);
449 }
450}