Skip to content

Commit 6df0c0f

Browse files
committed
wip
1 parent da95611 commit 6df0c0f

File tree

1 file changed

+98
-19
lines changed

1 file changed

+98
-19
lines changed

utils/resb/examples/time_zone_rule.rs

Lines changed: 98 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,86 @@ struct TzRule {
4747

4848
#[derive(Debug)]
4949
struct TzRuleDate {
50-
month: i8,
5150
day: i8,
5251
day_of_week: i8,
53-
seconds_of_day: i32,
54-
time_mode: i8,
52+
month: u8,
53+
millis_of_day: u32,
54+
time_mode: TimeMode,
55+
mode: &'static str,
56+
}
57+
58+
#[derive(Debug)]
59+
pub enum TimeMode {
60+
Wall = 0,
61+
Standard = 1,
62+
Utc = 2,
63+
}
64+
65+
impl TzRuleDate {
66+
fn new(
67+
mut day: i8,
68+
mut day_of_week: i8,
69+
month: u8,
70+
millis_of_day: u32,
71+
time_mode: i8,
72+
) -> Option<Self> {
73+
const GREGORIAN_MONTHS: [i8; 12] = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
74+
75+
if day == 0 {
76+
return None;
77+
}
78+
if month > 11 {
79+
return None;
80+
}
81+
if millis_of_day > 24 * 60 * 60 * 1000 {
82+
return None;
83+
}
84+
85+
let time_mode = match time_mode {
86+
0 => TimeMode::Wall,
87+
1 => TimeMode::Standard,
88+
2 => TimeMode::Utc,
89+
_ => return None,
90+
};
91+
92+
let mode;
93+
94+
if day_of_week == 0 {
95+
mode = "dom";
96+
} else {
97+
if day_of_week > 0 {
98+
mode = "dow_in_month"
99+
} else {
100+
day_of_week = -day_of_week;
101+
if day > 0 {
102+
mode = "dow_ge_dom";
103+
} else {
104+
day = -day;
105+
mode = "dow_le_dom";
106+
}
107+
}
108+
if day_of_week > 7 {
109+
return None;
110+
}
111+
}
112+
113+
if mode == "dow_in_month" {
114+
if !(-5..=5).contains(&day) {
115+
return None;
116+
}
117+
} else if day < 1 || day > GREGORIAN_MONTHS[month as usize] {
118+
return None;
119+
}
120+
121+
Some(Self {
122+
day,
123+
day_of_week,
124+
month,
125+
millis_of_day,
126+
time_mode,
127+
mode,
128+
})
129+
}
55130
}
56131

57132
impl<'de> Deserialize<'de> for ZoneInfo64<'de> {
@@ -191,20 +266,22 @@ impl<'de> Deserialize<'de> for ZoneInfo64<'de> {
191266
key,
192267
TzRule {
193268
additional_offset_secs: value[10],
194-
start: TzRuleDate {
195-
month: value[0] as i8,
196-
day: value[1] as i8,
197-
day_of_week: value[2] as i8,
198-
seconds_of_day: value[3],
199-
time_mode: value[4] as i8,
200-
},
201-
end: TzRuleDate {
202-
month: value[5] as i8,
203-
day: value[6] as i8,
204-
day_of_week: value[7] as i8,
205-
seconds_of_day: value[8],
206-
time_mode: value[9] as i8,
207-
},
269+
start: TzRuleDate::new(
270+
value[1] as i8,
271+
value[2] as i8,
272+
value[0] as u8,
273+
value[3] as u32,
274+
value[4] as i8,
275+
)
276+
.unwrap(),
277+
end: TzRuleDate::new(
278+
value[6] as i8,
279+
value[7] as i8,
280+
value[5] as u8,
281+
value[8] as u32,
282+
value[9] as i8,
283+
)
284+
.unwrap(),
208285
},
209286
));
210287
}
@@ -445,14 +522,16 @@ impl Rule<'_> {
445522
let _ = self.inner.start.month;
446523
let _ = self.inner.start.day;
447524
let _ = self.inner.start.day_of_week;
448-
let _ = self.inner.start.seconds_of_day;
525+
let _ = self.inner.start.millis_of_day;
449526
let _ = self.inner.start.time_mode;
527+
let _ = self.inner.start.mode;
450528

451529
let _ = self.inner.end.month;
452530
let _ = self.inner.end.day;
453531
let _ = self.inner.end.day_of_week;
454-
let _ = self.inner.end.seconds_of_day;
532+
let _ = self.inner.end.millis_of_day;
455533
let _ = self.inner.end.time_mode;
534+
let _ = self.inner.end.mode;
456535

457536
Transition {
458537
transition,

0 commit comments

Comments
 (0)