1use crate::any_calendar::{AnyCalendar, IntoAnyCalendar};
6use crate::types::{self, Time};
7use crate::{AsCalendar, Calendar, CalendarError, Date, Iso};
8use alloc::rc::Rc;
9use alloc::sync::Arc;
10
11#[derive(Debug)]
36#[allow(clippy::exhaustive_structs)] pub struct DateTime<A: AsCalendar> {
38 pub date: Date<A>,
40 pub time: Time,
42}
43
44impl<A: AsCalendar> DateTime<A> {
45 pub fn new(date: Date<A>, time: Time) -> Self {
47 DateTime { date, time }
48 }
49
50 #[inline]
53 pub fn try_new_from_codes(
54 era: types::Era,
55 year: i32,
56 month_code: types::MonthCode,
57 day: u8,
58 time: Time,
59 calendar: A,
60 ) -> Result<Self, CalendarError> {
61 let date = Date::try_new_from_codes(era, year, month_code, day, calendar)?;
62 Ok(DateTime { date, time })
63 }
64
65 #[inline]
67 pub fn new_from_iso(iso: DateTime<Iso>, calendar: A) -> Self {
68 let date = Date::new_from_iso(iso.date, calendar);
69 DateTime {
70 date,
71 time: iso.time,
72 }
73 }
74
75 #[inline]
77 pub fn to_iso(&self) -> DateTime<Iso> {
78 DateTime {
79 date: self.date.to_iso(),
80 time: self.time,
81 }
82 }
83
84 #[inline]
86 pub fn to_calendar<A2: AsCalendar>(&self, calendar: A2) -> DateTime<A2> {
87 DateTime {
88 date: self.date.to_calendar(calendar),
89 time: self.time,
90 }
91 }
92}
93
94impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>> DateTime<A> {
95 pub fn to_any(&self) -> DateTime<AnyCalendar> {
97 DateTime {
98 date: self.date.to_any(),
99 time: self.time,
100 }
101 }
102}
103
104impl<C: Calendar> DateTime<C> {
105 pub fn wrap_calendar_in_rc(self) -> DateTime<Rc<C>> {
109 DateTime {
110 date: self.date.wrap_calendar_in_rc(),
111 time: self.time,
112 }
113 }
114
115 pub fn wrap_calendar_in_arc(self) -> DateTime<Arc<C>> {
119 DateTime {
120 date: self.date.wrap_calendar_in_arc(),
121 time: self.time,
122 }
123 }
124}
125
126impl<C, A, B> PartialEq<DateTime<B>> for DateTime<A>
127where
128 C: Calendar,
129 A: AsCalendar<Calendar = C>,
130 B: AsCalendar<Calendar = C>,
131{
132 fn eq(&self, other: &DateTime<B>) -> bool {
133 self.date == other.date && self.time == other.time
134 }
135}
136
137impl<A: AsCalendar> Eq for DateTime<A> {}
139
140impl<C, A, B> PartialOrd<DateTime<B>> for DateTime<A>
141where
142 C: Calendar,
143 C::DateInner: PartialOrd,
144 A: AsCalendar<Calendar = C>,
145 B: AsCalendar<Calendar = C>,
146{
147 fn partial_cmp(&self, other: &DateTime<B>) -> Option<core::cmp::Ordering> {
148 match self.date.partial_cmp(&other.date) {
149 Some(core::cmp::Ordering::Equal) => self.time.partial_cmp(&other.time),
150 other => other,
151 }
152 }
153}
154
155impl<C, A> Ord for DateTime<A>
156where
157 C: Calendar,
158 C::DateInner: Ord,
159 A: AsCalendar<Calendar = C>,
160{
161 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
162 (&self.date, &self.time).cmp(&(&other.date, &other.time))
163 }
164}
165
166impl<A: AsCalendar + Clone> Clone for DateTime<A> {
167 fn clone(&self) -> Self {
168 Self {
169 date: self.date.clone(),
170 time: self.time,
171 }
172 }
173}
174
175impl<A> Copy for DateTime<A>
176where
177 A: AsCalendar + Copy,
178 <<A as AsCalendar>::Calendar as Calendar>::DateInner: Copy,
179{
180}
181
182#[cfg(test)]
183mod 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}