1use std::time::Duration;
5use std::time::SystemTime;
6use std::time::UNIX_EPOCH;
7
8use math_util::round_up;
9
10
11const DAY_SECS: u32 = 24 * 60 * 60;
13
14
15fn next_day_duration(now: SystemTime) -> Duration {
16 let duration = now.duration_since(UNIX_EPOCH).unwrap();
20 let next_day = round_up(duration.as_secs(), DAY_SECS.into());
21 let duration = Duration::from_secs(next_day);
22 duration
23}
24
25pub fn next_day(now: SystemTime) -> SystemTime {
32 let duration = next_day_duration(now);
33 UNIX_EPOCH + duration
34}
35
36pub fn days_back_from(now: SystemTime, count: u32) -> SystemTime {
37 let duration = next_day_duration(now) - Duration::from_secs(DAY_SECS.into()) * (count + 1);
38 UNIX_EPOCH + duration
39}
40
41pub fn days_back(count: u32) -> SystemTime {
42 days_back_from(SystemTime::now(), count)
43}
44
45pub fn tomorrow() -> SystemTime {
48 next_day(SystemTime::now())
49}
50
51
52#[cfg(test)]
53pub mod tests {
54 use super::*;
55
56 use crate::parse::parse_system_time_from_str;
57
58
59 #[test]
60 fn calculate_next_day() {
61 let now = parse_system_time_from_str("2020-02-07T13:00:00Z").unwrap();
62 let tomorrow = parse_system_time_from_str("2020-02-08T00:00:00Z").unwrap();
63 assert_eq!(next_day(now), tomorrow);
64
65 let now = parse_system_time_from_str("2019-03-31T23:59:59Z").unwrap();
66 let tomorrow = parse_system_time_from_str("2019-04-01T00:00:00Z").unwrap();
67 assert_eq!(next_day(now), tomorrow);
68 }
69
70 #[test]
71 fn calculate_prev_days() {
72 let now = parse_system_time_from_str("2020-02-07T09:00:00Z").unwrap();
73 let yesterday = parse_system_time_from_str("2020-02-06T00:00:00Z").unwrap();
74 assert_eq!(days_back_from(now, 1), yesterday);
75
76 let now = parse_system_time_from_str("2020-02-02T23:59:59Z").unwrap();
77 let five_ago = parse_system_time_from_str("2020-01-28T00:00:00Z").unwrap();
78 assert_eq!(days_back_from(now, 5), five_ago);
79 }
80}