Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_datime/src/clock/periods.rs

6.3 KiB, 33 runs

created by r1870400018:6331, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1//! [Written with AI entirely](https://need2know.ai/entirely-ai/code)\
2//! Anthropic Claude
3
4use crate::{
5 calendar::{Calendar, CalendarDate},
6 clock::{
7 ClockHour,
8 ClockMinute,
9 ClockSecond,
10 ClockTime,
11 ClockInterval,
12 },
13 time::CalClockZone,
14};
15
16use oxedyne_fe2o3_core::prelude::*;
17
18#[derive(Clone, Debug, PartialEq)]
19pub struct HourPeriod {
20 date: CalendarDate,
21 hour: ClockHour,
22}
23
24impl HourPeriod {
25 pub fn new(date: CalendarDate, hour: ClockHour) -> Self {
26 Self { date, hour }
27 }
28
29 pub fn from_components(
30 year: i32,
31 month: u8,
32 day: u8,
33 hour: u8,
34 zone: CalClockZone,
35 ) -> Outcome<Self> {
36 let calendar = Calendar::new(); // Default to Gregorian
37 let date = res!(calendar.date(year, month, day, zone));
38 let hour = res!(ClockHour::new(hour));
39 Ok(Self::new(date, hour))
40 }
41
42 pub fn date(&self) -> &CalendarDate {
43 &self.date
44 }
45
46 pub fn hour(&self) -> ClockHour {
47 self.hour
48 }
49
50 pub fn start_time(&self) -> Outcome<ClockTime> {
51 ClockTime::new(self.hour.of(), 0, 0, 0, self.date.zone().clone())
52 }
53
54 pub fn end_time(&self) -> Outcome<ClockTime> {
55 let next_hour = self.hour.add_hours(1);
56 ClockTime::new(next_hour.of(), 0, 0, 0, self.date.zone().clone())
57 }
58
59 pub fn to_interval(&self) -> Outcome<ClockInterval> {
60 let start = res!(self.start_time());
61 let end = res!(self.end_time());
62 ClockInterval::new(start, end)
63 }
64}
65
66#[derive(Clone, Debug, PartialEq)]
67pub struct MinutePeriod {
68 date: CalendarDate,
69 hour: ClockHour,
70 minute: ClockMinute,
71}
72
73impl MinutePeriod {
74 pub fn new(date: CalendarDate, hour: ClockHour, minute: ClockMinute) -> Self {
75 Self { date, hour, minute }
76 }
77
78 pub fn from_components(
79 year: i32,
80 month: u8,
81 day: u8,
82 hour: u8,
83 minute: u8,
84 zone: CalClockZone,
85 ) -> Outcome<Self> {
86 let calendar = Calendar::new(); // Default to Gregorian
87 let date = res!(calendar.date(year, month, day, zone));
88 let hour = res!(ClockHour::new(hour));
89 let minute = res!(ClockMinute::new(minute));
90 Ok(Self::new(date, hour, minute))
91 }
92
93 pub fn date(&self) -> &CalendarDate {
94 &self.date
95 }
96
97 pub fn hour(&self) -> ClockHour {
98 self.hour
99 }
100
101 pub fn minute(&self) -> ClockMinute {
102 self.minute
103 }
104
105 pub fn start_time(&self) -> Outcome<ClockTime> {
106 ClockTime::new(self.hour.of(), self.minute.of(), 0, 0, self.date.zone().clone())
107 }
108
109 pub fn end_time(&self) -> Outcome<ClockTime> {
110 let (next_minute, hour_carry) = self.minute.add_minutes(1);
111 let next_hour = if hour_carry > 0 {
112 self.hour.add_hours(hour_carry)
113 } else {
114 self.hour
115 };
116 ClockTime::new(next_hour.of(), next_minute.of(), 0, 0, self.date.zone().clone())
117 }
118
119 pub fn to_interval(&self) -> Outcome<ClockInterval> {
120 let start = res!(self.start_time());
121 let end = res!(self.end_time());
122 ClockInterval::new(start, end)
123 }
124}
125
126#[derive(Clone, Debug, PartialEq)]
127pub struct SecondPeriod {
128 date: CalendarDate,
129 hour: ClockHour,
130 minute: ClockMinute,
131 second: ClockSecond,
132}
133
134impl SecondPeriod {
135 pub fn new(
136 date: CalendarDate,
137 hour: ClockHour,
138 minute: ClockMinute,
139 second: ClockSecond
140 ) -> Self {
141 Self { date, hour, minute, second }
142 }
143
144 pub fn from_components(
145 year: i32,
146 month: u8,
147 day: u8,
148 hour: u8,
149 minute: u8,
150 second: u8,
151 zone: CalClockZone,
152 ) -> Outcome<Self> {
153 let calendar = Calendar::new(); // Default to Gregorian
154 let date = res!(calendar.date(year, month, day, zone));
155 let hour = res!(ClockHour::new(hour));
156 let minute = res!(ClockMinute::new(minute));
157 let second = res!(ClockSecond::new(second));
158 Ok(Self::new(date, hour, minute, second))
159 }
160
161 pub fn date(&self) -> &CalendarDate {
162 &self.date
163 }
164
165 pub fn hour(&self) -> ClockHour {
166 self.hour
167 }
168
169 pub fn minute(&self) -> ClockMinute {
170 self.minute
171 }
172
173 pub fn second(&self) -> ClockSecond {
174 self.second
175 }
176
177 pub fn start_time(&self) -> Outcome<ClockTime> {
178 ClockTime::new(
179 self.hour.of(),
180 self.minute.of(),
181 self.second.of(),
182 0,
183 self.date.zone().clone()
184 )
185 }
186
187 pub fn end_time(&self) -> Outcome<ClockTime> {
188 let (next_second, minute_carry) = self.second.add_seconds(1);
189 let (next_minute, hour_carry) = if minute_carry > 0 {
190 self.minute.add_minutes(minute_carry)
191 } else {
192 (self.minute, 0)
193 };
194 let next_hour = if hour_carry > 0 {
195 self.hour.add_hours(hour_carry)
196 } else {
197 self.hour
198 };
199
200 ClockTime::new(
201 next_hour.of(),
202 next_minute.of(),
203 next_second.of(),
204 0,
205 self.date.zone().clone()
206 )
207 }
208
209 pub fn to_interval(&self) -> Outcome<ClockInterval> {
210 let start = res!(self.start_time());
211 let end = res!(self.end_time());
212 ClockInterval::new(start, end)
213 }
214}
215
216#[cfg(test)]
217mod tests {
218 use super::*;
219
220 fn test_zone() -> CalClockZone {
221 CalClockZone::utc()
222 }
223
224 #[test]
225 fn test_hour_period() {
226 let date = CalendarDate::new(2024, 6, 15, test_zone()).unwrap();
227 let hour = ClockHour::new(14).unwrap();
228
229 let period = HourPeriod::new(date, hour);
230 assert_eq!(period.hour().of(), 14);
231
232 let start = period.start_time().unwrap();
233 assert_eq!(start.hour().of(), 14);
234 assert_eq!(start.minute().of(), 0);
235
236 let end = period.end_time().unwrap();
237 assert_eq!(end.hour().of(), 15);
238 assert_eq!(end.minute().of(), 0);
239 }
240
241 #[test]
242 fn test_minute_period() {
243 let period = MinutePeriod::from_components(
244 2024, 6, 15, 14, 30, test_zone()
245 ).unwrap();
246
247 assert_eq!(period.hour().of(), 14);
248 assert_eq!(period.minute().of(), 30);
249
250 let start = period.start_time().unwrap();
251 assert_eq!(start.minute().of(), 30);
252 assert_eq!(start.second().of(), 0);
253
254 let end = period.end_time().unwrap();
255 assert_eq!(end.minute().of(), 31);
256 assert_eq!(end.second().of(), 0);
257 }
258
259 #[test]
260 fn test_second_period() {
261 let period = SecondPeriod::from_components(
262 2024, 6, 15, 14, 30, 45, test_zone()
263 ).unwrap();
264
265 assert_eq!(period.hour().of(), 14);
266 assert_eq!(period.minute().of(), 30);
267 assert_eq!(period.second().of(), 45);
268
269 let start = period.start_time().unwrap();
270 assert_eq!(start.second().of(), 45);
271 assert_eq!(start.nanosecond().of(), 0);
272
273 let end = period.end_time().unwrap();
274 assert_eq!(end.second().of(), 46);
275 assert_eq!(end.nanosecond().of(), 0);
276 }
277
278 #[test]
279 fn test_period_intervals() {
280 let hour_period = HourPeriod::from_components(
281 2024, 6, 15, 14, test_zone()
282 ).unwrap();
283
284 let interval = hour_period.to_interval().unwrap();
285 let duration = interval.duration();
286 assert_eq!(duration.total_hours(), 1);
287 }
288}