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 use super::Tm;
12 use libc::{self, time_t};
13 use std::io;
14 use std::mem;
15
16 #[cfg(any(target_os = "solaris", target_os = "illumos"))]
17 extern "C" {
18 static timezone: time_t;
19 static altzone: time_t;
20 }
21
22 #[cfg(any(target_os = "solaris", target_os = "illumos"))]
tzset()23 fn tzset() {
24 extern "C" {
25 fn tzset();
26 }
27 unsafe { tzset() }
28 }
29
rust_tm_to_tm(rust_tm: &Tm, tm: &mut libc::tm)30 fn rust_tm_to_tm(rust_tm: &Tm, tm: &mut libc::tm) {
31 tm.tm_sec = rust_tm.tm_sec;
32 tm.tm_min = rust_tm.tm_min;
33 tm.tm_hour = rust_tm.tm_hour;
34 tm.tm_mday = rust_tm.tm_mday;
35 tm.tm_mon = rust_tm.tm_mon;
36 tm.tm_year = rust_tm.tm_year;
37 tm.tm_wday = rust_tm.tm_wday;
38 tm.tm_yday = rust_tm.tm_yday;
39 tm.tm_isdst = rust_tm.tm_isdst;
40 }
41
tm_to_rust_tm(tm: &libc::tm, utcoff: i32, rust_tm: &mut Tm)42 fn tm_to_rust_tm(tm: &libc::tm, utcoff: i32, rust_tm: &mut Tm) {
43 rust_tm.tm_sec = tm.tm_sec;
44 rust_tm.tm_min = tm.tm_min;
45 rust_tm.tm_hour = tm.tm_hour;
46 rust_tm.tm_mday = tm.tm_mday;
47 rust_tm.tm_mon = tm.tm_mon;
48 rust_tm.tm_year = tm.tm_year;
49 rust_tm.tm_wday = tm.tm_wday;
50 rust_tm.tm_yday = tm.tm_yday;
51 rust_tm.tm_isdst = tm.tm_isdst;
52 rust_tm.tm_utcoff = utcoff;
53 }
54
55 #[cfg(any(target_os = "nacl", target_os = "solaris", target_os = "illumos"))]
timegm(tm: *mut libc::tm) -> time_t56 unsafe fn timegm(tm: *mut libc::tm) -> time_t {
57 use std::env::{remove_var, set_var, var_os};
58 extern "C" {
59 fn tzset();
60 }
61
62 let ret;
63
64 let current_tz = var_os("TZ");
65 set_var("TZ", "UTC");
66 tzset();
67
68 ret = libc::mktime(tm);
69
70 if let Some(tz) = current_tz {
71 set_var("TZ", tz);
72 } else {
73 remove_var("TZ");
74 }
75 tzset();
76
77 ret
78 }
79
time_to_local_tm(sec: i64, tm: &mut Tm)80 pub fn time_to_local_tm(sec: i64, tm: &mut Tm) {
81 unsafe {
82 let sec = sec as time_t;
83 let mut out = mem::zeroed();
84 if libc::localtime_r(&sec, &mut out).is_null() {
85 panic!("localtime_r failed: {}", io::Error::last_os_error());
86 }
87 #[cfg(any(target_os = "solaris", target_os = "illumos"))]
88 let gmtoff = {
89 tzset();
90 // < 0 means we don't know; assume we're not in DST.
91 if out.tm_isdst == 0 {
92 // timezone is seconds west of UTC, tm_gmtoff is seconds east
93 -timezone
94 } else if out.tm_isdst > 0 {
95 -altzone
96 } else {
97 -timezone
98 }
99 };
100 #[cfg(not(any(target_os = "solaris", target_os = "illumos")))]
101 let gmtoff = out.tm_gmtoff;
102 tm_to_rust_tm(&out, gmtoff as i32, tm);
103 }
104 }
105
utc_tm_to_time(rust_tm: &Tm) -> i64106 pub fn utc_tm_to_time(rust_tm: &Tm) -> i64 {
107 #[cfg(not(any(
108 all(target_os = "android", target_pointer_width = "32"),
109 target_os = "nacl",
110 target_os = "solaris",
111 target_os = "illumos"
112 )))]
113 use libc::timegm;
114 #[cfg(all(target_os = "android", target_pointer_width = "32"))]
115 use libc::timegm64 as timegm;
116
117 let mut tm = unsafe { mem::zeroed() };
118 rust_tm_to_tm(rust_tm, &mut tm);
119 unsafe { timegm(&mut tm) as i64 }
120 }
121
local_tm_to_time(rust_tm: &Tm) -> i64122 pub fn local_tm_to_time(rust_tm: &Tm) -> i64 {
123 let mut tm = unsafe { mem::zeroed() };
124 rust_tm_to_tm(rust_tm, &mut tm);
125 unsafe { libc::mktime(&mut tm) as i64 }
126 }
127