nt_time/file_time/
consts.rs

1// SPDX-FileCopyrightText: 2023 Shun Sakai
2//
3// SPDX-License-Identifier: Apache-2.0 OR MIT
4
5//! Constants for [`FileTime`].
6
7use super::{FILE_TIMES_PER_SEC, FileTime};
8
9impl FileTime {
10    /// The [NT time epoch].
11    ///
12    /// This is defined as "1601-01-01 00:00:00 UTC", which was the first year
13    /// of the 400-year Gregorian calendar cycle at the time Windows NT was
14    /// being designed.
15    ///
16    /// # Examples
17    ///
18    /// ```
19    /// # use nt_time::{FileTime, time::macros::datetime};
20    /// #
21    /// assert_eq!(FileTime::NT_TIME_EPOCH, datetime!(1601-01-01 00:00 UTC));
22    /// ```
23    ///
24    /// [NT time epoch]: https://en.wikipedia.org/wiki/Epoch_(computing)
25    pub const NT_TIME_EPOCH: Self = Self::new(u64::MIN);
26
27    /// The [Unix epoch].
28    ///
29    /// This is defined as "1970-01-01 00:00:00 UTC", which is 11,644,473,600
30    /// seconds after [`FileTime::NT_TIME_EPOCH`].
31    ///
32    /// # Examples
33    ///
34    /// ```
35    /// # use nt_time::{FileTime, time::OffsetDateTime};
36    /// #
37    /// assert_eq!(FileTime::UNIX_EPOCH, OffsetDateTime::UNIX_EPOCH);
38    /// ```
39    ///
40    /// [Unix epoch]: https://en.wikipedia.org/wiki/Unix_time
41    pub const UNIX_EPOCH: Self = Self::new(134_774 * 86400 * FILE_TIMES_PER_SEC);
42
43    /// The largest file time accepted by the [`FileTimeToSystemTime`] function
44    /// of the [Win32 API].
45    ///
46    /// This is "+30828-09-14 02:48:05.477580700 UTC", which is equal to the
47    /// largest value of a 64-bit signed integer type when represented as an
48    /// underlying integer value.
49    ///
50    /// The [`FILETIME`] structure of the Win32 API represents a 64-bit unsigned
51    /// integer value, but many environments, such as the Win32 API, may limit
52    /// the largest value to [`i64::MAX`], and the file time is sometimes
53    /// represented as an [`i64`] value, such as in the
54    /// [`DateTime.FromFileTimeUtc`] method and the [`DateTime.ToFileTimeUtc`]
55    /// method in [.NET], so if you want the process to succeed in more
56    /// environments, it is generally recommended that you use this constant as
57    /// the largest value instead of [`FileTime::MAX`].
58    ///
59    /// <div class="warning">
60    ///
61    /// Note that the actual largest value of the [`SYSTEMTIME`] structure of
62    /// the Win32 API is "+30827-12-31 23:59:59.999000000" (which is either in
63    /// UTC or local time, depending on the function that is being called),
64    /// which is different from this constant. The `FileTimeToSystemTime`
65    /// function accepts the value of this constant, but it is an invalid date
66    /// and time for the `SYSTEMTIME` structure.
67    ///
68    /// </div>
69    ///
70    /// # Examples
71    ///
72    /// ```
73    /// # #[cfg(feature = "large-dates")]
74    /// # {
75    /// # use nt_time::{FileTime, time::macros::datetime};
76    /// #
77    /// assert_eq!(
78    ///     FileTime::SIGNED_MAX,
79    ///     datetime!(+30828-09-14 02:48:05.477_580_700 UTC)
80    /// );
81    /// # }
82    /// ```
83    ///
84    /// [`FileTimeToSystemTime`]: https://learn.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-filetimetosystemtime
85    /// [Win32 API]: https://learn.microsoft.com/en-us/windows/win32/
86    /// [`FILETIME`]: https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
87    /// [`DateTime.FromFileTimeUtc`]: https://learn.microsoft.com/en-us/dotnet/api/system.datetime.fromfiletimeutc
88    /// [`DateTime.ToFileTimeUtc`]: https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tofiletimeutc
89    /// [.NET]: https://dotnet.microsoft.com/
90    /// [`SYSTEMTIME`]: https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime
91    pub const SIGNED_MAX: Self = Self::new(i64::MAX as u64);
92
93    /// The largest value that can be represented by the file time.
94    ///
95    /// This is "+60056-05-28 05:36:10.955161500 UTC".
96    ///
97    /// This is the theoretical largest value that the [`FILETIME`] structure of
98    /// the [Win32 API] can represent.
99    ///
100    /// Many environments, such as the Win32 API, may limit the largest file
101    /// time to [`i64::MAX`], and the file time is sometimes represented as an
102    /// [`i64`] value, such as in the [`DateTime.FromFileTimeUtc`] method and
103    /// the [`DateTime.ToFileTimeUtc`] method in [.NET], so if you want the
104    /// process to succeed in more environments, it is generally recommended
105    /// that you use [`FileTime::SIGNED_MAX`] as the largest value instead of
106    /// this constant.
107    ///
108    /// # Examples
109    ///
110    /// ```
111    /// # #[cfg(feature = "large-dates")]
112    /// # {
113    /// # use nt_time::{FileTime, time::macros::datetime};
114    /// #
115    /// assert_eq!(
116    ///     FileTime::MAX,
117    ///     datetime!(+60056-05-28 05:36:10.955_161_500 UTC)
118    /// );
119    /// # }
120    /// ```
121    ///
122    /// [`FILETIME`]: https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
123    /// [Win32 API]: https://learn.microsoft.com/en-us/windows/win32/
124    /// [`DateTime.FromFileTimeUtc`]: https://learn.microsoft.com/en-us/dotnet/api/system.datetime.fromfiletimeutc
125    /// [`DateTime.ToFileTimeUtc`]: https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tofiletimeutc
126    /// [.NET]: https://dotnet.microsoft.com/
127    pub const MAX: Self = Self::new(u64::MAX);
128}
129
130#[cfg(test)]
131mod tests {
132    use time::{OffsetDateTime, macros::datetime};
133
134    use super::*;
135
136    #[test]
137    fn nt_time_epoch() {
138        assert_eq!(FileTime::NT_TIME_EPOCH, datetime!(1601-01-01 00:00 UTC));
139    }
140
141    #[test]
142    fn unix_epoch() {
143        assert_eq!(FileTime::UNIX_EPOCH, OffsetDateTime::UNIX_EPOCH);
144    }
145
146    #[cfg(feature = "large-dates")]
147    #[test]
148    fn signed_max() {
149        assert_eq!(
150            FileTime::SIGNED_MAX,
151            datetime!(+30828-09-14 02:48:05.477_580_700 UTC)
152        );
153    }
154
155    #[cfg(feature = "large-dates")]
156    #[test]
157    fn max() {
158        assert_eq!(
159            FileTime::MAX,
160            datetime!(+60056-05-28 05:36:10.955_161_500 UTC)
161        );
162    }
163}