embassy_stm32/rtc/
datetime.rs1#[cfg(feature = "chrono")]
2use chrono::{Datelike, NaiveDate, Timelike, Weekday};
3
4#[derive(Clone, Debug, PartialEq, Eq)]
6pub enum Error {
7 InvalidYear,
9 InvalidMonth,
11 InvalidDay,
13 InvalidDayOfWeek(
15 u8,
17 ),
18 InvalidHour,
20 InvalidMinute,
22 InvalidSecond,
24}
25
26pub struct DateTime {
28 year: u16,
30 month: u8,
32 day: u8,
34 day_of_week: DayOfWeek,
36 hour: u8,
38 minute: u8,
40 second: u8,
42}
43
44impl DateTime {
45 pub const fn year(&self) -> u16 {
47 self.year
48 }
49
50 pub const fn month(&self) -> u8 {
52 self.month
53 }
54
55 pub const fn day(&self) -> u8 {
57 self.day
58 }
59
60 pub const fn day_of_week(&self) -> DayOfWeek {
62 self.day_of_week
63 }
64
65 pub const fn hour(&self) -> u8 {
67 self.hour
68 }
69
70 pub const fn minute(&self) -> u8 {
72 self.minute
73 }
74
75 pub const fn second(&self) -> u8 {
77 self.second
78 }
79
80 pub fn from(
82 year: u16,
83 month: u8,
84 day: u8,
85 day_of_week: DayOfWeek,
86 hour: u8,
87 minute: u8,
88 second: u8,
89 ) -> Result<Self, Error> {
90 if year > 4095 {
91 Err(Error::InvalidYear)
92 } else if !(1..=12).contains(&month) {
93 Err(Error::InvalidMonth)
94 } else if !(1..=31).contains(&day) {
95 Err(Error::InvalidDay)
96 } else if hour > 23 {
97 Err(Error::InvalidHour)
98 } else if minute > 59 {
99 Err(Error::InvalidMinute)
100 } else if second > 59 {
101 Err(Error::InvalidSecond)
102 } else {
103 Ok(Self {
104 year,
105 month,
106 day,
107 day_of_week,
108 hour,
109 minute,
110 second,
111 })
112 }
113 }
114}
115
116#[cfg(feature = "chrono")]
117impl From<chrono::NaiveDateTime> for DateTime {
118 fn from(date_time: chrono::NaiveDateTime) -> Self {
119 Self {
120 year: date_time.year() as u16,
121 month: date_time.month() as u8,
122 day: date_time.day() as u8,
123 day_of_week: date_time.weekday().into(),
124 hour: date_time.hour() as u8,
125 minute: date_time.minute() as u8,
126 second: date_time.second() as u8,
127 }
128 }
129}
130
131#[cfg(feature = "chrono")]
132impl From<DateTime> for chrono::NaiveDateTime {
133 fn from(date_time: DateTime) -> Self {
134 NaiveDate::from_ymd_opt(date_time.year as i32, date_time.month as u32, date_time.day as u32)
135 .unwrap()
136 .and_hms_opt(date_time.hour as u32, date_time.minute as u32, date_time.second as u32)
137 .unwrap()
138 }
139}
140
141#[repr(u8)]
143#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
144#[allow(missing_docs)]
145pub enum DayOfWeek {
146 Monday = 1,
147 Tuesday = 2,
148 Wednesday = 3,
149 Thursday = 4,
150 Friday = 5,
151 Saturday = 6,
152 Sunday = 7,
153}
154
155#[cfg(feature = "chrono")]
156impl From<chrono::Weekday> for DayOfWeek {
157 fn from(weekday: Weekday) -> Self {
158 day_of_week_from_u8(weekday.number_from_monday() as u8).unwrap()
159 }
160}
161
162#[cfg(feature = "chrono")]
163impl From<DayOfWeek> for chrono::Weekday {
164 fn from(weekday: DayOfWeek) -> Self {
165 match weekday {
166 DayOfWeek::Monday => Weekday::Mon,
167 DayOfWeek::Tuesday => Weekday::Tue,
168 DayOfWeek::Wednesday => Weekday::Wed,
169 DayOfWeek::Thursday => Weekday::Thu,
170 DayOfWeek::Friday => Weekday::Fri,
171 DayOfWeek::Saturday => Weekday::Sat,
172 DayOfWeek::Sunday => Weekday::Sun,
173 }
174 }
175}
176
177pub(super) const fn day_of_week_from_u8(v: u8) -> Result<DayOfWeek, Error> {
178 Ok(match v {
179 1 => DayOfWeek::Monday,
180 2 => DayOfWeek::Tuesday,
181 3 => DayOfWeek::Wednesday,
182 4 => DayOfWeek::Thursday,
183 5 => DayOfWeek::Friday,
184 6 => DayOfWeek::Saturday,
185 7 => DayOfWeek::Sunday,
186 x => return Err(Error::InvalidDayOfWeek(x)),
187 })
188}
189
190pub(super) const fn day_of_week_to_u8(dotw: DayOfWeek) -> u8 {
191 dotw as u8
192}