fix date format (#5619)

This commit is contained in:
WindSoilder 2022-05-24 00:59:34 +08:00 committed by GitHub
parent a8db4f0b0e
commit ef322a24c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 22 deletions

View file

@ -1,10 +1,13 @@
use chrono::Local;
use chrono::{DateTime, TimeZone};
use nu_engine::CallExt;
use nu_protocol::{
ast::Call,
engine::{Command, EngineState, Stack},
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value,
};
use std::fmt::{Display, Write};
use super::utils::parse_date_from_string;
@ -50,11 +53,11 @@ impl Command for SubCommand {
));
}
let format = call.opt::<String>(engine_state, stack, 0)?;
let format = call.opt::<Spanned<String>>(engine_state, stack, 0)?;
input.map(
move |value| match &format {
Some(format) => format_helper(value, format.as_str(), head),
Some(format) => format_helper(value, format.item.as_str(), format.span, head),
None => format_helper_rfc2822(value, head),
},
engine_state.ctrlc.clone(),
@ -90,34 +93,41 @@ impl Command for SubCommand {
}
}
fn format_helper(value: Value, formatter: &str, span: Span) -> Value {
match value {
Value::Date { val, span: _ } => Value::String {
val: val.format(formatter).to_string(),
fn format_from<Tz: TimeZone>(date_time: DateTime<Tz>, formatter: &str, span: Span) -> Value
where
Tz::Offset: Display,
{
let mut formatter_buf = String::new();
let format = date_time.format(formatter);
match formatter_buf.write_fmt(format_args!("{}", format)) {
Ok(_) => Value::String {
val: formatter_buf,
span,
},
Value::String {
val,
span: val_span,
} => {
let dt = parse_date_from_string(&val, val_span);
Err(_) => Value::Error {
error: ShellError::UnsupportedInput("invalid format".to_string(), span),
},
}
}
fn format_helper(value: Value, formatter: &str, formatter_span: Span, head_span: Span) -> Value {
match value {
Value::Date { val, .. } => format_from(val, formatter, formatter_span),
Value::String { val, .. } => {
let dt = parse_date_from_string(&val, formatter_span);
match dt {
Ok(x) => Value::String {
val: x.format(formatter).to_string(),
span,
},
Ok(x) => format_from(x, formatter, formatter_span),
Err(e) => e,
}
}
Value::Nothing { span: _ } => {
Value::Nothing { .. } => {
let dt = Local::now();
Value::String {
val: dt.with_timezone(dt.offset()).format(formatter).to_string(),
span,
}
format_from(dt, formatter, formatter_span)
}
_ => Value::Error {
error: ShellError::DatetimeParseError(span),
error: ShellError::DatetimeParseError(head_span),
},
}
}

View file

@ -0,0 +1,14 @@
use nu_test_support::{nu, pipeline};
#[test]
fn formatter_not_valid() {
let actual = nu!(
cwd: ".", pipeline(
r#"
date format '%N'
"#
)
);
assert!(actual.err.contains("invalid format"));
}

View file

@ -0,0 +1 @@
mod format;

View file

@ -6,6 +6,7 @@ mod cal;
mod cd;
mod compact;
mod cp;
mod date;
mod def;
mod default;
mod drop;