mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-30 04:27:45 +00:00
touch: add support of -d '1970-01-01 18:43:33.023456789'
This commit is contained in:
parent
31c28eeaa9
commit
9d81d6fef2
3 changed files with 84 additions and 28 deletions
|
@ -64,7 +64,7 @@ highlight = "all"
|
||||||
# spell-checker: disable
|
# spell-checker: disable
|
||||||
skip = [
|
skip = [
|
||||||
# getrandom
|
# getrandom
|
||||||
{ name = "wasi", version="0.10.2+wasi-snapshot-preview1" },
|
{ name = "wasi", version="0.10.0+wasi-snapshot-preview1" },
|
||||||
# blake2d_simd
|
# blake2d_simd
|
||||||
{ name = "arrayvec", version = "=0.7.2" },
|
{ name = "arrayvec", version = "=0.7.2" },
|
||||||
# flimit/unix_socket
|
# flimit/unix_socket
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
// For the full copyright and license information, please view the LICENSE file
|
// For the full copyright and license information, please view the LICENSE file
|
||||||
// that was distributed with this source code.
|
// that was distributed with this source code.
|
||||||
|
|
||||||
// spell-checker:ignore (ToDO) filetime strptime utcoff strs datetime MMDDhhmm clapv PWSTR lpszfilepath hresult mktime YYYYMMDDHHMM YYMMDDHHMM DATETIME subsecond
|
// spell-checker:ignore (ToDO) filetime strptime utcoff strs datetime MMDDhhmm clapv PWSTR lpszfilepath hresult mktime YYYYMMDDHHMM YYMMDDHHMM DATETIME YYYYMMDDHHMMS
|
||||||
pub extern crate filetime;
|
pub extern crate filetime;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -255,6 +255,41 @@ const POSIX_LOCALE_FORMAT: &[time::format_description::FormatItem] = format_desc
|
||||||
const ISO_8601_FORMAT: &[time::format_description::FormatItem] =
|
const ISO_8601_FORMAT: &[time::format_description::FormatItem] =
|
||||||
format_description!("[year]-[month]-[day]");
|
format_description!("[year]-[month]-[day]");
|
||||||
|
|
||||||
|
// "%Y%m%d%H%M.%S" 15 chars
|
||||||
|
const YYYYMMDDHHMM_DOT_SS_FORMAT: &[time::format_description::FormatItem] = format_description!(
|
||||||
|
"[year repr:full][month repr:numerical padding:zero]\
|
||||||
|
[day][hour][minute].[second]"
|
||||||
|
);
|
||||||
|
|
||||||
|
// "%Y-%m-%d %H:%M:%S.%SS" 12 chars
|
||||||
|
const YYYYMMDDHHMMSS_FORMAT: &[time::format_description::FormatItem] = format_description!(
|
||||||
|
"[year repr:full]-[month repr:numerical padding:zero]-\
|
||||||
|
[day] [hour]:[minute]:[second].[subsecond]"
|
||||||
|
);
|
||||||
|
// "%Y-%m-%d %H:%M:%S" 12 chars
|
||||||
|
const YYYYMMDDHHMMS_FORMAT: &[time::format_description::FormatItem] = format_description!(
|
||||||
|
"[year repr:full]-[month repr:numerical padding:zero]-\
|
||||||
|
[day] [hour]:[minute]:[second]"
|
||||||
|
);
|
||||||
|
|
||||||
|
// "%Y%m%d%H%M" 12 chars
|
||||||
|
const YYYYMMDDHHMM_FORMAT: &[time::format_description::FormatItem] = format_description!(
|
||||||
|
"[year repr:full][month repr:numerical padding:zero]\
|
||||||
|
[day][hour][minute]"
|
||||||
|
);
|
||||||
|
|
||||||
|
// "%y%m%d%H%M.%S" 13 chars
|
||||||
|
const YYMMDDHHMM_DOT_SS_FORMAT: &[time::format_description::FormatItem] = format_description!(
|
||||||
|
"[year repr:last_two padding:none][month][day]\
|
||||||
|
[hour][minute].[second]"
|
||||||
|
);
|
||||||
|
|
||||||
|
// "%y%m%d%H%M" 10 chars
|
||||||
|
const YYMMDDHHMM_FORMAT: &[time::format_description::FormatItem] = format_description!(
|
||||||
|
"[year repr:last_two padding:none][month padding:zero][day padding:zero]\
|
||||||
|
[hour repr:24 padding:zero][minute padding:zero]"
|
||||||
|
);
|
||||||
|
|
||||||
fn parse_date(s: &str) -> UResult<FileTime> {
|
fn parse_date(s: &str) -> UResult<FileTime> {
|
||||||
// This isn't actually compatible with GNU touch, but there doesn't seem to
|
// This isn't actually compatible with GNU touch, but there doesn't seem to
|
||||||
// be any simple specification for what format this parameter allows and I'm
|
// be any simple specification for what format this parameter allows and I'm
|
||||||
|
@ -269,8 +304,17 @@ fn parse_date(s: &str) -> UResult<FileTime> {
|
||||||
// which is equivalent to the POSIX locale: %a %b %e %H:%M:%S %Y
|
// which is equivalent to the POSIX locale: %a %b %e %H:%M:%S %Y
|
||||||
// Tue Dec 3 ...
|
// Tue Dec 3 ...
|
||||||
// ("%c", POSIX_LOCALE_FORMAT),
|
// ("%c", POSIX_LOCALE_FORMAT),
|
||||||
if let Ok(parsed) = time::PrimitiveDateTime::parse(s, &POSIX_LOCALE_FORMAT) {
|
//
|
||||||
return Ok(local_dt_to_filetime(to_local(parsed)));
|
// But also support other format found in the GNU tests like
|
||||||
|
// in tests/misc/stat-nanoseconds.sh
|
||||||
|
for fmt in [
|
||||||
|
POSIX_LOCALE_FORMAT,
|
||||||
|
YYYYMMDDHHMMS_FORMAT,
|
||||||
|
YYYYMMDDHHMMSS_FORMAT,
|
||||||
|
] {
|
||||||
|
if let Ok(parsed) = time::PrimitiveDateTime::parse(s, &fmt) {
|
||||||
|
return Ok(local_dt_to_filetime(to_local(parsed)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// "Equivalent to %Y-%m-%d (the ISO 8601 date format). (C99)"
|
// "Equivalent to %Y-%m-%d (the ISO 8601 date format). (C99)"
|
||||||
|
@ -294,30 +338,6 @@ fn parse_date(s: &str) -> UResult<FileTime> {
|
||||||
Err(USimpleError::new(1, format!("Unable to parse date: {}", s)))
|
Err(USimpleError::new(1, format!("Unable to parse date: {}", s)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// "%Y%m%d%H%M.%S" 15 chars
|
|
||||||
const YYYYMMDDHHMM_DOT_SS_FORMAT: &[time::format_description::FormatItem] = format_description!(
|
|
||||||
"[year repr:full][month repr:numerical padding:zero]\
|
|
||||||
[day][hour][minute].[second]"
|
|
||||||
);
|
|
||||||
|
|
||||||
// "%Y%m%d%H%M" 12 chars
|
|
||||||
const YYYYMMDDHHMM_FORMAT: &[time::format_description::FormatItem] = format_description!(
|
|
||||||
"[year repr:full][month repr:numerical padding:zero]\
|
|
||||||
[day][hour][minute]"
|
|
||||||
);
|
|
||||||
|
|
||||||
// "%y%m%d%H%M.%S" 13 chars
|
|
||||||
const YYMMDDHHMM_DOT_SS_FORMAT: &[time::format_description::FormatItem] = format_description!(
|
|
||||||
"[year repr:last_two padding:none][month][day]\
|
|
||||||
[hour][minute].[second]"
|
|
||||||
);
|
|
||||||
|
|
||||||
// "%y%m%d%H%M" 10 chars
|
|
||||||
const YYMMDDHHMM_FORMAT: &[time::format_description::FormatItem] = format_description!(
|
|
||||||
"[year repr:last_two padding:none][month padding:zero][day padding:zero]\
|
|
||||||
[hour repr:24 padding:zero][minute padding:zero]"
|
|
||||||
);
|
|
||||||
|
|
||||||
fn parse_timestamp(s: &str) -> UResult<FileTime> {
|
fn parse_timestamp(s: &str) -> UResult<FileTime> {
|
||||||
// TODO: handle error
|
// TODO: handle error
|
||||||
let now = time::OffsetDateTime::now_utc();
|
let now = time::OffsetDateTime::now_utc();
|
||||||
|
|
|
@ -427,6 +427,42 @@ fn test_touch_set_date3() {
|
||||||
assert_eq!(mtime, expected);
|
assert_eq!(mtime, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_touch_set_date4() {
|
||||||
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
let file = "test_touch_set_date";
|
||||||
|
|
||||||
|
ucmd.args(&["-d", "1970-01-01 18:43:33", file])
|
||||||
|
.succeeds()
|
||||||
|
.no_stderr();
|
||||||
|
|
||||||
|
assert!(at.file_exists(file));
|
||||||
|
|
||||||
|
let expected = FileTime::from_unix_time(60213, 0);
|
||||||
|
let (atime, mtime) = get_file_times(&at, file);
|
||||||
|
assert_eq!(atime, mtime);
|
||||||
|
assert_eq!(atime, expected);
|
||||||
|
assert_eq!(mtime, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_touch_set_date5() {
|
||||||
|
let (at, mut ucmd) = at_and_ucmd!();
|
||||||
|
let file = "test_touch_set_date";
|
||||||
|
|
||||||
|
ucmd.args(&["-d", "1970-01-01 18:43:33.023456789", file])
|
||||||
|
.succeeds()
|
||||||
|
.no_stderr();
|
||||||
|
|
||||||
|
assert!(at.file_exists(file));
|
||||||
|
|
||||||
|
let expected = FileTime::from_unix_time(60213, 023456789);
|
||||||
|
let (atime, mtime) = get_file_times(&at, file);
|
||||||
|
assert_eq!(atime, mtime);
|
||||||
|
assert_eq!(atime, expected);
|
||||||
|
assert_eq!(mtime, expected);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_touch_set_date_wrong_format() {
|
fn test_touch_set_date_wrong_format() {
|
||||||
let (_at, mut ucmd) = at_and_ucmd!();
|
let (_at, mut ucmd) = at_and_ucmd!();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue