chrono_intervals/intervals_impl/
boundaries.rs1use 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}