baseunits_rs/time/
calendar_year_month.rs1use 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}