Skip to main content

date_differencer/diff/
chrono_support.rs

1use chrono::{DateTime, Datelike, NaiveDateTime, Offset, Timelike};
2
3use super::DateTimeParts;
4
5impl<Tz> DateTimeParts for DateTime<Tz>
6where
7    Tz: chrono::TimeZone,
8    DateTime<Tz>: Ord,
9{
10    #[inline]
11    fn year(&self) -> i32 {
12        Datelike::year(self)
13    }
14
15    #[inline]
16    fn month(&self) -> u8 {
17        Datelike::month(self) as u8
18    }
19
20    #[inline]
21    fn day(&self) -> u8 {
22        Datelike::day(self) as u8
23    }
24
25    #[inline]
26    fn hour(&self) -> u8 {
27        Timelike::hour(self) as u8
28    }
29
30    #[inline]
31    fn minute(&self) -> u8 {
32        Timelike::minute(self) as u8
33    }
34
35    #[inline]
36    fn second(&self) -> u8 {
37        Timelike::second(self) as u8
38    }
39
40    #[inline]
41    fn nanosecond(&self) -> u32 {
42        // chrono represents a leap second with 1_000_000_000 or more nanoseconds, so treat it as the last nanosecond of the second.
43        Timelike::nanosecond(self).min(999_999_999)
44    }
45
46    #[inline]
47    fn all_parts(&self) -> (i32, u8, u8, u8, u8, u8, u32) {
48        // Calculate the local date-time only once instead of once per field.
49        self.naive_local().all_parts()
50    }
51
52    #[inline]
53    fn to_same_time_zone(&self, other: Self) -> Self {
54        // Looking up a time zone such as `Local` is slow, so skip the conversion when the offsets are already the same.
55        if self.offset().fix() == other.offset().fix() {
56            other
57        } else {
58            other.with_timezone(&self.timezone())
59        }
60    }
61}
62
63impl DateTimeParts for NaiveDateTime {
64    #[inline]
65    fn year(&self) -> i32 {
66        Datelike::year(self)
67    }
68
69    #[inline]
70    fn month(&self) -> u8 {
71        Datelike::month(self) as u8
72    }
73
74    #[inline]
75    fn day(&self) -> u8 {
76        Datelike::day(self) as u8
77    }
78
79    #[inline]
80    fn hour(&self) -> u8 {
81        Timelike::hour(self) as u8
82    }
83
84    #[inline]
85    fn minute(&self) -> u8 {
86        Timelike::minute(self) as u8
87    }
88
89    #[inline]
90    fn second(&self) -> u8 {
91        Timelike::second(self) as u8
92    }
93
94    #[inline]
95    fn nanosecond(&self) -> u32 {
96        // chrono represents a leap second with 1_000_000_000 or more nanoseconds, so treat it as the last nanosecond of the second.
97        Timelike::nanosecond(self).min(999_999_999)
98    }
99}