use chrono::{DateTime, Datelike, Duration, TimeZone, Utc};
pub fn get_last_xp_reset_timestamp_ms() -> i64 {
let now = chrono::Utc::now();
let weekday = now.weekday().num_days_from_monday();
let days_since_monday = weekday as i64;
let days_to_wednesday = 2 - days_since_monday;
let mut reset_day = now
.date_naive()
.and_hms_opt(1, 0, 0)
.unwrap_or_default() .and_utc()
+ chrono::Duration::days(days_to_wednesday);
if now < reset_day {
reset_day -= chrono::Duration::weeks(1);
}
reset_day.timestamp_millis()
}
pub fn next_market_reset_time(now: DateTime<Utc>) -> DateTime<Utc> {
let weekday_from_monday = now.weekday().num_days_from_monday() as i64;
let days_back = (weekday_from_monday + 5) % 7;
let reset_today_naive = now
.date_naive()
.and_hms_opt(1, 0, 0)
.expect("01:00:00 is always valid");
let reset_today = Utc.from_utc_datetime(&reset_today_naive);
let last_reset = reset_today - Duration::days(days_back);
if now < last_reset {
return last_reset;
}
let mut next_reset = last_reset + Duration::weeks(1);
if next_reset <= now {
next_reset += Duration::weeks(1);
}
next_reset
}
#[cfg(test)]
mod tests {
use super::*;
use chrono::TimeZone;
fn utc(year: i32, month: u32, day: u32, hour: u32, min: u32) -> DateTime<Utc> {
Utc.with_ymd_and_hms(year, month, day, hour, min, 0)
.single()
.expect("valid datetime")
}
fn next_wed_01(year: i32, month: u32, day: u32) -> DateTime<Utc> {
utc(year, month, day, 1, 0)
}
#[test]
fn tuesday_before_reset_next_wed_is_tomorrow() {
let now = utc(2024, 6, 4, 23, 0);
assert_eq!(next_market_reset_time(now), next_wed_01(2024, 6, 5, ));
}
#[test]
fn wednesday_before_reset_same_day() {
let now = utc(2024, 6, 5, 0, 30);
assert_eq!(next_market_reset_time(now), next_wed_01(2024, 6, 5));
}
#[test]
fn wednesday_after_reset_next_week() {
let now = utc(2024, 6, 5, 1, 30);
assert_eq!(next_market_reset_time(now), next_wed_01(2024, 6, 12));
}
#[test]
fn thursday_after_reset_next_week() {
let now = utc(2024, 6, 6, 2, 0);
assert_eq!(next_market_reset_time(now), next_wed_01(2024, 6, 12));
}
#[test]
fn sunday_midday_next_wed() {
let now = utc(2024, 6, 9, 12, 0);
assert_eq!(next_market_reset_time(now), next_wed_01(2024, 6, 12));
}
}