1 //! Timestamps for files in Rust
3 //! This library provides platform-agnostic inspection of the various timestamps
4 //! present in the standard `fs::Metadata` structure.
8 //! Add this to your `Cargo.toml`:
19 //! use filetime::FileTime;
21 //! let metadata = fs::metadata("foo.txt").unwrap();
23 //! let mtime = FileTime::from_last_modification_time(&metadata);
24 //! println!("{}", mtime);
26 //! let atime = FileTime::from_last_access_time(&metadata);
27 //! assert!(mtime < atime);
29 //! // Inspect values that can be interpreted across platforms
30 //! println!("{}", mtime.unix_seconds());
31 //! println!("{}", mtime.nanoseconds());
33 //! // Print the platform-specific value of seconds
34 //! println!("{}", mtime.seconds());
41 use std
::time
::{Duration, SystemTime, UNIX_EPOCH}
;
44 if #[cfg(target_os = "redox")] {
47 } else if #[cfg(windows)] {
48 #[path = "windows.rs"]
50 } else if #[cfg(target_arch = "wasm32")] {
54 #[path = "unix/mod.rs"]
59 /// A helper structure to represent a timestamp for a file.
61 /// The actual value contined within is platform-specific and does not have the
62 /// same meaning across platforms, but comparisons and stringification can be
63 /// significant among the same platform.
64 #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Copy, Clone, Hash)]
71 /// Creates a new timestamp representing a 0 time.
73 /// Useful for creating the base of a cmp::max chain of times.
74 pub const fn zero() -> FileTime
{
81 const fn emulate_second_only_system(self) -> FileTime
{
82 if cfg
!(emulate_second_only_system
) {
84 seconds
: self.seconds
,
92 /// Creates a new timestamp representing the current system time.
95 /// # use filetime::FileTime;
97 /// # fn example() -> std::io::Result<()> {
100 /// filetime::set_file_mtime(path, FileTime::now())?;
106 /// Equivalent to `FileTime::from_system_time(SystemTime::now())`.
107 pub fn now() -> FileTime
{
108 FileTime
::from_system_time(SystemTime
::now())
111 /// Creates a new instance of `FileTime` with a number of seconds and
112 /// nanoseconds relative to the Unix epoch, 1970-01-01T00:00:00Z.
114 /// Negative seconds represent times before the Unix epoch, and positive
115 /// values represent times after it. Nanos always count forwards in time.
117 /// Note that this is typically the relative point that Unix time stamps are
118 /// from, but on Windows the native time stamp is relative to January 1,
119 /// 1601 so the return value of `seconds` from the returned `FileTime`
120 /// instance may not be the same as that passed in.
121 pub const fn from_unix_time(seconds
: i64, nanos
: u32) -> FileTime
{
123 seconds
: seconds
+ if cfg
!(windows
) { 11644473600 }
else { 0 }
,
126 .emulate_second_only_system()
129 /// Creates a new timestamp from the last modification time listed in the
130 /// specified metadata.
132 /// The returned value corresponds to the `mtime` field of `stat` on Unix
133 /// platforms and the `ftLastWriteTime` field on Windows platforms.
134 pub fn from_last_modification_time(meta
: &fs
::Metadata
) -> FileTime
{
135 imp
::from_last_modification_time(meta
).emulate_second_only_system()
138 /// Creates a new timestamp from the last access time listed in the
139 /// specified metadata.
141 /// The returned value corresponds to the `atime` field of `stat` on Unix
142 /// platforms and the `ftLastAccessTime` field on Windows platforms.
143 pub fn from_last_access_time(meta
: &fs
::Metadata
) -> FileTime
{
144 imp
::from_last_access_time(meta
).emulate_second_only_system()
147 /// Creates a new timestamp from the creation time listed in the specified
150 /// The returned value corresponds to the `birthtime` field of `stat` on
151 /// Unix platforms and the `ftCreationTime` field on Windows platforms. Note
152 /// that not all Unix platforms have this field available and may return
153 /// `None` in some circumstances.
154 pub fn from_creation_time(meta
: &fs
::Metadata
) -> Option
<FileTime
> {
155 imp
::from_creation_time(meta
).map(|x
| x
.emulate_second_only_system())
158 /// Creates a new timestamp from the given SystemTime.
160 /// Windows counts file times since 1601-01-01T00:00:00Z, and cannot
161 /// represent times before this, but it's possible to create a SystemTime
162 /// that does. This function will error if passed such a SystemTime.
163 pub fn from_system_time(time
: SystemTime
) -> FileTime
{
164 let epoch
= if cfg
!(windows
) {
165 UNIX_EPOCH
- Duration
::from_secs(11644473600)
170 time
.duration_since(epoch
)
172 seconds
: d
.as_secs() as i64,
173 nanos
: d
.subsec_nanos(),
175 .unwrap_or_else(|e
| {
176 let until_epoch
= e
.duration();
177 let (sec_offset
, nanos
) = if until_epoch
.subsec_nanos() == 0 {
180 (-1, 1_000_000_000 - until_epoch
.subsec_nanos())
184 seconds
: -1 * until_epoch
.as_secs() as i64 + sec_offset
,
188 .emulate_second_only_system()
191 /// Returns the whole number of seconds represented by this timestamp.
193 /// Note that this value's meaning is **platform specific**. On Unix
194 /// platform time stamps are typically relative to January 1, 1970, but on
195 /// Windows platforms time stamps are relative to January 1, 1601.
196 pub const fn seconds(&self) -> i64 {
200 /// Returns the whole number of seconds represented by this timestamp,
201 /// relative to the Unix epoch start of January 1, 1970.
203 /// Note that this does not return the same value as `seconds` for Windows
204 /// platforms as seconds are relative to a different date there.
205 pub const fn unix_seconds(&self) -> i64 {
206 self.seconds
- if cfg
!(windows
) { 11644473600 }
else { 0 }
209 /// Returns the nanosecond precision of this timestamp.
211 /// The returned value is always less than one billion and represents a
212 /// portion of a second forward from the seconds returned by the `seconds`
214 pub const fn nanoseconds(&self) -> u32 {
219 impl fmt
::Display
for FileTime
{
220 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
221 write
!(f
, "{}.{:09}s", self.seconds
, self.nanos
)
225 impl From
<SystemTime
> for FileTime
{
226 fn from(time
: SystemTime
) -> FileTime
{
227 FileTime
::from_system_time(time
)
231 /// Set the last access and modification times for a file on the filesystem.
233 /// This function will set the `atime` and `mtime` metadata fields for a file
234 /// on the local filesystem, returning any error encountered.
235 pub fn set_file_times
<P
>(p
: P
, atime
: FileTime
, mtime
: FileTime
) -> io
::Result
<()>
239 imp
::set_file_times(p
.as_ref(), atime
, mtime
)
242 /// Set the last access and modification times for a file handle.
244 /// This function will either or both of the `atime` and `mtime` metadata
245 /// fields for a file handle , returning any error encountered. If `None` is
246 /// specified then the time won't be updated. If `None` is specified for both
247 /// options then no action is taken.
248 pub fn set_file_handle_times(
250 atime
: Option
<FileTime
>,
251 mtime
: Option
<FileTime
>,
252 ) -> io
::Result
<()> {
253 imp
::set_file_handle_times(f
, atime
, mtime
)
256 /// Set the last access and modification times for a file on the filesystem.
257 /// This function does not follow symlink.
259 /// This function will set the `atime` and `mtime` metadata fields for a file
260 /// on the local filesystem, returning any error encountered.
261 pub fn set_symlink_file_times
<P
>(p
: P
, atime
: FileTime
, mtime
: FileTime
) -> io
::Result
<()>
265 imp
::set_symlink_file_times(p
.as_ref(), atime
, mtime
)
268 /// Set the last modification time for a file on the filesystem.
270 /// This function will set the `mtime` metadata field for a file on the local
271 /// filesystem, returning any error encountered.
273 /// # Platform support
275 /// Where supported this will attempt to issue just one syscall to update only
276 /// the `mtime`, but where not supported this may issue one syscall to learn the
277 /// existing `atime` so only the `mtime` can be configured.
278 pub fn set_file_mtime
<P
>(p
: P
, mtime
: FileTime
) -> io
::Result
<()>
282 imp
::set_file_mtime(p
.as_ref(), mtime
)
285 /// Set the last access time for a file on the filesystem.
287 /// This function will set the `atime` metadata field for a file on the local
288 /// filesystem, returning any error encountered.
290 /// # Platform support
292 /// Where supported this will attempt to issue just one syscall to update only
293 /// the `atime`, but where not supported this may issue one syscall to learn the
294 /// existing `mtime` so only the `atime` can be configured.
295 pub fn set_file_atime
<P
>(p
: P
, atime
: FileTime
) -> io
::Result
<()>
299 imp
::set_file_atime(p
.as_ref(), atime
)
305 set_file_atime
, set_file_handle_times
, set_file_mtime
, set_file_times
,
306 set_symlink_file_times
, FileTime
,
308 use std
::fs
::{self, File}
;
311 use std
::time
::{Duration, UNIX_EPOCH}
;
312 use tempfile
::Builder
;
315 fn make_symlink_file
<P
, Q
>(src
: P
, dst
: Q
) -> io
::Result
<()>
320 use std
::os
::unix
::fs
::symlink
;
325 fn make_symlink_file
<P
, Q
>(src
: P
, dst
: Q
) -> io
::Result
<()>
330 use std
::os
::windows
::fs
::symlink_file
;
331 symlink_file(src
, dst
)
335 fn make_symlink_dir
<P
, Q
>(src
: P
, dst
: Q
) -> io
::Result
<()>
340 use std
::os
::unix
::fs
::symlink
;
345 fn make_symlink_dir
<P
, Q
>(src
: P
, dst
: Q
) -> io
::Result
<()>
350 use std
::os
::windows
::fs
::symlink_dir
;
351 symlink_dir(src
, dst
)
356 fn from_unix_time_test() {
357 let time
= FileTime
::from_unix_time(10, 100_000_000);
358 assert_eq
!(11644473610, time
.seconds
);
359 assert_eq
!(100_000_000, time
.nanos
);
361 let time
= FileTime
::from_unix_time(-10, 100_000_000);
362 assert_eq
!(11644473590, time
.seconds
);
363 assert_eq
!(100_000_000, time
.nanos
);
365 let time
= FileTime
::from_unix_time(-12_000_000_000, 0);
366 assert_eq
!(-355526400, time
.seconds
);
367 assert_eq
!(0, time
.nanos
);
372 fn from_unix_time_test() {
373 let time
= FileTime
::from_unix_time(10, 100_000_000);
374 assert_eq
!(10, time
.seconds
);
375 assert_eq
!(100_000_000, time
.nanos
);
377 let time
= FileTime
::from_unix_time(-10, 100_000_000);
378 assert_eq
!(-10, time
.seconds
);
379 assert_eq
!(100_000_000, time
.nanos
);
381 let time
= FileTime
::from_unix_time(-12_000_000_000, 0);
382 assert_eq
!(-12_000_000_000, time
.seconds
);
383 assert_eq
!(0, time
.nanos
);
388 fn from_system_time_test() {
389 let time
= FileTime
::from_system_time(UNIX_EPOCH
+ Duration
::from_secs(10));
390 assert_eq
!(11644473610, time
.seconds
);
391 assert_eq
!(0, time
.nanos
);
393 let time
= FileTime
::from_system_time(UNIX_EPOCH
- Duration
::from_secs(10));
394 assert_eq
!(11644473590, time
.seconds
);
395 assert_eq
!(0, time
.nanos
);
397 let time
= FileTime
::from_system_time(UNIX_EPOCH
- Duration
::from_millis(1100));
398 assert_eq
!(11644473598, time
.seconds
);
399 assert_eq
!(900_000_000, time
.nanos
);
401 let time
= FileTime
::from_system_time(UNIX_EPOCH
- Duration
::from_secs(12_000_000_000));
402 assert_eq
!(-355526400, time
.seconds
);
403 assert_eq
!(0, time
.nanos
);
408 fn from_system_time_test() {
409 let time
= FileTime
::from_system_time(UNIX_EPOCH
+ Duration
::from_secs(10));
410 assert_eq
!(10, time
.seconds
);
411 assert_eq
!(0, time
.nanos
);
413 let time
= FileTime
::from_system_time(UNIX_EPOCH
- Duration
::from_secs(10));
414 assert_eq
!(-10, time
.seconds
);
415 assert_eq
!(0, time
.nanos
);
417 let time
= FileTime
::from_system_time(UNIX_EPOCH
- Duration
::from_millis(1100));
418 assert_eq
!(-2, time
.seconds
);
419 assert_eq
!(900_000_000, time
.nanos
);
421 let time
= FileTime
::from_system_time(UNIX_EPOCH
- Duration
::from_secs(12_000_000));
422 assert_eq
!(-12_000_000, time
.seconds
);
423 assert_eq
!(0, time
.nanos
);
427 fn set_file_times_test() -> io
::Result
<()> {
428 let td
= Builder
::new().prefix("filetime").tempdir()?
;
429 let path
= td
.path().join("foo.txt");
430 let mut f
= File
::create(&path
)?
;
432 let metadata
= fs
::metadata(&path
)?
;
433 let mtime
= FileTime
::from_last_modification_time(&metadata
);
434 let atime
= FileTime
::from_last_access_time(&metadata
);
435 set_file_times(&path
, atime
, mtime
)?
;
437 let new_mtime
= FileTime
::from_unix_time(10_000, 0);
438 set_file_times(&path
, atime
, new_mtime
)?
;
440 let metadata
= fs
::metadata(&path
)?
;
441 let mtime
= FileTime
::from_last_modification_time(&metadata
);
442 assert_eq
!(mtime
, new_mtime
, "modification should be updated");
445 let new_mtime
= FileTime
::from_unix_time(20_000, 0);
446 set_file_handle_times(&mut f
, None
, Some(new_mtime
))?
;
447 let metadata
= f
.metadata()?
;
448 let mtime
= FileTime
::from_last_modification_time(&metadata
);
449 assert_eq
!(mtime
, new_mtime
, "modification time should be updated");
450 let new_atime
= FileTime
::from_last_access_time(&metadata
);
451 assert_eq
!(atime
, new_atime
, "accessed time should not be updated");
454 let new_atime
= FileTime
::from_unix_time(30_000, 0);
455 set_file_handle_times(&mut f
, Some(new_atime
), None
)?
;
456 let metadata
= f
.metadata()?
;
457 let mtime
= FileTime
::from_last_modification_time(&metadata
);
458 assert_eq
!(mtime
, new_mtime
, "modification time should not be updated");
459 let atime
= FileTime
::from_last_access_time(&metadata
);
460 assert_eq
!(atime
, new_atime
, "accessed time should be updated");
462 let spath
= td
.path().join("bar.txt");
463 make_symlink_file(&path
, &spath
)?
;
464 let metadata
= fs
::symlink_metadata(&spath
)?
;
465 let smtime
= FileTime
::from_last_modification_time(&metadata
);
467 set_file_times(&spath
, atime
, mtime
)?
;
469 let metadata
= fs
::metadata(&path
)?
;
470 let cur_mtime
= FileTime
::from_last_modification_time(&metadata
);
471 assert_eq
!(mtime
, cur_mtime
);
473 let metadata
= fs
::symlink_metadata(&spath
)?
;
474 let cur_mtime
= FileTime
::from_last_modification_time(&metadata
);
475 assert_eq
!(smtime
, cur_mtime
);
477 set_file_times(&spath
, atime
, new_mtime
)?
;
479 let metadata
= fs
::metadata(&path
)?
;
480 let mtime
= FileTime
::from_last_modification_time(&metadata
);
481 assert_eq
!(mtime
, new_mtime
);
483 let metadata
= fs
::symlink_metadata(&spath
)?
;
484 let mtime
= FileTime
::from_last_modification_time(&metadata
);
485 assert_eq
!(mtime
, smtime
);
490 fn set_dir_times_test() -> io
::Result
<()> {
491 let td
= Builder
::new().prefix("filetime").tempdir()?
;
492 let path
= td
.path().join("foo");
493 fs
::create_dir(&path
)?
;
495 let metadata
= fs
::metadata(&path
)?
;
496 let mtime
= FileTime
::from_last_modification_time(&metadata
);
497 let atime
= FileTime
::from_last_access_time(&metadata
);
498 set_file_times(&path
, atime
, mtime
)?
;
500 let new_mtime
= FileTime
::from_unix_time(10_000, 0);
501 set_file_times(&path
, atime
, new_mtime
)?
;
503 let metadata
= fs
::metadata(&path
)?
;
504 let mtime
= FileTime
::from_last_modification_time(&metadata
);
505 assert_eq
!(mtime
, new_mtime
, "modification should be updated");
508 let new_mtime
= FileTime
::from_unix_time(20_000, 0);
509 set_file_mtime(&path
, new_mtime
)?
;
510 let metadata
= fs
::metadata(&path
)?
;
511 let mtime
= FileTime
::from_last_modification_time(&metadata
);
512 assert_eq
!(mtime
, new_mtime
, "modification time should be updated");
513 let new_atime
= FileTime
::from_last_access_time(&metadata
);
514 assert_eq
!(atime
, new_atime
, "accessed time should not be updated");
517 let new_atime
= FileTime
::from_unix_time(30_000, 0);
518 set_file_atime(&path
, new_atime
)?
;
519 let metadata
= fs
::metadata(&path
)?
;
520 let mtime
= FileTime
::from_last_modification_time(&metadata
);
521 assert_eq
!(mtime
, new_mtime
, "modification time should not be updated");
522 let atime
= FileTime
::from_last_access_time(&metadata
);
523 assert_eq
!(atime
, new_atime
, "accessed time should be updated");
525 let spath
= td
.path().join("bar");
526 make_symlink_dir(&path
, &spath
)?
;
527 let metadata
= fs
::symlink_metadata(&spath
)?
;
528 let smtime
= FileTime
::from_last_modification_time(&metadata
);
530 set_file_times(&spath
, atime
, mtime
)?
;
532 let metadata
= fs
::metadata(&path
)?
;
533 let cur_mtime
= FileTime
::from_last_modification_time(&metadata
);
534 assert_eq
!(mtime
, cur_mtime
);
536 let metadata
= fs
::symlink_metadata(&spath
)?
;
537 let cur_mtime
= FileTime
::from_last_modification_time(&metadata
);
538 assert_eq
!(smtime
, cur_mtime
);
540 set_file_times(&spath
, atime
, new_mtime
)?
;
542 let metadata
= fs
::metadata(&path
)?
;
543 let mtime
= FileTime
::from_last_modification_time(&metadata
);
544 assert_eq
!(mtime
, new_mtime
);
546 let metadata
= fs
::symlink_metadata(&spath
)?
;
547 let mtime
= FileTime
::from_last_modification_time(&metadata
);
548 assert_eq
!(mtime
, smtime
);
553 fn set_file_times_pre_unix_epoch_test() {
554 let td
= Builder
::new().prefix("filetime").tempdir().unwrap();
555 let path
= td
.path().join("foo.txt");
556 File
::create(&path
).unwrap();
558 let metadata
= fs
::metadata(&path
).unwrap();
559 let mtime
= FileTime
::from_last_modification_time(&metadata
);
560 let atime
= FileTime
::from_last_access_time(&metadata
);
561 set_file_times(&path
, atime
, mtime
).unwrap();
563 let new_mtime
= FileTime
::from_unix_time(-10_000, 0);
564 set_file_times(&path
, atime
, new_mtime
).unwrap();
566 let metadata
= fs
::metadata(&path
).unwrap();
567 let mtime
= FileTime
::from_last_modification_time(&metadata
);
568 assert_eq
!(mtime
, new_mtime
);
573 fn set_file_times_pre_windows_epoch_test() {
574 let td
= Builder
::new().prefix("filetime").tempdir().unwrap();
575 let path
= td
.path().join("foo.txt");
576 File
::create(&path
).unwrap();
578 let metadata
= fs
::metadata(&path
).unwrap();
579 let mtime
= FileTime
::from_last_modification_time(&metadata
);
580 let atime
= FileTime
::from_last_access_time(&metadata
);
581 set_file_times(&path
, atime
, mtime
).unwrap();
583 let new_mtime
= FileTime
::from_unix_time(-12_000_000_000, 0);
584 assert
!(set_file_times(&path
, atime
, new_mtime
).is_err());
588 fn set_symlink_file_times_test() {
589 let td
= Builder
::new().prefix("filetime").tempdir().unwrap();
590 let path
= td
.path().join("foo.txt");
591 File
::create(&path
).unwrap();
593 let metadata
= fs
::metadata(&path
).unwrap();
594 let mtime
= FileTime
::from_last_modification_time(&metadata
);
595 let atime
= FileTime
::from_last_access_time(&metadata
);
596 set_symlink_file_times(&path
, atime
, mtime
).unwrap();
598 let new_mtime
= FileTime
::from_unix_time(10_000, 0);
599 set_symlink_file_times(&path
, atime
, new_mtime
).unwrap();
601 let metadata
= fs
::metadata(&path
).unwrap();
602 let mtime
= FileTime
::from_last_modification_time(&metadata
);
603 assert_eq
!(mtime
, new_mtime
);
605 let spath
= td
.path().join("bar.txt");
606 make_symlink_file(&path
, &spath
).unwrap();
608 let metadata
= fs
::symlink_metadata(&spath
).unwrap();
609 let smtime
= FileTime
::from_last_modification_time(&metadata
);
610 let satime
= FileTime
::from_last_access_time(&metadata
);
611 set_symlink_file_times(&spath
, smtime
, satime
).unwrap();
613 let metadata
= fs
::metadata(&path
).unwrap();
614 let mtime
= FileTime
::from_last_modification_time(&metadata
);
615 assert_eq
!(mtime
, new_mtime
);
617 let new_smtime
= FileTime
::from_unix_time(20_000, 0);
618 set_symlink_file_times(&spath
, atime
, new_smtime
).unwrap();
620 let metadata
= fs
::metadata(&spath
).unwrap();
621 let mtime
= FileTime
::from_last_modification_time(&metadata
);
622 assert_eq
!(mtime
, new_mtime
);
624 let metadata
= fs
::symlink_metadata(&spath
).unwrap();
625 let mtime
= FileTime
::from_last_modification_time(&metadata
);
626 assert_eq
!(mtime
, new_smtime
);
630 fn set_symlink_dir_times_test() {
631 let td
= Builder
::new().prefix("filetime").tempdir().unwrap();
632 let path
= td
.path().join("foo");
633 fs
::create_dir(&path
).unwrap();
635 let metadata
= fs
::metadata(&path
).unwrap();
636 let mtime
= FileTime
::from_last_modification_time(&metadata
);
637 let atime
= FileTime
::from_last_access_time(&metadata
);
638 set_symlink_file_times(&path
, atime
, mtime
).unwrap();
640 let new_mtime
= FileTime
::from_unix_time(10_000, 0);
641 set_symlink_file_times(&path
, atime
, new_mtime
).unwrap();
643 let metadata
= fs
::metadata(&path
).unwrap();
644 let mtime
= FileTime
::from_last_modification_time(&metadata
);
645 assert_eq
!(mtime
, new_mtime
);
647 let spath
= td
.path().join("bar");
648 make_symlink_dir(&path
, &spath
).unwrap();
650 let metadata
= fs
::symlink_metadata(&spath
).unwrap();
651 let smtime
= FileTime
::from_last_modification_time(&metadata
);
652 let satime
= FileTime
::from_last_access_time(&metadata
);
653 set_symlink_file_times(&spath
, smtime
, satime
).unwrap();
655 let metadata
= fs
::metadata(&path
).unwrap();
656 let mtime
= FileTime
::from_last_modification_time(&metadata
);
657 assert_eq
!(mtime
, new_mtime
);
659 let new_smtime
= FileTime
::from_unix_time(20_000, 0);
660 set_symlink_file_times(&spath
, atime
, new_smtime
).unwrap();
662 let metadata
= fs
::metadata(&spath
).unwrap();
663 let mtime
= FileTime
::from_last_modification_time(&metadata
);
664 assert_eq
!(mtime
, new_mtime
);
666 let metadata
= fs
::symlink_metadata(&spath
).unwrap();
667 let mtime
= FileTime
::from_last_modification_time(&metadata
);
668 assert_eq
!(mtime
, new_smtime
);
672 fn set_single_time_test() {
673 use super::{set_file_atime, set_file_mtime}
;
675 let td
= Builder
::new().prefix("filetime").tempdir().unwrap();
676 let path
= td
.path().join("foo.txt");
677 File
::create(&path
).unwrap();
679 let metadata
= fs
::metadata(&path
).unwrap();
680 let mtime
= FileTime
::from_last_modification_time(&metadata
);
681 let atime
= FileTime
::from_last_access_time(&metadata
);
682 set_file_times(&path
, atime
, mtime
).unwrap();
684 let new_mtime
= FileTime
::from_unix_time(10_000, 0);
685 set_file_mtime(&path
, new_mtime
).unwrap();
687 let metadata
= fs
::metadata(&path
).unwrap();
688 let mtime
= FileTime
::from_last_modification_time(&metadata
);
689 assert_eq
!(mtime
, new_mtime
, "modification time should be updated");
692 FileTime
::from_last_access_time(&metadata
),
693 "access time should not be updated",
696 let new_atime
= FileTime
::from_unix_time(20_000, 0);
697 set_file_atime(&path
, new_atime
).unwrap();
699 let metadata
= fs
::metadata(&path
).unwrap();
700 let atime
= FileTime
::from_last_access_time(&metadata
);
701 assert_eq
!(atime
, new_atime
, "access time should be updated");
704 FileTime
::from_last_modification_time(&metadata
),
705 "modification time should not be updated"