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
use chrono::*;
const HOUR_TO_SEC: i32 = 3600;
const MIN_TO_SEC: i32 = 60;
pub mod known_timezones;
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug, Default, Ord, PartialOrd)]
pub struct UtcZst<const HOUR: i32, const MINUTE: u32>;
impl<const HOUR: i32, const MINUTE: u32> UtcZst<HOUR, MINUTE> {
pub const OFFSET_SECS: i32 =
HOUR * HOUR_TO_SEC + if HOUR < 0 { -1 } else { 1 } * (MINUTE as i32) * MIN_TO_SEC;
pub const IS_IN_VALID_RANGE: bool = (HOUR >= -23) & (HOUR <= 23) & (MINUTE < 60);
pub const fn new() -> Self {
UtcZst
}
}
impl<const HOUR: i32, const MINUTE: u32> Offset for UtcZst<HOUR, MINUTE> {
fn fix(&self) -> FixedOffset {
FixedOffset::east(Self::OFFSET_SECS)
}
}
impl<const HOUR: i32, const MINUTE: u32> TimeZone for UtcZst<HOUR, MINUTE> {
type Offset = Self;
fn from_offset(offset: &Self::Offset) -> Self {
*offset
}
fn offset_from_local_date(&self, _local: &NaiveDate) -> LocalResult<Self::Offset> {
LocalResult::Single(*self)
}
fn offset_from_local_datetime(&self, _local: &NaiveDateTime) -> LocalResult<Self::Offset> {
LocalResult::Single(*self)
}
fn offset_from_utc_date(&self, _utc: &NaiveDate) -> Self::Offset {
*self
}
fn offset_from_utc_datetime(&self, _utc: &NaiveDateTime) -> Self::Offset {
*self
}
}
impl<const HOUR: i32, const MINUTE: u32> core::fmt::Display for UtcZst<HOUR, MINUTE> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(f, "{:+03}:{:02}", HOUR, MINUTE)
}
}
#[cfg(test)]
mod tests {
use crate::known_timezones::*;
use crate::*;
#[test]
fn it_works() {
let p9 = UtcP9::default();
assert_eq!(&p9.to_string(), "+09:00");
assert_eq!(std::mem::size_of_val(&p9), 0);
assert_eq!(UtcP9::IS_IN_VALID_RANGE, true);
let n = p9.ymd(2000, 1, 1).and_hms(12, 00, 00);
assert_eq!(
n.naive_utc(),
NaiveDate::from_ymd(2000, 1, 1).and_hms(3, 0, 0)
);
let m9 = UtcM9::default();
assert_eq!(&m9.to_string(), "-09:00");
let n = m9.ymd(2000, 1, 1).and_hms(12, 00, 00);
assert_eq!(
n.naive_utc(),
NaiveDate::from_ymd(2000, 1, 1).and_hms(21, 0, 0)
);
let p9 = UtcP9_30::default();
let n = p9.ymd(2000, 1, 1).and_hms(12, 00, 00);
assert_eq!(
n.naive_utc(),
NaiveDate::from_ymd(2000, 1, 1).and_hms(2, 30, 0)
);
let m9 = UtcM9_30::default();
let n = m9.ymd(2000, 1, 1).and_hms(12, 00, 00);
assert_eq!(
n.naive_utc(),
NaiveDate::from_ymd(2000, 1, 1).and_hms(21, 30, 0)
);
}
}