baseunits_rs/time/
calendar_year_month.rs

1use crate::time::{MonthOfYear, Month, DayOfMonth, TimePoint};
2use chrono::{DateTime, Datelike, Date, TimeZone, Utc, ParseError};
3use num::{FromPrimitive, ToPrimitive};
4
5#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Hash)]
6pub struct CalendarYearMonth {
7  year: i32,
8  month: MonthOfYear,
9}
10
11impl<T: TimeZone> From<DateTime<T>> for CalendarYearMonth {
12  fn from(date_time: DateTime<T>) -> Self {
13    let year = date_time.year();
14    let month = date_time.month();
15    let month_of_year = MonthOfYear::from_month(Month::from_u32(month).unwrap());
16    CalendarYearMonth::new(year, month_of_year)
17  }
18}
19
20impl<T: TimeZone> From<Date<T>> for CalendarYearMonth {
21  fn from(date: Date<T>) -> Self {
22    let year = date.year();
23    let month = date.month();
24    let month_of_year = MonthOfYear::from_month(Month::from_u32(month).unwrap());
25    CalendarYearMonth::new(year, month_of_year)
26  }
27}
28
29impl From<TimePoint> for CalendarYearMonth {
30  fn from(value: TimePoint) -> Self {
31    Self::from(value.to_date_time(Utc))
32  }
33}
34
35impl From<(i32, MonthOfYear)> for CalendarYearMonth {
36  fn from((year, month): (i32, MonthOfYear)) -> Self {
37    Self::new(year, month)
38  }
39}
40
41impl From<(i32, u32)> for CalendarYearMonth {
42  fn from((year, month): (i32, u32)) -> Self {
43    Self::new(
44      year,
45      MonthOfYear::from_month(Month::from_u32(month).unwrap()),
46    )
47  }
48}
49
50impl CalendarYearMonth {
51  pub fn new(year: i32, month: MonthOfYear) -> Self {
52    Self { year, month }
53  }
54
55  pub fn to_year(&self) -> i32 {
56    self.year
57  }
58
59  pub fn as_month_of_year(&self) -> &MonthOfYear {
60    &self.month
61  }
62
63  pub fn as_month(&self) -> &Month {
64    self.month.as_value()
65  }
66
67  pub fn to_month_u32(&self) -> u32 {
68    self.month.as_value().to_u32().unwrap()
69  }
70
71  pub fn as_last_day_of_month(&self) -> &DayOfMonth {
72    self.month.as_last_day()
73  }
74
75  pub fn add_month(&mut self) -> &Self {
76    let (new_month, overflow) = self.month.add_with_overflow();
77    self.month = new_month;
78    if overflow {
79      self.year += 1;
80    }
81    self
82  }
83
84  pub fn parse_tz<T>(date_str: &str, pattern: &str, time_zone: T) -> Result<Self, ParseError>
85  where
86    T: TimeZone,
87  {
88    let tp = TimePoint::parse_tz(date_str, pattern, time_zone)?;
89    Ok(CalendarYearMonth::from(tp))
90  }
91
92  pub fn is_after(&self, other: &Self) -> bool {
93    !self.is_before(other) && self != other
94  }
95
96  pub fn is_before(&self, other: &Self) -> bool {
97    match (self.year, other.year) {
98      (sy, oy) if sy < oy => true,
99      (sy, oy) if sy > oy => false,
100      _ => self.month.is_before(&other.month),
101    }
102  }
103}