nt_time/
lib.rs

1// SPDX-FileCopyrightText: 2023 Shun Sakai
2//
3// SPDX-License-Identifier: Apache-2.0 OR MIT
4
5//! The `nt-time` crate is a [Windows file time] library.
6//!
7//! The [`FileTime`] is a type that represents the file time, which is a 64-bit
8//! unsigned integer value that represents the number of 100-nanosecond
9//! intervals that have elapsed since "1601-01-01 00:00:00 UTC", and is used as
10//! timestamps such as [NTFS] and [7z]. Windows uses a file time to record when
11//! an application creates, accesses, or writes to a file.
12//!
13//! <div class="warning">
14//!
15//! Note that many environments, such as the [Win32 API], may limit the largest
16//! value of the file time to "+30828-09-14 02:48:05.477580700 UTC", which is
17//! equal to [`i64::MAX`], the largest value of a 64-bit signed integer type
18//! when represented as an underlying integer value. This is the largest file
19//! time accepted by the [`FileTimeToSystemTime`] function of the Win32 API.
20//!
21//! </div>
22//!
23//! # Examples
24//!
25//! ## Basic usage
26//!
27//! [`FileTime`] can be converted from and to a type which represents time such
28//! as [`time::OffsetDateTime`]. Addition and subtraction are also supported.
29//!
30//! ```
31//! use core::time::Duration;
32//!
33//! use nt_time::{
34//!     FileTime,
35//!     time::{OffsetDateTime, macros::datetime},
36//! };
37//!
38//! let ft = FileTime::NT_TIME_EPOCH;
39//! assert_eq!(
40//!     OffsetDateTime::try_from(ft),
41//!     Ok(datetime!(1601-01-01 00:00 UTC))
42//! );
43//!
44//! let ft = ft + Duration::from_secs(11_644_473_600);
45//! assert_eq!(OffsetDateTime::try_from(ft), Ok(OffsetDateTime::UNIX_EPOCH));
46//! assert_eq!(ft.to_raw(), 116_444_736_000_000_000);
47//!
48//! // The practical largest file time.
49//! assert_eq!(FileTime::try_from(i64::MAX), Ok(FileTime::SIGNED_MAX));
50//! // The theoretical largest file time.
51//! assert_eq!(FileTime::new(u64::MAX), FileTime::MAX);
52//! ```
53//!
54//! ## Conversion from and to other system times
55//!
56//! [`FileTime`] can be converted from and to other system times such as [Unix
57//! time] or [MS-DOS date and time].
58//!
59//! ```
60//! use core::time::Duration;
61//!
62//! use nt_time::{FileTime, time::OffsetDateTime};
63//!
64//! // `1970-01-01 00:00:00 UTC`.
65//! let ut = i64::default();
66//! assert_eq!(
67//!     OffsetDateTime::from_unix_timestamp(ut),
68//!     Ok(OffsetDateTime::UNIX_EPOCH)
69//! );
70//!
71//! let ft = FileTime::from_unix_time_secs(ut).unwrap();
72//! assert_eq!(ft, FileTime::UNIX_EPOCH);
73//!
74//! // From `1980-01-01 00:00:00 UTC` to `1980-01-01 00:00:00`.
75//! let ft = ft + Duration::from_secs(315_532_800);
76//! let dos_dt = ft.to_dos_date_time();
77//! assert_eq!(dos_dt, Ok((0x0021, u16::MIN)));
78//! ```
79//!
80//! ## Formatting and printing the file time
81//!
82//! The formatting traits for [`FileTime`] are implemented to show the
83//! underlying [`u64`] value. If you need a human-readable date and time,
84//! convert [`FileTime`] to a type which represents time such as
85//! [`time::OffsetDateTime`].
86//!
87//! ```
88//! use nt_time::{FileTime, time::OffsetDateTime};
89//!
90//! let ft = FileTime::NT_TIME_EPOCH;
91//! assert_eq!(format!("{ft}"), "0");
92//!
93//! let dt = OffsetDateTime::try_from(ft).unwrap();
94//! assert_eq!(format!("{dt}"), "1601-01-01 0:00:00.0 +00:00:00");
95//! ```
96//!
97//! [Windows file time]: https://docs.microsoft.com/en-us/windows/win32/sysinfo/file-times
98//! [NTFS]: https://en.wikipedia.org/wiki/NTFS
99//! [7z]: https://www.7-zip.org/7z.html
100//! [Win32 API]: https://learn.microsoft.com/en-us/windows/win32/
101//! [`FileTimeToSystemTime`]: https://learn.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-filetimetosystemtime
102//! [Unix time]: https://en.wikipedia.org/wiki/Unix_time
103//! [MS-DOS date and time]: https://learn.microsoft.com/en-us/windows/win32/sysinfo/ms-dos-date-and-time
104
105#![doc(html_root_url = "https://docs.rs/nt-time/0.12.1/")]
106#![no_std]
107#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
108// Lint levels of rustc.
109#![deny(missing_docs)]
110
111#[cfg(test)]
112#[macro_use]
113extern crate alloc;
114#[cfg(feature = "std")]
115extern crate std;
116
117pub mod error;
118mod file_time;
119#[cfg(feature = "serde")]
120pub mod serde_with;
121
122#[cfg(feature = "chrono")]
123pub use chrono;
124#[cfg(feature = "jiff")]
125pub use jiff;
126#[cfg(feature = "rand")]
127pub use rand;
128#[cfg(feature = "serde")]
129pub use serde;
130pub use time;
131
132pub use crate::file_time::FileTime;