/rust/registry/src/index.crates.io-6f17d22bba15001f/icu_calendar-1.5.2/src/datetime.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // This file is part of ICU4X. For terms of use, please see the file |
2 | | // called LICENSE at the top level of the ICU4X source tree |
3 | | // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). |
4 | | |
5 | | use crate::any_calendar::{AnyCalendar, IntoAnyCalendar}; |
6 | | use crate::types::{self, Time}; |
7 | | use crate::{AsCalendar, Calendar, CalendarError, Date, Iso}; |
8 | | use alloc::rc::Rc; |
9 | | use alloc::sync::Arc; |
10 | | |
11 | | /// A date+time for a given calendar. |
12 | | /// |
13 | | /// This can work with wrappers around [`Calendar`](crate::Calendar) types, |
14 | | /// e.g. `Rc<C>`, via the [`AsCalendar`] trait, much like |
15 | | /// [`Date`]. |
16 | | /// |
17 | | /// This can be constructed manually from a [`Date`] and [`Time`], or can be constructed |
18 | | /// from its fields via [`Self::try_new_from_codes()`], or can be constructed with one of the |
19 | | /// `new_<calendar>_datetime()` per-calendar methods (and then freely converted between calendars). |
20 | | /// |
21 | | /// ```rust |
22 | | /// use icu::calendar::DateTime; |
23 | | /// |
24 | | /// // Example: Construction of ISO datetime from integers. |
25 | | /// let datetime_iso = DateTime::try_new_iso_datetime(1970, 1, 2, 13, 1, 0) |
26 | | /// .expect("Failed to initialize ISO DateTime instance."); |
27 | | /// |
28 | | /// assert_eq!(datetime_iso.date.year().number, 1970); |
29 | | /// assert_eq!(datetime_iso.date.month().ordinal, 1); |
30 | | /// assert_eq!(datetime_iso.date.day_of_month().0, 2); |
31 | | /// assert_eq!(datetime_iso.time.hour.number(), 13); |
32 | | /// assert_eq!(datetime_iso.time.minute.number(), 1); |
33 | | /// assert_eq!(datetime_iso.time.second.number(), 0); |
34 | | /// ``` |
35 | | #[derive(Debug)] |
36 | | #[allow(clippy::exhaustive_structs)] // this type is stable |
37 | | pub struct DateTime<A: AsCalendar> { |
38 | | /// The date |
39 | | pub date: Date<A>, |
40 | | /// The time |
41 | | pub time: Time, |
42 | | } |
43 | | |
44 | | impl<A: AsCalendar> DateTime<A> { |
45 | | /// Construct a [`DateTime`] for a given [`Date`] and [`Time`] |
46 | 0 | pub fn new(date: Date<A>, time: Time) -> Self { |
47 | 0 | DateTime { date, time } |
48 | 0 | } Unexecuted instantiation: <icu_calendar::datetime::DateTime<alloc::sync::Arc<icu_calendar::any_calendar::AnyCalendar>>>::new Unexecuted instantiation: <icu_calendar::datetime::DateTime<icu_calendar::iso::Iso>>::new Unexecuted instantiation: <icu_calendar::datetime::DateTime<_>>::new |
49 | | |
50 | | /// Construct a datetime from from era/month codes and fields, |
51 | | /// and some calendar representation |
52 | | #[inline] |
53 | 0 | pub fn try_new_from_codes( |
54 | 0 | era: types::Era, |
55 | 0 | year: i32, |
56 | 0 | month_code: types::MonthCode, |
57 | 0 | day: u8, |
58 | 0 | time: Time, |
59 | 0 | calendar: A, |
60 | 0 | ) -> Result<Self, CalendarError> { |
61 | 0 | let date = Date::try_new_from_codes(era, year, month_code, day, calendar)?; |
62 | 0 | Ok(DateTime { date, time }) |
63 | 0 | } Unexecuted instantiation: <icu_calendar::datetime::DateTime<alloc::sync::Arc<icu_calendar::any_calendar::AnyCalendar>>>::try_new_from_codes Unexecuted instantiation: <icu_calendar::datetime::DateTime<_>>::try_new_from_codes |
64 | | |
65 | | /// Construct a DateTime from an ISO datetime and some calendar representation |
66 | | #[inline] |
67 | 0 | pub fn new_from_iso(iso: DateTime<Iso>, calendar: A) -> Self { |
68 | 0 | let date = Date::new_from_iso(iso.date, calendar); |
69 | 0 | DateTime { |
70 | 0 | date, |
71 | 0 | time: iso.time, |
72 | 0 | } |
73 | 0 | } Unexecuted instantiation: <icu_calendar::datetime::DateTime<icu_calendar::gregorian::Gregorian>>::new_from_iso Unexecuted instantiation: <icu_calendar::datetime::DateTime<_>>::new_from_iso |
74 | | |
75 | | /// Convert the DateTime to an ISO DateTime |
76 | | #[inline] |
77 | 0 | pub fn to_iso(&self) -> DateTime<Iso> { |
78 | 0 | DateTime { |
79 | 0 | date: self.date.to_iso(), |
80 | 0 | time: self.time, |
81 | 0 | } |
82 | 0 | } Unexecuted instantiation: <icu_calendar::datetime::DateTime<alloc::sync::Arc<icu_calendar::any_calendar::AnyCalendar>>>::to_iso Unexecuted instantiation: <icu_calendar::datetime::DateTime<_>>::to_iso |
83 | | |
84 | | /// Convert the DateTime to a DateTime in a different calendar |
85 | | #[inline] |
86 | 0 | pub fn to_calendar<A2: AsCalendar>(&self, calendar: A2) -> DateTime<A2> { |
87 | 0 | DateTime { |
88 | 0 | date: self.date.to_calendar(calendar), |
89 | 0 | time: self.time, |
90 | 0 | } |
91 | 0 | } Unexecuted instantiation: <icu_calendar::datetime::DateTime<alloc::sync::Arc<icu_calendar::any_calendar::AnyCalendar>>>::to_calendar::<alloc::sync::Arc<icu_calendar::any_calendar::AnyCalendar>> Unexecuted instantiation: <icu_calendar::datetime::DateTime<icu_calendar::iso::Iso>>::to_calendar::<alloc::sync::Arc<icu_calendar::any_calendar::AnyCalendar>> Unexecuted instantiation: <icu_calendar::datetime::DateTime<_>>::to_calendar::<_> |
92 | | } |
93 | | |
94 | | impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>> DateTime<A> { |
95 | | /// Type-erase the date, converting it to a date for [`AnyCalendar`] |
96 | 0 | pub fn to_any(&self) -> DateTime<AnyCalendar> { |
97 | 0 | DateTime { |
98 | 0 | date: self.date.to_any(), |
99 | 0 | time: self.time, |
100 | 0 | } |
101 | 0 | } Unexecuted instantiation: <icu_calendar::datetime::DateTime<icu_calendar::iso::Iso>>::to_any Unexecuted instantiation: <icu_calendar::datetime::DateTime<_>>::to_any |
102 | | } |
103 | | |
104 | | impl<C: Calendar> DateTime<C> { |
105 | | /// Wrap the calendar type in `Rc<T>` |
106 | | /// |
107 | | /// Useful when paired with [`Self::to_any()`] to obtain a `DateTime<Rc<AnyCalendar>>` |
108 | 0 | pub fn wrap_calendar_in_rc(self) -> DateTime<Rc<C>> { |
109 | 0 | DateTime { |
110 | 0 | date: self.date.wrap_calendar_in_rc(), |
111 | 0 | time: self.time, |
112 | 0 | } |
113 | 0 | } |
114 | | |
115 | | /// Wrap the calendar type in `Arc<T>` |
116 | | /// |
117 | | /// Useful when paired with [`Self::to_any()`] to obtain a `DateTime<Rc<AnyCalendar>>` |
118 | 0 | pub fn wrap_calendar_in_arc(self) -> DateTime<Arc<C>> { |
119 | 0 | DateTime { |
120 | 0 | date: self.date.wrap_calendar_in_arc(), |
121 | 0 | time: self.time, |
122 | 0 | } |
123 | 0 | } Unexecuted instantiation: <icu_calendar::datetime::DateTime<icu_calendar::any_calendar::AnyCalendar>>::wrap_calendar_in_arc Unexecuted instantiation: <icu_calendar::datetime::DateTime<_>>::wrap_calendar_in_arc |
124 | | } |
125 | | |
126 | | impl<C, A, B> PartialEq<DateTime<B>> for DateTime<A> |
127 | | where |
128 | | C: Calendar, |
129 | | A: AsCalendar<Calendar = C>, |
130 | | B: AsCalendar<Calendar = C>, |
131 | | { |
132 | 0 | fn eq(&self, other: &DateTime<B>) -> bool { |
133 | 0 | self.date == other.date && self.time == other.time |
134 | 0 | } |
135 | | } |
136 | | |
137 | | // We can do this since DateInner is required to be Eq by the Calendar trait |
138 | | impl<A: AsCalendar> Eq for DateTime<A> {} |
139 | | |
140 | | impl<C, A, B> PartialOrd<DateTime<B>> for DateTime<A> |
141 | | where |
142 | | C: Calendar, |
143 | | C::DateInner: PartialOrd, |
144 | | A: AsCalendar<Calendar = C>, |
145 | | B: AsCalendar<Calendar = C>, |
146 | | { |
147 | 0 | fn partial_cmp(&self, other: &DateTime<B>) -> Option<core::cmp::Ordering> { |
148 | 0 | match self.date.partial_cmp(&other.date) { |
149 | 0 | Some(core::cmp::Ordering::Equal) => self.time.partial_cmp(&other.time), |
150 | 0 | other => other, |
151 | | } |
152 | 0 | } |
153 | | } |
154 | | |
155 | | impl<C, A> Ord for DateTime<A> |
156 | | where |
157 | | C: Calendar, |
158 | | C::DateInner: Ord, |
159 | | A: AsCalendar<Calendar = C>, |
160 | | { |
161 | 0 | fn cmp(&self, other: &Self) -> core::cmp::Ordering { |
162 | 0 | (&self.date, &self.time).cmp(&(&other.date, &other.time)) |
163 | 0 | } |
164 | | } |
165 | | |
166 | | impl<A: AsCalendar + Clone> Clone for DateTime<A> { |
167 | 0 | fn clone(&self) -> Self { |
168 | 0 | Self { |
169 | 0 | date: self.date.clone(), |
170 | 0 | time: self.time, |
171 | 0 | } |
172 | 0 | } |
173 | | } |
174 | | |
175 | | impl<A> Copy for DateTime<A> |
176 | | where |
177 | | A: AsCalendar + Copy, |
178 | | <<A as AsCalendar>::Calendar as Calendar>::DateInner: Copy, |
179 | | { |
180 | | } |
181 | | |
182 | | #[cfg(test)] |
183 | | mod tests { |
184 | | use super::*; |
185 | | |
186 | | #[test] |
187 | | fn test_ord() { |
188 | | let dates_in_order = [ |
189 | | DateTime::try_new_iso_datetime(0, 1, 1, 0, 0, 0).unwrap(), |
190 | | DateTime::try_new_iso_datetime(0, 1, 1, 0, 0, 1).unwrap(), |
191 | | DateTime::try_new_iso_datetime(0, 1, 1, 0, 1, 0).unwrap(), |
192 | | DateTime::try_new_iso_datetime(0, 1, 1, 1, 0, 0).unwrap(), |
193 | | DateTime::try_new_iso_datetime(0, 1, 2, 0, 0, 0).unwrap(), |
194 | | DateTime::try_new_iso_datetime(0, 2, 1, 0, 0, 0).unwrap(), |
195 | | DateTime::try_new_iso_datetime(1, 1, 1, 0, 0, 0).unwrap(), |
196 | | ]; |
197 | | for (i, i_date) in dates_in_order.iter().enumerate() { |
198 | | for (j, j_date) in dates_in_order.iter().enumerate() { |
199 | | let result1 = i_date.cmp(j_date); |
200 | | let result2 = j_date.cmp(i_date); |
201 | | assert_eq!(result1.reverse(), result2); |
202 | | assert_eq!(i.cmp(&j), i_date.cmp(j_date)); |
203 | | } |
204 | | } |
205 | | } |
206 | | } |