]>
Commit | Line | Data |
---|---|---|
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 |
25 | use error::Error; |
26 | use fmt; | |
54a0048b | 27 | use ops::{Add, Sub, AddAssign, SubAssign}; |
92a42be0 | 28 | use sys::time; |
7453a54e | 29 | use sys_common::FromInner; |
92a42be0 SL |
30 | |
31 | #[stable(feature = "time", since = "1.3.0")] | |
1a4d82fc JJ |
32 | pub use self::duration::Duration; |
33 | ||
d9579d0f | 34 | mod 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 |
71 | pub 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 |
118 | pub 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 |
124 | pub struct SystemTimeError(Duration); |
125 | ||
92a42be0 SL |
126 | impl 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 |
167 | impl 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")] |
176 | impl 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 |
183 | impl 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")] |
192 | impl 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")] |
199 | impl 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 |
208 | impl fmt::Debug for Instant { |
209 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
210 | self.0.fmt(f) | |
211 | } | |
212 | } | |
213 | ||
92a42be0 SL |
214 | impl 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 |
263 | impl 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")] |
272 | impl 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 |
279 | impl 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")] |
288 | impl 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 |
295 | impl 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 |
310 | pub const UNIX_EPOCH: SystemTime = SystemTime(time::UNIX_EPOCH); |
311 | ||
92a42be0 SL |
312 | impl 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 |
326 | impl 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 |
331 | impl 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 |
337 | impl FromInner<time::SystemTime> for SystemTime { |
338 | fn from_inner(time: time::SystemTime) -> SystemTime { | |
339 | SystemTime(time) | |
340 | } | |
341 | } | |
342 | ||
92a42be0 SL |
343 | #[cfg(test)] |
344 | mod 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 | } |