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}