diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index e9970cb2456..85eb97bc462 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -3,10 +3,13 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore (ToDO) filetime datetime lpszfilepath mktime DATETIME subsecond datelike timelike +// spell-checker:ignore (ToDO) filetime datetime lpszfilepath mktime DATETIME datelike timelike // spell-checker:ignore (FORMATS) MMDDhhmm YYYYMMDDHHMM YYMMDDHHMM YYYYMMDDHHMMS -use chrono::{DateTime, Datelike, Duration, Local, NaiveDate, NaiveTime, TimeZone, Timelike, Utc}; +use chrono::{ + DateTime, Datelike, Duration, Local, LocalResult, NaiveDate, NaiveDateTime, NaiveTime, + TimeZone, Timelike, +}; use clap::builder::ValueParser; use clap::{crate_version, Arg, ArgAction, ArgGroup, Command}; use filetime::{set_file_times, set_symlink_file_times, FileTime}; @@ -348,8 +351,8 @@ fn parse_date(s: &str) -> UResult { // Tue Dec 3 ... // ("%c", POSIX_LOCALE_FORMAT), // - if let Ok(parsed) = Local.datetime_from_str(s, format::POSIX_LOCALE) { - return Ok(datetime_to_filetime(&parsed)); + if let Ok(parsed) = NaiveDateTime::parse_from_str(s, format::POSIX_LOCALE) { + return Ok(datetime_to_filetime(&parsed.and_utc())); } // Also support other formats found in the GNU tests like @@ -361,8 +364,8 @@ fn parse_date(s: &str) -> UResult { format::YYYY_MM_DD_HH_MM, format::YYYYMMDDHHMM_OFFSET, ] { - if let Ok(parsed) = Utc.datetime_from_str(s, fmt) { - return Ok(datetime_to_filetime(&parsed)); + if let Ok(parsed) = NaiveDateTime::parse_from_str(s, fmt) { + return Ok(datetime_to_filetime(&parsed.and_utc())); } } @@ -411,9 +414,17 @@ fn parse_timestamp(s: &str) -> UResult { } }; - let mut local = chrono::Local - .datetime_from_str(&ts, format) + let local = NaiveDateTime::parse_from_str(&ts, format) .map_err(|_| USimpleError::new(1, format!("invalid date ts format {}", ts.quote())))?; + let mut local = match chrono::Local.from_local_datetime(&local) { + LocalResult::Single(dt) => dt, + _ => { + return Err(USimpleError::new( + 1, + format!("invalid date ts format {}", ts.quote()), + )) + } + }; // Chrono caps seconds at 59, but 60 is valid. It might be a leap second // or wrap to the next minute. But that doesn't really matter, because we diff --git a/tests/by-util/test_touch.rs b/tests/by-util/test_touch.rs index 942446a3383..c9c0d700e2a 100644 --- a/tests/by-util/test_touch.rs +++ b/tests/by-util/test_touch.rs @@ -5,7 +5,6 @@ // spell-checker:ignore (formats) cymdhm cymdhms mdhm mdhms ymdhm ymdhms datetime mktime use crate::common::util::{AtPath, TestScenario}; -use chrono::TimeZone; use filetime::{self, FileTime}; use std::fs::remove_file; use std::path::PathBuf; @@ -32,7 +31,7 @@ fn set_file_times(at: &AtPath, path: &str, atime: FileTime, mtime: FileTime) { } fn str_to_filetime(format: &str, s: &str) -> FileTime { - let tm = chrono::Utc.datetime_from_str(s, format).unwrap(); + let tm = chrono::NaiveDateTime::parse_from_str(s, format).unwrap(); FileTime::from_unix_time(tm.timestamp(), tm.timestamp_subsec_nanos()) }