1 // Copyright 2013 The Servo Project Developers. See the COPYRIGHT 2 // file at the top-level directory of this distribution. 3 // 4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or 5 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license 6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your 7 // option. This file may not be copied, modified, or distributed 8 // except according to those terms. 9 10 //! Core Foundation time zone objects. 11 12 pub use core_foundation_sys::timezone::*; 13 use core_foundation_sys::base::kCFAllocatorDefault; 14 15 use base::TCFType; 16 use date::{CFDate, CFTimeInterval}; 17 use string::CFString; 18 19 #[cfg(feature = "with-chrono")] 20 use chrono::{FixedOffset, NaiveDateTime}; 21 22 23 declare_TCFType!{ 24 /// A time zone. 25 CFTimeZone, CFTimeZoneRef 26 } 27 impl_TCFType!(CFTimeZone, CFTimeZoneRef, CFTimeZoneGetTypeID); 28 impl_CFTypeDescription!(CFTimeZone); 29 30 impl Default for CFTimeZone { default() -> CFTimeZone31 fn default() -> CFTimeZone { 32 unsafe { 33 let tz_ref = CFTimeZoneCopyDefault(); 34 TCFType::wrap_under_create_rule(tz_ref) 35 } 36 } 37 } 38 39 impl CFTimeZone { 40 #[inline] new(interval: CFTimeInterval) -> CFTimeZone41 pub fn new(interval: CFTimeInterval) -> CFTimeZone { 42 unsafe { 43 let tz_ref = CFTimeZoneCreateWithTimeIntervalFromGMT(kCFAllocatorDefault, interval); 44 TCFType::wrap_under_create_rule(tz_ref) 45 } 46 } 47 48 #[inline] system() -> CFTimeZone49 pub fn system() -> CFTimeZone { 50 unsafe { 51 let tz_ref = CFTimeZoneCopySystem(); 52 TCFType::wrap_under_create_rule(tz_ref) 53 } 54 } 55 seconds_from_gmt(&self, date: CFDate) -> CFTimeInterval56 pub fn seconds_from_gmt(&self, date: CFDate) -> CFTimeInterval { 57 unsafe { 58 CFTimeZoneGetSecondsFromGMT(self.0, date.abs_time()) 59 } 60 } 61 62 #[cfg(feature = "with-chrono")] offset_at_date(&self, date: NaiveDateTime) -> FixedOffset63 pub fn offset_at_date(&self, date: NaiveDateTime) -> FixedOffset { 64 let date = CFDate::from_naive_utc(date); 65 FixedOffset::east(self.seconds_from_gmt(date) as i32) 66 } 67 68 #[cfg(feature = "with-chrono")] from_offset(offset: FixedOffset) -> CFTimeZone69 pub fn from_offset(offset: FixedOffset) -> CFTimeZone { 70 CFTimeZone::new(offset.local_minus_utc() as f64) 71 } 72 73 /// The timezone database ID that identifies the time zone. E.g. "America/Los_Angeles" or 74 /// "Europe/Paris". name(&self) -> CFString75 pub fn name(&self) -> CFString { 76 unsafe { 77 CFString::wrap_under_get_rule(CFTimeZoneGetName(self.0)) 78 } 79 } 80 } 81 82 #[cfg(test)] 83 mod test { 84 use super::CFTimeZone; 85 86 #[cfg(feature = "with-chrono")] 87 use chrono::{NaiveDateTime, FixedOffset}; 88 89 #[test] timezone_comparison()90 fn timezone_comparison() { 91 let system = CFTimeZone::system(); 92 let default = CFTimeZone::default(); 93 assert_eq!(system, default); 94 } 95 96 #[test] 97 #[cfg(feature = "with-chrono")] timezone_chrono_conversion()98 fn timezone_chrono_conversion() { 99 let offset = FixedOffset::west(28800); 100 let tz = CFTimeZone::from_offset(offset); 101 let converted = tz.offset_at_date(NaiveDateTime::from_timestamp(0, 0)); 102 assert_eq!(offset, converted); 103 } 104 } 105