1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use time::{OffsetDateTime, PrimitiveDateTime, UtcOffset};
pub trait Offset
{
fn to_utc(&self) -> UtcOffset;
fn name(&self) -> &str;
}
pub trait TimeZone
{
type Offset: Offset;
fn get_offset_utc(&self, date_time: &OffsetDateTime) -> Self::Offset;
fn name(&self) -> &str;
}
pub trait OffsetDateTimeExt
{
fn to_timezone<T: TimeZone>(&self, tz: &T) -> OffsetDateTime;
}
pub trait PrimitiveDateTimeExt
{
fn assume_timezone<T: TimeZone>(&self, tz: &T) -> OffsetDateTime;
}
impl PrimitiveDateTimeExt for PrimitiveDateTime {
fn assume_timezone<T: TimeZone>(&self, tz: &T) -> OffsetDateTime {
let offset = tz.get_offset_utc(&self.assume_utc());
self.assume_offset(offset.to_utc())
}
}
impl OffsetDateTimeExt for OffsetDateTime {
fn to_timezone<T: TimeZone>(&self, tz: &T) -> OffsetDateTime {
let offset = tz.get_offset_utc(self);
self.to_offset(offset.to_utc())
}
}
mod timezone_impl;
pub mod timezones;
mod binary_search;
#[cfg(feature = "system")]
pub mod system;
pub use timezone_impl::Tz;
#[cfg(test)]
mod tests {
use time::macros::datetime;
use time::OffsetDateTime;
use crate::PrimitiveDateTimeExt;
use crate::OffsetDateTimeExt;
use crate::timezones;
use crate::TimeZone;
use crate::Offset;
#[test]
fn names() {
let shanghai = timezones::get_by_name("Asia/Shanghai");
let china = timezones::get_by_name("China Standard Time");
assert!(shanghai.is_some());
assert!(china.is_some());
assert_eq!(shanghai, china);
}
#[test]
fn find() {
let zones_iana = timezones::find_by_name("Asia");
assert!(zones_iana.len() > 1);
}
#[test]
fn offsets_and_name() {
let tz = timezones::db::europe::LONDON;
assert_eq!(tz.name(), "Europe/London");
let offset = tz.get_offset_utc(&OffsetDateTime::now_utc());
assert!(!offset.name().is_empty());
}
#[test]
fn london_to_berlin() {
let dt = datetime!(2016-10-8 17:0:0).assume_timezone(timezones::db::europe::LONDON);
let converted = dt.to_timezone(timezones::db::europe::BERLIN);
let expected = datetime!(2016-10-8 18:0:0).assume_timezone(timezones::db::europe::BERLIN);
assert_eq!(converted, expected);
}
}