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 //! Platform wrappers for converting UTC times to and from the local time zone.
12 //!
13 //! This code was rescued from v0.1 of the time crate, which is no longer
14 //! maintained. It has been substantially stripped down to the bare minimum
15 //! required by chrono.
16 
17 use std::time::{SystemTime, UNIX_EPOCH};
18 
19 #[cfg(any(target_arch = "wasm32", target_env = "sgx"))]
20 #[path = "sys/stub.rs"]
21 mod inner;
22 
23 #[cfg(unix)]
24 #[path = "sys/unix.rs"]
25 mod inner;
26 
27 #[cfg(windows)]
28 #[path = "sys/windows.rs"]
29 mod inner;
30 
31 /// A record specifying a time value in seconds and nanoseconds, where
32 /// nanoseconds represent the offset from the given second.
33 ///
34 /// For example a timespec of 1.2 seconds after the beginning of the epoch would
35 /// be represented as {sec: 1, nsec: 200000000}.
36 pub struct Timespec {
37     pub sec: i64,
38     pub nsec: i32,
39 }
40 
41 impl Timespec {
42     /// Constructs a timespec representing the current time in UTC.
now() -> Timespec43     pub fn now() -> Timespec {
44         let st =
45             SystemTime::now().duration_since(UNIX_EPOCH).expect("system time before Unix epoch");
46         Timespec { sec: st.as_secs() as i64, nsec: st.subsec_nanos() as i32 }
47     }
48 
49     /// Converts this timespec into the system's local time.
local(self) -> Tm50     pub fn local(self) -> Tm {
51         let mut tm = Tm {
52             tm_sec: 0,
53             tm_min: 0,
54             tm_hour: 0,
55             tm_mday: 0,
56             tm_mon: 0,
57             tm_year: 0,
58             tm_wday: 0,
59             tm_yday: 0,
60             tm_isdst: 0,
61             tm_utcoff: 0,
62             tm_nsec: 0,
63         };
64         inner::time_to_local_tm(self.sec, &mut tm);
65         tm.tm_nsec = self.nsec;
66         tm
67     }
68 }
69 
70 /// Holds a calendar date and time broken down into its components (year, month,
71 /// day, and so on), also called a broken-down time value.
72 // FIXME: use c_int instead of i32?
73 #[cfg(feature = "clock")]
74 #[repr(C)]
75 pub struct Tm {
76     /// Seconds after the minute - [0, 60]
77     pub tm_sec: i32,
78 
79     /// Minutes after the hour - [0, 59]
80     pub tm_min: i32,
81 
82     /// Hours after midnight - [0, 23]
83     pub tm_hour: i32,
84 
85     /// Day of the month - [1, 31]
86     pub tm_mday: i32,
87 
88     /// Months since January - [0, 11]
89     pub tm_mon: i32,
90 
91     /// Years since 1900
92     pub tm_year: i32,
93 
94     /// Days since Sunday - [0, 6]. 0 = Sunday, 1 = Monday, ..., 6 = Saturday.
95     pub tm_wday: i32,
96 
97     /// Days since January 1 - [0, 365]
98     pub tm_yday: i32,
99 
100     /// Daylight Saving Time flag.
101     ///
102     /// This value is positive if Daylight Saving Time is in effect, zero if
103     /// Daylight Saving Time is not in effect, and negative if this information
104     /// is not available.
105     pub tm_isdst: i32,
106 
107     /// Identifies the time zone that was used to compute this broken-down time
108     /// value, including any adjustment for Daylight Saving Time. This is the
109     /// number of seconds east of UTC. For example, for U.S. Pacific Daylight
110     /// Time, the value is `-7*60*60 = -25200`.
111     pub tm_utcoff: i32,
112 
113     /// Nanoseconds after the second - [0, 10<sup>9</sup> - 1]
114     pub tm_nsec: i32,
115 }
116 
117 impl Tm {
118     /// Convert time to the seconds from January 1, 1970
to_timespec(&self) -> Timespec119     pub fn to_timespec(&self) -> Timespec {
120         let sec = match self.tm_utcoff {
121             0 => inner::utc_tm_to_time(self),
122             _ => inner::local_tm_to_time(self),
123         };
124         Timespec { sec: sec, nsec: self.tm_nsec }
125     }
126 }
127