]> git.proxmox.com Git - rustc.git/blob - src/libstd/time/mod.rs
Imported Upstream version 1.6.0+dfsg1
[rustc.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 #![stable(feature = "time", since = "1.3.0")]
14
15 use error::Error;
16 use fmt;
17 use ops::{Add, Sub};
18 use sys::time;
19
20 #[stable(feature = "time", since = "1.3.0")]
21 pub use self::duration::Duration;
22
23 mod duration;
24
25 /// A measurement of a monotonically increasing clock.
26 ///
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.
30 ///
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
35 /// backwards.
36 ///
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
40 /// instants).
41 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
42 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
43 pub struct Instant(time::Instant);
44
45 /// A measurement of the system clock appropriate for timestamps such as those
46 /// on files on the filesystem.
47 ///
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`!
54 ///
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.
58 ///
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);
67
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);
73
74 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
75 impl Instant {
76 /// Returns an instant corresponding to "now".
77 pub fn now() -> Instant {
78 Instant(time::Instant::now())
79 }
80
81 /// Returns the amount of time elapsed from another instant to this one.
82 ///
83 /// # Panics
84 ///
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
88 /// a bug.
89 pub fn duration_from_earlier(&self, earlier: Instant) -> Duration {
90 self.0.sub_instant(&earlier.0)
91 }
92
93 /// Returns the amount of time elapsed since this instant was created.
94 ///
95 /// # Panics
96 ///
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)
102 }
103 }
104
105 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
106 impl Add<Duration> for Instant {
107 type Output = Instant;
108
109 fn add(self, other: Duration) -> Instant {
110 Instant(self.0.add_duration(&other))
111 }
112 }
113
114 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
115 impl Sub<Duration> for Instant {
116 type Output = Instant;
117
118 fn sub(self, other: Duration) -> Instant {
119 Instant(self.0.sub_duration(&other))
120 }
121 }
122
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 {
126 self.0.fmt(f)
127 }
128 }
129
130 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
131 impl SystemTime {
132 /// Returns the system time corresponding to "now".
133 pub fn now() -> SystemTime {
134 SystemTime(time::SystemTime::now())
135 }
136
137 /// Returns the amount of time elapsed from an earlier point in time.
138 ///
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).
142 ///
143 /// If successful, `Ok(Duration)` is returned where the duration represents
144 /// the amount of time elapsed from the specified measurement to this one.
145 ///
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)
151 }
152
153 /// Returns the amount of time elapsed since this system time was created.
154 ///
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.
160 ///
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)
165 }
166 }
167
168 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
169 impl Add<Duration> for SystemTime {
170 type Output = SystemTime;
171
172 fn add(self, dur: Duration) -> SystemTime {
173 SystemTime(self.0.add_duration(&dur))
174 }
175 }
176
177 #[unstable(feature = "time2", reason = "recently added", issue = "29866")]
178 impl Sub<Duration> for SystemTime {
179 type Output = SystemTime;
180
181 fn sub(self, dur: Duration) -> SystemTime {
182 SystemTime(self.0.sub_duration(&dur))
183 }
184 }
185
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 {
189 self.0.fmt(f)
190 }
191 }
192
193 /// An anchor in time which can be used to create new `SystemTime` instances or
194 /// learn about where in time a `SystemTime` lies.
195 ///
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);
203
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.
208 ///
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 {
213 self.0
214 }
215 }
216
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" }
220 }
221
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")
226 }
227 }
228
229 #[cfg(test)]
230 mod tests {
231 use super::{Instant, SystemTime, Duration, UNIX_EPOCH};
232
233 macro_rules! assert_almost_eq {
234 ($a:expr, $b:expr) => ({
235 let (a, b) = ($a, $b);
236 if a != b {
237 let (a, b) = if a > b {(a, b)} else {(b, a)};
238 assert!(a - Duration::new(0, 100) <= b);
239 }
240 })
241 }
242
243 #[test]
244 fn instant_monotonic() {
245 let a = Instant::now();
246 let b = Instant::now();
247 assert!(b >= a);
248 }
249
250 #[test]
251 fn instant_elapsed() {
252 let a = Instant::now();
253 a.elapsed();
254 }
255
256 #[test]
257 fn instant_math() {
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);
263
264 let second = Duration::new(1, 0);
265 assert_almost_eq!(a - second + second, a);
266 }
267
268 #[test]
269 #[should_panic]
270 fn instant_duration_panic() {
271 let a = Instant::now();
272 (a - Duration::new(1, 0)).duration_from_earlier(a);
273 }
274
275 #[test]
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);
282 }
283 Ok(dur) => {
284 assert!(b > a);
285 assert_almost_eq!(b - dur, a);
286 assert_almost_eq!(a + dur, b);
287 }
288 Err(dur) => {
289 let dur = dur.duration();
290 assert!(a > b);
291 assert_almost_eq!(b + dur, a);
292 assert_almost_eq!(b - dur, a);
293 }
294 }
295
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);
300
301 assert_almost_eq!(a - second + second, a);
302
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);
306
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);
311 }
312
313 #[test]
314 fn system_time_elapsed() {
315 let a = SystemTime::now();
316 drop(a.elapsed());
317 }
318
319 #[test]
320 fn since_epoch() {
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();
324 assert!(b > a);
325 assert_eq!(b - a, Duration::new(1, 0));
326
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);
330
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);
335 }
336 }