mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 23:58:06 +02:00
Date parse refactor (#4661)
* More flexible and DRY datetime parsing * Update error messages * cargo fmt * clippy * Add DatetimeParseError
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
use chrono::{DateTime, FixedOffset, Local, LocalResult, Offset, TimeZone, Utc};
|
||||
use chrono::{DateTime, FixedOffset, Local, TimeZone, Utc};
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::ast::CellPath;
|
||||
@ -8,6 +8,7 @@ use nu_protocol::{
|
||||
};
|
||||
|
||||
use crate::generate_strftime_list;
|
||||
use crate::parse_date_from_string;
|
||||
|
||||
struct Arguments {
|
||||
timezone: Option<Spanned<String>>,
|
||||
@ -205,7 +206,7 @@ fn action(
|
||||
head: Span,
|
||||
) -> Value {
|
||||
match input {
|
||||
Value::String { val: s, span, .. } => {
|
||||
Value::String { val: s, span } => {
|
||||
let ts = s.parse::<i64>();
|
||||
// if timezone if specified, first check if the input is a timestamp.
|
||||
if let Some(tz) = timezone {
|
||||
@ -253,7 +254,7 @@ fn action(
|
||||
return stampout;
|
||||
}
|
||||
};
|
||||
// if it's not, continue and negelect the timezone option.
|
||||
// if it's not, continue and default to the system's local timezone.
|
||||
let out = match dateformat {
|
||||
Some(dt) => match DateTime::parse_from_str(s, &dt.0) {
|
||||
Ok(d) => Value::Date { val: d, span: head },
|
||||
@ -267,35 +268,15 @@ fn action(
|
||||
}
|
||||
}
|
||||
},
|
||||
None => match dtparse::parse(s) {
|
||||
Ok((native_dt, fixed_offset)) => {
|
||||
let offset = match fixed_offset {
|
||||
Some(fo) => fo,
|
||||
None => FixedOffset::east(0).fix(),
|
||||
};
|
||||
match offset.from_local_datetime(&native_dt) {
|
||||
LocalResult::Single(d) => Value::Date { val: d, span: head },
|
||||
LocalResult::Ambiguous(d, _) => Value::Date { val: d, span: head },
|
||||
LocalResult::None => {
|
||||
return Value::Error {
|
||||
error: ShellError::CantConvert(
|
||||
"could not convert to a timezone-aware datetime"
|
||||
.to_string(),
|
||||
"local time representation is invalid".to_string(),
|
||||
head,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
return Value::Error {
|
||||
error: ShellError::UnsupportedInput(
|
||||
"Cannot convert input string as datetime. Might be missing timezone or offset".to_string(),
|
||||
*span,
|
||||
),
|
||||
}
|
||||
}
|
||||
// Tries to automatically parse the date
|
||||
// (i.e. without a format string)
|
||||
// and assumes the system's local timezone if none is specified
|
||||
None => match parse_date_from_string(s, *span) {
|
||||
Ok(date) => Value::Date {
|
||||
val: date,
|
||||
span: *span,
|
||||
},
|
||||
Err(err) => err,
|
||||
},
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user