chrono_intervals/intervals_impl/
boundaries.rs

1use chrono::{DateTime, Datelike, Duration, FixedOffset, TimeZone};
2
3pub fn get_initial_begin_end_times_day<T>(
4    begin: DateTime<T>,
5    local_timezone: &FixedOffset,
6    end_precision: Duration,
7    extend_begin: bool,
8) -> (DateTime<FixedOffset>, DateTime<FixedOffset>)
9where
10    T: TimeZone,
11{
12    let init_begin = match extend_begin {
13        true => begin.with_timezone(local_timezone).date().and_hms(0, 0, 0),
14        false => begin.with_timezone(local_timezone).date().and_hms(0, 0, 0) + Duration::hours(24),
15    };
16    let init_end = init_begin + Duration::hours(24) - end_precision;
17    (init_begin, init_end)
18}
19
20pub fn get_initial_begin_end_times_week<T>(
21    begin: DateTime<T>,
22    local_timezone: &FixedOffset,
23    end_precision: Duration,
24    extend_begin: bool,
25) -> (DateTime<FixedOffset>, DateTime<FixedOffset>)
26where
27    T: TimeZone,
28{
29    let localized_begin = begin.with_timezone(local_timezone);
30    let num_days_since_monday = localized_begin.weekday() as i64;
31    let init_begin = match extend_begin {
32        true => localized_begin.date().and_hms(0, 0, 0) - Duration::days(num_days_since_monday),
33        false => {
34            localized_begin.date().and_hms(0, 0, 0) + Duration::days(7 - num_days_since_monday)
35        }
36    };
37    let init_end = init_begin + Duration::days(7) - end_precision;
38    (init_begin, init_end)
39}
40
41pub fn get_initial_begin_end_times_month<T>(
42    begin: DateTime<T>,
43    local_timezone: &FixedOffset,
44    end_precision: Duration,
45    extend_begin: bool,
46) -> (DateTime<FixedOffset>, DateTime<FixedOffset>)
47where
48    T: TimeZone,
49{
50    let localized_begin = begin.with_timezone(local_timezone);
51    let init_begin = match extend_begin {
52        true => local_timezone
53            .ymd(localized_begin.year(), localized_begin.month(), 1)
54            .and_hms(0, 0, 0),
55        false => next_month_start(localized_begin),
56    };
57    let init_end = next_month_start(init_begin) - end_precision;
58    (init_begin, init_end)
59}
60
61pub fn get_next_begin_end_times_day(
62    cur_begin: DateTime<FixedOffset>,
63    end_precision: Duration,
64) -> (DateTime<FixedOffset>, DateTime<FixedOffset>) {
65    let cur_begin = cur_begin + Duration::hours(24);
66    let cur_end = cur_begin + Duration::hours(24) - end_precision;
67    (cur_begin, cur_end)
68}
69
70pub fn get_next_begin_end_times_week(
71    cur_begin: DateTime<FixedOffset>,
72    end_precision: Duration,
73) -> (DateTime<FixedOffset>, DateTime<FixedOffset>) {
74    let cur_begin = cur_begin + Duration::days(7);
75    let cur_end = cur_begin + Duration::days(7) - end_precision;
76    (cur_begin, cur_end)
77}
78
79pub fn get_next_begin_end_times_month(
80    cur_begin: DateTime<FixedOffset>,
81    end_precision: Duration,
82) -> (DateTime<FixedOffset>, DateTime<FixedOffset>) {
83    let cur_begin = next_month_start(cur_begin);
84    let cur_end = next_month_start(cur_begin) - end_precision;
85    (cur_begin, cur_end)
86}
87
88fn next_month_start<T>(datetime: DateTime<T>) -> DateTime<T>
89where
90    T: TimeZone,
91{
92    let date = datetime.date();
93    datetime
94        .timezone()
95        .ymd(
96            match date.month() {
97                12 => date.year() + 1,
98                _ => date.year(),
99            },
100            match date.month() {
101                12 => 1,
102                _ => date.month() + 1,
103            },
104            1,
105        )
106        .and_hms(0, 0, 0)
107}