mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 19:47:45 +00:00
touch: improve the -d option support of other dates
This commit is contained in:
parent
65d0f5ba9f
commit
06ef89b3d8
2 changed files with 25 additions and 10 deletions
|
@ -16,7 +16,7 @@ use clap::{crate_version, Arg, ArgGroup, Command};
|
||||||
use filetime::*;
|
use filetime::*;
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use time::macros::{format_description, time};
|
use time::macros::{format_description, offset, time};
|
||||||
use time::Duration;
|
use time::Duration;
|
||||||
use uucore::display::Quotable;
|
use uucore::display::Quotable;
|
||||||
use uucore::error::{FromIo, UError, UResult, USimpleError};
|
use uucore::error::{FromIo, UError, UResult, USimpleError};
|
||||||
|
@ -42,6 +42,7 @@ pub mod options {
|
||||||
|
|
||||||
static ARG_FILES: &str = "files";
|
static ARG_FILES: &str = "files";
|
||||||
|
|
||||||
|
// Convert a date/time to a date with a TZ offset
|
||||||
fn to_local(tm: time::PrimitiveDateTime) -> time::OffsetDateTime {
|
fn to_local(tm: time::PrimitiveDateTime) -> time::OffsetDateTime {
|
||||||
let offset = match time::OffsetDateTime::now_local() {
|
let offset = match time::OffsetDateTime::now_local() {
|
||||||
Ok(lo) => lo.offset(),
|
Ok(lo) => lo.offset(),
|
||||||
|
@ -52,10 +53,18 @@ fn to_local(tm: time::PrimitiveDateTime) -> time::OffsetDateTime {
|
||||||
tm.assume_offset(offset)
|
tm.assume_offset(offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert a date/time with a TZ offset into a FileTime
|
||||||
fn local_dt_to_filetime(dt: time::OffsetDateTime) -> FileTime {
|
fn local_dt_to_filetime(dt: time::OffsetDateTime) -> FileTime {
|
||||||
FileTime::from_unix_time(dt.unix_timestamp(), dt.nanosecond())
|
FileTime::from_unix_time(dt.unix_timestamp(), dt.nanosecond())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert a date/time, considering that the input is in UTC time
|
||||||
|
// Used for touch -d 1970-01-01 18:43:33.023456789 for example
|
||||||
|
fn dt_to_filename(tm: time::PrimitiveDateTime) -> FileTime {
|
||||||
|
let dt = tm.assume_offset(offset!(UTC));
|
||||||
|
local_dt_to_filetime(dt)
|
||||||
|
}
|
||||||
|
|
||||||
#[uucore::main]
|
#[uucore::main]
|
||||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
let matches = uu_app().get_matches_from(args);
|
let matches = uu_app().get_matches_from(args);
|
||||||
|
@ -310,15 +319,15 @@ fn parse_date(s: &str) -> UResult<FileTime> {
|
||||||
// Tue Dec 3 ...
|
// Tue Dec 3 ...
|
||||||
// ("%c", POSIX_LOCALE_FORMAT),
|
// ("%c", POSIX_LOCALE_FORMAT),
|
||||||
//
|
//
|
||||||
// But also support other format found in the GNU tests like
|
if let Ok(parsed) = time::PrimitiveDateTime::parse(s, &POSIX_LOCALE_FORMAT) {
|
||||||
|
return Ok(local_dt_to_filetime(to_local(parsed)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also support other formats found in the GNU tests like
|
||||||
// in tests/misc/stat-nanoseconds.sh
|
// in tests/misc/stat-nanoseconds.sh
|
||||||
for fmt in [
|
for fmt in [YYYYMMDDHHMMS_FORMAT, YYYYMMDDHHMMSS_FORMAT] {
|
||||||
POSIX_LOCALE_FORMAT,
|
|
||||||
YYYYMMDDHHMMS_FORMAT,
|
|
||||||
YYYYMMDDHHMMSS_FORMAT,
|
|
||||||
] {
|
|
||||||
if let Ok(parsed) = time::PrimitiveDateTime::parse(s, &fmt) {
|
if let Ok(parsed) = time::PrimitiveDateTime::parse(s, &fmt) {
|
||||||
return Ok(local_dt_to_filetime(to_local(parsed)));
|
return Ok(dt_to_filename(parsed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -438,7 +438,7 @@ fn test_touch_set_date4() {
|
||||||
|
|
||||||
assert!(at.file_exists(file));
|
assert!(at.file_exists(file));
|
||||||
|
|
||||||
let expected = FileTime::from_unix_time(60213, 0);
|
let expected = FileTime::from_unix_time(67413, 0);
|
||||||
let (atime, mtime) = get_file_times(&at, file);
|
let (atime, mtime) = get_file_times(&at, file);
|
||||||
assert_eq!(atime, mtime);
|
assert_eq!(atime, mtime);
|
||||||
assert_eq!(atime, expected);
|
assert_eq!(atime, expected);
|
||||||
|
@ -456,7 +456,13 @@ fn test_touch_set_date5() {
|
||||||
|
|
||||||
assert!(at.file_exists(file));
|
assert!(at.file_exists(file));
|
||||||
|
|
||||||
let expected = FileTime::from_unix_time(60213, 023456789);
|
// Slightly different result on Windows for nano seconds
|
||||||
|
// TODO: investigate
|
||||||
|
#[cfg(windows)]
|
||||||
|
let expected = FileTime::from_unix_time(67413, 23456700);
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
let expected = FileTime::from_unix_time(67413, 23456789);
|
||||||
|
|
||||||
let (atime, mtime) = get_file_times(&at, file);
|
let (atime, mtime) = get_file_times(&at, file);
|
||||||
assert_eq!(atime, mtime);
|
assert_eq!(atime, mtime);
|
||||||
assert_eq!(atime, expected);
|
assert_eq!(atime, expected);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue