mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
date: consolidate date parsing logic
Removed the `parse_offset` function and rely on `parse_date` only.
This commit is contained in:
+11
-43
@@ -8,7 +8,7 @@
|
||||
use clap::{Arg, ArgAction, Command};
|
||||
use jiff::fmt::strtime;
|
||||
use jiff::tz::TimeZone;
|
||||
use jiff::{SignedDuration, Timestamp, Zoned};
|
||||
use jiff::{Timestamp, Zoned};
|
||||
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "redox")))]
|
||||
use libc::{CLOCK_REALTIME, clock_settime, timespec};
|
||||
use std::fs::File;
|
||||
@@ -64,10 +64,9 @@ enum Format {
|
||||
/// Various places that dates can come from
|
||||
enum DateSource {
|
||||
Now,
|
||||
Custom(String),
|
||||
File(PathBuf),
|
||||
Stdin,
|
||||
Human(SignedDuration),
|
||||
Human(String),
|
||||
}
|
||||
|
||||
enum Iso8601Format {
|
||||
@@ -141,11 +140,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
};
|
||||
|
||||
let date_source = if let Some(date) = matches.get_one::<String>(OPT_DATE) {
|
||||
if let Ok(duration) = parse_offset(date.as_str()) {
|
||||
DateSource::Human(duration)
|
||||
} else {
|
||||
DateSource::Custom(date.into())
|
||||
}
|
||||
DateSource::Human(date.into())
|
||||
} else if let Some(file) = matches.get_one::<String>(OPT_FILE) {
|
||||
match file.as_ref() {
|
||||
"-" => DateSource::Stdin,
|
||||
@@ -176,7 +171,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
if let Some(date) = settings.set_to {
|
||||
// All set time functions expect UTC datetimes.
|
||||
let date = if settings.utc {
|
||||
date.with_time_zone(TimeZone::UTC)
|
||||
date.datetime().to_zoned(TimeZone::UTC).map_err(|e| {
|
||||
USimpleError::new(1, translate!("date-error-invalid-date", "error" => e))
|
||||
})?
|
||||
} else {
|
||||
date
|
||||
};
|
||||
@@ -193,27 +190,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
|
||||
// Iterate over all dates - whether it's a single date or a file.
|
||||
let dates: Box<dyn Iterator<Item = _>> = match settings.date_source {
|
||||
DateSource::Custom(ref input) => {
|
||||
DateSource::Human(ref input) => {
|
||||
let date = parse_date(input);
|
||||
let iter = std::iter::once(date);
|
||||
Box::new(iter)
|
||||
}
|
||||
DateSource::Human(relative_time) => {
|
||||
// Double check the result is overflow or not of the current_time + relative_time
|
||||
// it may cause a panic of chrono::datetime::DateTime add
|
||||
match now.checked_add(relative_time) {
|
||||
Ok(date) => {
|
||||
let iter = std::iter::once(Ok(date));
|
||||
Box::new(iter)
|
||||
}
|
||||
Err(_) => {
|
||||
return Err(USimpleError::new(
|
||||
1,
|
||||
translate!("date-error-date-overflow", "date" => relative_time),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
DateSource::Stdin => {
|
||||
let lines = BufReader::new(std::io::stdin()).lines();
|
||||
let iter = lines.map_while(Result::ok).map(parse_date);
|
||||
@@ -391,28 +372,15 @@ fn parse_date<S: AsRef<str> + Clone>(
|
||||
Ok(date) => {
|
||||
let timestamp =
|
||||
Timestamp::new(date.timestamp(), date.timestamp_subsec_nanos() as i32).unwrap();
|
||||
Ok(Zoned::new(timestamp, TimeZone::UTC))
|
||||
Ok(Zoned::new(
|
||||
timestamp,
|
||||
TimeZone::try_system().unwrap_or(TimeZone::UTC),
|
||||
))
|
||||
}
|
||||
Err(e) => Err((s.as_ref().into(), e)),
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Convert `parse_datetime` to jiff and remove wrapper from chrono to jiff structures.
|
||||
// Also, consider whether parse_datetime::parse_datetime_at_date can be renamed to something
|
||||
// like parse_datetime::parse_offset, instead of doing some addition/subtraction.
|
||||
fn parse_offset(date: &str) -> Result<SignedDuration, ()> {
|
||||
let ref_time = chrono::Local::now();
|
||||
if let Ok(new_time) = parse_datetime::parse_datetime_at_date(ref_time, date) {
|
||||
let duration = new_time.signed_duration_since(ref_time);
|
||||
Ok(SignedDuration::new(
|
||||
duration.num_seconds(),
|
||||
duration.subsec_nanos(),
|
||||
))
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(unix, windows)))]
|
||||
fn set_system_datetime(_date: Zoned) -> UResult<()> {
|
||||
unimplemented!("setting date not implemented (unsupported target)");
|
||||
|
||||
Reference in New Issue
Block a user