1use core::cmp::Ordering;
8#[cfg(feature = "std")]
9use std::time::SystemTime;
10
11#[cfg(feature = "chrono")]
12use chrono::{DateTime, Utc};
13#[cfg(feature = "jiff")]
14use jiff::Timestamp;
15use time::UtcDateTime;
16
17use super::FileTime;
18
19#[cfg(feature = "std")]
20impl PartialEq<FileTime> for SystemTime {
21 fn eq(&self, other: &FileTime) -> bool {
22 self == &Self::from(*other)
23 }
24}
25
26#[cfg(feature = "std")]
27impl PartialEq<SystemTime> for FileTime {
28 fn eq(&self, other: &SystemTime) -> bool {
29 &SystemTime::from(*self) == other
30 }
31}
32
33impl PartialEq<FileTime> for UtcDateTime {
34 fn eq(&self, other: &FileTime) -> bool {
35 self == &Self::try_from(*other).expect("`other` is out of range for `UtcDateTime`")
36 }
37}
38
39impl PartialEq<UtcDateTime> for FileTime {
40 fn eq(&self, other: &UtcDateTime) -> bool {
41 &UtcDateTime::try_from(*self).expect("`self` is out of range for `UtcDateTime`") == other
42 }
43}
44
45#[cfg(feature = "chrono")]
46impl PartialEq<FileTime> for DateTime<Utc> {
47 fn eq(&self, other: &FileTime) -> bool {
48 self == &Self::from(*other)
49 }
50}
51
52#[cfg(feature = "chrono")]
53impl PartialEq<DateTime<Utc>> for FileTime {
54 fn eq(&self, other: &DateTime<Utc>) -> bool {
55 &DateTime::<Utc>::from(*self) == other
56 }
57}
58
59#[cfg(feature = "jiff")]
60impl PartialEq<FileTime> for Timestamp {
61 fn eq(&self, other: &FileTime) -> bool {
62 self == &Self::try_from(*other).expect("`other` is out of range for `Timestamp`")
63 }
64}
65
66#[cfg(feature = "jiff")]
67impl PartialEq<Timestamp> for FileTime {
68 fn eq(&self, other: &Timestamp) -> bool {
69 &Timestamp::try_from(*self).expect("`self` is out of range for `Timestamp`") == other
70 }
71}
72
73#[cfg(feature = "std")]
74impl PartialOrd<FileTime> for SystemTime {
75 fn partial_cmp(&self, other: &FileTime) -> Option<Ordering> {
76 self.partial_cmp(&Self::from(*other))
77 }
78}
79
80#[cfg(feature = "std")]
81impl PartialOrd<SystemTime> for FileTime {
82 fn partial_cmp(&self, other: &SystemTime) -> Option<Ordering> {
83 SystemTime::from(*self).partial_cmp(other)
84 }
85}
86
87impl PartialOrd<FileTime> for UtcDateTime {
88 fn partial_cmp(&self, other: &FileTime) -> Option<Ordering> {
89 self.partial_cmp(
90 &Self::try_from(*other).expect("`other` is out of range for `UtcDateTime`"),
91 )
92 }
93}
94
95impl PartialOrd<UtcDateTime> for FileTime {
96 fn partial_cmp(&self, other: &UtcDateTime) -> Option<Ordering> {
97 UtcDateTime::try_from(*self)
98 .expect("`self` is out of range for `UtcDateTime`")
99 .partial_cmp(other)
100 }
101}
102
103#[cfg(feature = "chrono")]
104impl PartialOrd<FileTime> for DateTime<Utc> {
105 fn partial_cmp(&self, other: &FileTime) -> Option<Ordering> {
106 self.partial_cmp(&Self::from(*other))
107 }
108}
109
110#[cfg(feature = "chrono")]
111impl PartialOrd<DateTime<Utc>> for FileTime {
112 fn partial_cmp(&self, other: &DateTime<Utc>) -> Option<Ordering> {
113 DateTime::<Utc>::from(*self).partial_cmp(other)
114 }
115}
116
117#[cfg(feature = "jiff")]
118impl PartialOrd<FileTime> for Timestamp {
119 fn partial_cmp(&self, other: &FileTime) -> Option<Ordering> {
120 self.partial_cmp(&Self::try_from(*other).expect("`other` is out of range for `Timestamp`"))
121 }
122}
123
124#[cfg(feature = "jiff")]
125impl PartialOrd<Timestamp> for FileTime {
126 fn partial_cmp(&self, other: &Timestamp) -> Option<Ordering> {
127 Timestamp::try_from(*self)
128 .expect("`self` is out of range for `Timestamp`")
129 .partial_cmp(other)
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 #[cfg(feature = "std")]
136 use std::time::Duration;
137
138 #[cfg(feature = "jiff")]
139 use jiff::ToSpan;
140 use time::macros::utc_datetime;
141
142 use super::*;
143
144 #[test]
145 fn equality() {
146 assert_eq!(FileTime::NT_TIME_EPOCH, FileTime::NT_TIME_EPOCH);
147 assert_ne!(FileTime::NT_TIME_EPOCH, FileTime::UNIX_EPOCH);
148 assert_ne!(FileTime::NT_TIME_EPOCH, FileTime::MAX);
149 assert_ne!(FileTime::UNIX_EPOCH, FileTime::NT_TIME_EPOCH);
150 assert_eq!(FileTime::UNIX_EPOCH, FileTime::UNIX_EPOCH);
151 assert_ne!(FileTime::UNIX_EPOCH, FileTime::MAX);
152 assert_ne!(FileTime::MAX, FileTime::NT_TIME_EPOCH);
153 assert_ne!(FileTime::MAX, FileTime::UNIX_EPOCH);
154 assert_eq!(FileTime::MAX, FileTime::MAX);
155 }
156
157 #[test]
158 fn order() {
159 assert!(FileTime::UNIX_EPOCH < FileTime::MAX);
160 assert_eq!(
161 FileTime::UNIX_EPOCH.cmp(&FileTime::UNIX_EPOCH),
162 Ordering::Equal
163 );
164 assert!(FileTime::UNIX_EPOCH > FileTime::NT_TIME_EPOCH);
165 }
166
167 #[cfg(feature = "std")]
168 #[test]
169 fn equality_system_time_and_file_time() {
170 assert_eq!(
171 (SystemTime::UNIX_EPOCH + Duration::new(910_692_730_085, 477_580_700)),
172 FileTime::new(9_223_372_036_854_775_807)
173 );
174 assert_ne!(
175 (SystemTime::UNIX_EPOCH + Duration::new(910_692_730_085, 477_580_700)),
176 FileTime::new(9_223_372_036_854_775_806)
177 );
178 assert_eq!(SystemTime::UNIX_EPOCH, FileTime::UNIX_EPOCH);
179 assert_ne!(SystemTime::UNIX_EPOCH, FileTime::NT_TIME_EPOCH);
180 }
181
182 #[cfg(feature = "std")]
183 #[test]
184 fn equality_file_time_and_system_time() {
185 assert_eq!(
186 FileTime::new(9_223_372_036_854_775_807),
187 (SystemTime::UNIX_EPOCH + Duration::new(910_692_730_085, 477_580_700))
188 );
189 assert_ne!(
190 FileTime::new(9_223_372_036_854_775_806),
191 (SystemTime::UNIX_EPOCH + Duration::new(910_692_730_085, 477_580_700))
192 );
193 assert_eq!(FileTime::UNIX_EPOCH, SystemTime::UNIX_EPOCH);
194 assert_ne!(FileTime::NT_TIME_EPOCH, SystemTime::UNIX_EPOCH);
195 }
196
197 #[test]
198 fn equality_utc_date_time_and_file_time() {
199 assert_eq!(
200 utc_datetime!(9999-12-31 23:59:59.999_999_900),
201 FileTime::new(2_650_467_743_999_999_999)
202 );
203 assert_ne!(
204 utc_datetime!(9999-12-31 23:59:59.999_999_900),
205 FileTime::NT_TIME_EPOCH
206 );
207 assert_ne!(
208 utc_datetime!(1601-01-01 00:00:00),
209 FileTime::new(2_650_467_743_999_999_999)
210 );
211 assert_eq!(utc_datetime!(1601-01-01 00:00:00), FileTime::NT_TIME_EPOCH);
212 }
213
214 #[test]
215 fn equality_file_time_and_utc_date_time() {
216 assert_eq!(
217 FileTime::new(2_650_467_743_999_999_999),
218 utc_datetime!(9999-12-31 23:59:59.999_999_900)
219 );
220 assert_ne!(
221 FileTime::NT_TIME_EPOCH,
222 utc_datetime!(9999-12-31 23:59:59.999_999_900)
223 );
224 assert_ne!(
225 FileTime::new(2_650_467_743_999_999_999),
226 utc_datetime!(1601-01-01 00:00:00)
227 );
228 assert_eq!(FileTime::NT_TIME_EPOCH, utc_datetime!(1601-01-01 00:00:00));
229 }
230
231 #[cfg(feature = "chrono")]
232 #[test]
233 fn equality_chrono_date_time_and_file_time() {
234 assert_eq!(
235 "+60056-05-28 05:36:10.955161500 UTC"
236 .parse::<DateTime<Utc>>()
237 .unwrap(),
238 FileTime::MAX
239 );
240 assert_ne!(
241 "+60056-05-28 05:36:10.955161500 UTC"
242 .parse::<DateTime<Utc>>()
243 .unwrap(),
244 FileTime::NT_TIME_EPOCH
245 );
246 assert_ne!(
247 "1601-01-01 00:00:00 UTC".parse::<DateTime<Utc>>().unwrap(),
248 FileTime::MAX
249 );
250 assert_eq!(
251 "1601-01-01 00:00:00 UTC".parse::<DateTime<Utc>>().unwrap(),
252 FileTime::NT_TIME_EPOCH
253 );
254 }
255
256 #[cfg(feature = "chrono")]
257 #[test]
258 fn equality_file_time_and_chrono_date_time() {
259 assert_eq!(
260 FileTime::MAX,
261 "+60056-05-28 05:36:10.955161500 UTC"
262 .parse::<DateTime<Utc>>()
263 .unwrap()
264 );
265 assert_ne!(
266 FileTime::NT_TIME_EPOCH,
267 "+60056-05-28 05:36:10.955161500 UTC"
268 .parse::<DateTime<Utc>>()
269 .unwrap()
270 );
271 assert_ne!(
272 FileTime::MAX,
273 "1601-01-01 00:00:00 UTC".parse::<DateTime<Utc>>().unwrap()
274 );
275 assert_eq!(
276 FileTime::NT_TIME_EPOCH,
277 "1601-01-01 00:00:00 UTC".parse::<DateTime<Utc>>().unwrap()
278 );
279 }
280
281 #[cfg(feature = "jiff")]
282 #[test]
283 fn equality_jiff_timestamp_and_file_time() {
284 assert_eq!(
285 Timestamp::MAX - 99.nanoseconds(),
286 FileTime::new(2_650_466_808_009_999_999)
287 );
288 assert_ne!(Timestamp::MAX - 99.nanoseconds(), FileTime::NT_TIME_EPOCH);
289 assert_ne!(
290 Timestamp::from_second(-11_644_473_600).unwrap(),
291 FileTime::new(2_650_466_808_009_999_999)
292 );
293 assert_eq!(
294 Timestamp::from_second(-11_644_473_600).unwrap(),
295 FileTime::NT_TIME_EPOCH
296 );
297 }
298
299 #[cfg(feature = "jiff")]
300 #[test]
301 fn equality_file_time_and_jiff_timestamp() {
302 assert_eq!(
303 FileTime::new(2_650_466_808_009_999_999),
304 Timestamp::MAX - 99.nanoseconds()
305 );
306 assert_ne!(FileTime::NT_TIME_EPOCH, Timestamp::MAX - 99.nanoseconds());
307 assert_ne!(
308 FileTime::new(2_650_466_808_009_999_999),
309 Timestamp::from_second(-11_644_473_600).unwrap()
310 );
311 assert_eq!(
312 FileTime::NT_TIME_EPOCH,
313 Timestamp::from_second(-11_644_473_600).unwrap()
314 );
315 }
316
317 #[cfg(feature = "std")]
318 #[test]
319 fn order_system_time_and_file_time() {
320 assert!(SystemTime::UNIX_EPOCH < FileTime::new(9_223_372_036_854_775_807));
321 assert_eq!(
322 SystemTime::UNIX_EPOCH.partial_cmp(&FileTime::UNIX_EPOCH),
323 Some(Ordering::Equal)
324 );
325 assert!(SystemTime::UNIX_EPOCH > FileTime::NT_TIME_EPOCH);
326 }
327
328 #[cfg(feature = "std")]
329 #[test]
330 fn order_file_time_and_system_time() {
331 assert!(
332 FileTime::UNIX_EPOCH
333 < (SystemTime::UNIX_EPOCH + Duration::new(910_692_730_085, 477_580_700))
334 );
335 assert_eq!(
336 FileTime::UNIX_EPOCH.partial_cmp(&SystemTime::UNIX_EPOCH),
337 Some(Ordering::Equal)
338 );
339 assert!(
340 FileTime::UNIX_EPOCH > (SystemTime::UNIX_EPOCH - FileTime::UNIX_EPOCH.to_duration())
341 );
342 }
343
344 #[test]
345 fn order_utc_date_time_and_file_time() {
346 assert!(UtcDateTime::UNIX_EPOCH < FileTime::new(2_650_467_743_999_999_999));
347 assert_eq!(
348 UtcDateTime::UNIX_EPOCH.partial_cmp(&FileTime::UNIX_EPOCH),
349 Some(Ordering::Equal)
350 );
351 assert!(UtcDateTime::UNIX_EPOCH > FileTime::NT_TIME_EPOCH);
352 }
353
354 #[test]
355 fn order_file_time_and_utc_date_time() {
356 assert!(FileTime::UNIX_EPOCH < utc_datetime!(9999-12-31 23:59:59.999_999_900));
357 assert_eq!(
358 FileTime::UNIX_EPOCH.partial_cmp(&UtcDateTime::UNIX_EPOCH),
359 Some(Ordering::Equal)
360 );
361 assert!(FileTime::UNIX_EPOCH > utc_datetime!(1601-01-01 00:00:00));
362 }
363
364 #[cfg(feature = "chrono")]
365 #[test]
366 fn order_chrono_date_time_and_file_time() {
367 assert!(DateTime::<Utc>::UNIX_EPOCH < FileTime::MAX);
368 assert_eq!(
369 DateTime::<Utc>::UNIX_EPOCH.partial_cmp(&FileTime::UNIX_EPOCH),
370 Some(Ordering::Equal)
371 );
372 assert!(DateTime::<Utc>::UNIX_EPOCH > FileTime::NT_TIME_EPOCH);
373 }
374
375 #[cfg(feature = "chrono")]
376 #[test]
377 fn order_file_time_and_chrono_date_time() {
378 assert!(
379 FileTime::UNIX_EPOCH
380 < "+60056-05-28 05:36:10.955161500 UTC"
381 .parse::<DateTime<Utc>>()
382 .unwrap()
383 );
384 assert_eq!(
385 FileTime::UNIX_EPOCH.partial_cmp(&DateTime::<Utc>::UNIX_EPOCH),
386 Some(Ordering::Equal)
387 );
388 assert!(FileTime::UNIX_EPOCH > "1601-01-01 00:00:00 UTC".parse::<DateTime<Utc>>().unwrap());
389 }
390
391 #[cfg(feature = "jiff")]
392 #[test]
393 fn order_jiff_timestamp_and_file_time() {
394 assert!(Timestamp::UNIX_EPOCH < FileTime::new(2_650_466_808_009_999_999));
395 assert_eq!(
396 Timestamp::UNIX_EPOCH.partial_cmp(&FileTime::UNIX_EPOCH),
397 Some(Ordering::Equal)
398 );
399 assert!(Timestamp::UNIX_EPOCH > FileTime::NT_TIME_EPOCH);
400 }
401
402 #[cfg(feature = "jiff")]
403 #[test]
404 fn order_file_time_and_jiff_timestamp() {
405 assert!(FileTime::UNIX_EPOCH < Timestamp::MAX);
406 assert_eq!(
407 FileTime::UNIX_EPOCH.partial_cmp(&Timestamp::UNIX_EPOCH),
408 Some(Ordering::Equal)
409 );
410 assert!(FileTime::UNIX_EPOCH > Timestamp::from_second(-11_644_473_600).unwrap());
411 }
412}