hutools/date/begin/
begin_of_quarter.rs

1use chrono::{Date, DateTime, Datelike, TimeZone};
2#[cfg(test)]
3mod test {
4    use super::*;
5    use chrono::Utc;
6
7    #[test]
8    fn begin_of_quarter_test() {
9        let date = Utc.ymd(2008, 8, 8);
10        let actual = Utc.ymd(2008, 6, 1);
11        let result = begin_of_quarter(date);
12        assert_eq!(Some(actual), result);
13    }
14    #[test]
15    fn begin_of_first_quarter_test() {
16        let date = Utc.ymd(2008, 2, 2);
17        let actual = Utc.ymd(2007, 12, 1);
18        let result = begin_of_quarter(date);
19        assert_eq!(Some(actual), result);
20    }
21}
22
23/// Get the start date of the quarter.
24/// 获取某个季度的开始日期
25/// # Arguments
26///
27/// * `date`: 日期
28///
29/// returns: Option<Date<Tz>>
30///
31/// # Examples
32///
33/// ```
34/// use chrono::{TimeZone, Utc};
35/// use hutools::date::begin_of_quarter;
36/// let date = Utc.ymd(2008,8,8);
37/// let actual = Utc.ymd(2008,6,1);
38/// let result = begin_of_quarter(date);
39/// assert_eq!(Some(actual), result);
40/// ```
41pub fn begin_of_quarter<Tz: TimeZone>(date: Date<Tz>) -> Option<Date<Tz>> {
42    let month = date.month();
43    let year = date.year();
44    if month == 12 || month == 1 || month == 2 {
45        return date.with_year(year - 1)?.with_month(12)?.with_day(1);
46    }
47    if month == 3 || month == 4 || month == 5 {
48        return date.with_month(3)?.with_day(1);
49    }
50    if month == 6 || month == 7 || month == 8 {
51        return date.with_month(6)?.with_day(1);
52    }
53    if month == 9 || month == 10 || month == 11 {
54        return date.with_month(9)?.with_day(1);
55    }
56    None
57}
58
59/// Get the start date of a quarter.
60/// 获取某个季度的开始日期
61/// # Arguments
62///
63/// * `datetime`: 日期时间
64///
65/// returns: Option<Date<Tz>>
66///
67/// # Examples
68///
69/// ```
70/// use chrono::{TimeZone, Utc};
71/// use hutools::date::begin_of_quarter_with_time;
72/// let datetime = Utc.ymd(2008,8,8).and_hms(8,8,8);
73/// let actual = Utc.ymd(2008,6,1);
74/// let result = begin_of_quarter_with_time(datetime);
75/// assert_eq!(Some(actual), result);
76/// ```
77pub fn begin_of_quarter_with_time<Tz: TimeZone>(datetime: DateTime<Tz>) -> Option<Date<Tz>> {
78    let month = datetime.month();
79    if month == 12 || month == 1 || month == 2 {
80        let year = datetime.year();
81        return datetime
82            .date()
83            .with_year(year - 1)?
84            .with_month(12)?
85            .with_day(1);
86    }
87    if month == 3 || month == 4 || month == 5 {
88        return datetime.date().with_month(3)?.with_day(1);
89    }
90    if month == 6 || month == 7 || month == 8 {
91        return datetime.date().with_month(6)?.with_day(1);
92    }
93    if month == 9 || month == 10 || month == 11 {
94        return datetime.date().with_month(9)?.with_day(1);
95    }
96    None
97}