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
341 > (SystemTime::UNIX_EPOCH - (FileTime::UNIX_EPOCH - FileTime::NT_TIME_EPOCH))
342 );
343 }
344
345 #[test]
346 fn order_utc_date_time_and_file_time() {
347 assert!(UtcDateTime::UNIX_EPOCH < FileTime::new(2_650_467_743_999_999_999));
348 assert_eq!(
349 UtcDateTime::UNIX_EPOCH.partial_cmp(&FileTime::UNIX_EPOCH),
350 Some(Ordering::Equal)
351 );
352 assert!(UtcDateTime::UNIX_EPOCH > FileTime::NT_TIME_EPOCH);
353 }
354
355 #[test]
356 fn order_file_time_and_utc_date_time() {
357 assert!(FileTime::UNIX_EPOCH < utc_datetime!(9999-12-31 23:59:59.999_999_900));
358 assert_eq!(
359 FileTime::UNIX_EPOCH.partial_cmp(&UtcDateTime::UNIX_EPOCH),
360 Some(Ordering::Equal)
361 );
362 assert!(FileTime::UNIX_EPOCH > utc_datetime!(1601-01-01 00:00:00));
363 }
364
365 #[cfg(feature = "chrono")]
366 #[test]
367 fn order_chrono_date_time_and_file_time() {
368 assert!(DateTime::<Utc>::UNIX_EPOCH < FileTime::MAX);
369 assert_eq!(
370 DateTime::<Utc>::UNIX_EPOCH.partial_cmp(&FileTime::UNIX_EPOCH),
371 Some(Ordering::Equal)
372 );
373 assert!(DateTime::<Utc>::UNIX_EPOCH > FileTime::NT_TIME_EPOCH);
374 }
375
376 #[cfg(feature = "chrono")]
377 #[test]
378 fn order_file_time_and_chrono_date_time() {
379 assert!(
380 FileTime::UNIX_EPOCH
381 < "+60056-05-28 05:36:10.955161500 UTC"
382 .parse::<DateTime<Utc>>()
383 .unwrap()
384 );
385 assert_eq!(
386 FileTime::UNIX_EPOCH.partial_cmp(&DateTime::<Utc>::UNIX_EPOCH),
387 Some(Ordering::Equal)
388 );
389 assert!(FileTime::UNIX_EPOCH > "1601-01-01 00:00:00 UTC".parse::<DateTime<Utc>>().unwrap());
390 }
391
392 #[cfg(feature = "jiff")]
393 #[test]
394 fn order_jiff_timestamp_and_file_time() {
395 assert!(Timestamp::UNIX_EPOCH < FileTime::new(2_650_466_808_009_999_999));
396 assert_eq!(
397 Timestamp::UNIX_EPOCH.partial_cmp(&FileTime::UNIX_EPOCH),
398 Some(Ordering::Equal)
399 );
400 assert!(Timestamp::UNIX_EPOCH > FileTime::NT_TIME_EPOCH);
401 }
402
403 #[cfg(feature = "jiff")]
404 #[test]
405 fn order_file_time_and_jiff_timestamp() {
406 assert!(FileTime::UNIX_EPOCH < Timestamp::MAX);
407 assert_eq!(
408 FileTime::UNIX_EPOCH.partial_cmp(&Timestamp::UNIX_EPOCH),
409 Some(Ordering::Equal)
410 );
411 assert!(FileTime::UNIX_EPOCH > Timestamp::from_second(-11_644_473_600).unwrap());
412 }
413}