1use chrono::{DateTime, Datelike, Duration, TimeZone, Utc};
4
5pub fn get_last_xp_reset_timestamp_ms() -> i64 {
11 let now = chrono::Utc::now();
12 let weekday = now.weekday().num_days_from_monday();
14
15 let days_since_monday = weekday as i64;
17 let days_to_wednesday = 2 - days_since_monday;
18
19 let mut reset_day = now
20 .date_naive()
21 .and_hms_opt(1, 0, 0)
22 .unwrap_or_default() .and_utc()
24 + chrono::Duration::days(days_to_wednesday);
25
26 if now < reset_day {
28 reset_day -= chrono::Duration::weeks(1);
29 }
30 reset_day.timestamp_millis()
31}
32
33pub fn next_market_reset_time(now: DateTime<Utc>) -> DateTime<Utc> {
47 let weekday_from_monday = now.weekday().num_days_from_monday() as i64;
49
50 let days_back = (weekday_from_monday + 5) % 7;
53
54 let reset_today_naive = now
55 .date_naive()
56 .and_hms_opt(1, 0, 0)
57 .expect("01:00:00 is always valid");
58 let reset_today = Utc.from_utc_datetime(&reset_today_naive);
59
60 let last_reset = reset_today - Duration::days(days_back);
61
62 if now < last_reset {
65 return last_reset;
66 }
67
68 let mut next_reset = last_reset + Duration::weeks(1);
69 if next_reset <= now {
70 next_reset += Duration::weeks(1);
71 }
72 next_reset
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78 use chrono::TimeZone;
79
80 fn utc(year: i32, month: u32, day: u32, hour: u32, min: u32) -> DateTime<Utc> {
81 Utc.with_ymd_and_hms(year, month, day, hour, min, 0)
82 .single()
83 .expect("valid datetime")
84 }
85
86 fn next_wed_01(year: i32, month: u32, day: u32) -> DateTime<Utc> {
88 utc(year, month, day, 1, 0)
89 }
90
91 #[test]
92 fn tuesday_before_reset_next_wed_is_tomorrow() {
93 let now = utc(2024, 6, 4, 23, 0);
95 assert_eq!(next_market_reset_time(now), next_wed_01(2024, 6, 5, ));
96 }
97
98 #[test]
99 fn wednesday_before_reset_same_day() {
100 let now = utc(2024, 6, 5, 0, 30);
102 assert_eq!(next_market_reset_time(now), next_wed_01(2024, 6, 5));
103 }
104
105 #[test]
106 fn wednesday_after_reset_next_week() {
107 let now = utc(2024, 6, 5, 1, 30);
109 assert_eq!(next_market_reset_time(now), next_wed_01(2024, 6, 12));
110 }
111
112 #[test]
113 fn thursday_after_reset_next_week() {
114 let now = utc(2024, 6, 6, 2, 0);
116 assert_eq!(next_market_reset_time(now), next_wed_01(2024, 6, 12));
117 }
118
119 #[test]
120 fn sunday_midday_next_wed() {
121 let now = utc(2024, 6, 9, 12, 0);
123 assert_eq!(next_market_reset_time(now), next_wed_01(2024, 6, 12));
124 }
125}