mirror of
https://github.com/nushell/nushell.git
synced 2025-04-19 10:48:21 +02:00
Support default offset with dateformat option (#13289)
# Description Fixes #13280. After apply this patch, we can use non-timezone string + format option `into datetime` cmd # User-Facing Changes AS-IS (before fixing) ``` $ "09.02.2024 11:06:11" | into datetime --format '%m.%d.%Y %T' Error: nu:🐚:cant_convert × Can't convert to could not parse as datetime using format '%m.%d.%Y %T'. ╭─[entry #1:1:25] 1 │ "09.02.2024 11:06:11" | into datetime --format '%m.%d.%Y %T' · ──────┬────── · ╰── can't convert input is not enough for unique date and time to could not parse as datetime using format '%m.%d.%Y %T' ╰──── help: you can use `into datetime` without a format string to enable flexible parsing $ "09.02.2024 11:06:11" | into datetime Mon, 2 Sep 2024 11:06:11 +0900 (in 2 months) ``` TO-BE(After fixing) ``` $ "09.02.2024 11:06:11" | into datetime --format '%m.%d.%Y %T' Mon, 2 Sep 2024 20:06:11 +0900 (in 2 months) $ "09.02.2024 11:06:11" | into datetime Mon, 2 Sep 2024 11:06:11 +0900 (in 2 months) ``` # Tests + Formatting If there is agreement on the direction, I will add a test. # After Submitting --------- Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com>
This commit is contained in:
parent
3fae77209a
commit
d5e00c0d5d
@ -1,5 +1,5 @@
|
|||||||
use crate::{generate_strftime_list, parse_date_from_string};
|
use crate::{generate_strftime_list, parse_date_from_string};
|
||||||
use chrono::{DateTime, FixedOffset, Local, NaiveTime, TimeZone, Utc};
|
use chrono::{DateTime, FixedOffset, Local, NaiveDateTime, NaiveTime, TimeZone, Utc};
|
||||||
use human_date_parser::{from_human_time, ParseResult};
|
use human_date_parser::{from_human_time, ParseResult};
|
||||||
use nu_cmd_base::input_handler::{operate, CmdArgument};
|
use nu_cmd_base::input_handler::{operate, CmdArgument};
|
||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
@ -162,24 +162,37 @@ impl Command for SubCommand {
|
|||||||
};
|
};
|
||||||
vec![
|
vec![
|
||||||
Example {
|
Example {
|
||||||
description: "Convert any standard timestamp string to datetime",
|
description: "Convert timestamp string to datetime with timezone offset",
|
||||||
example: "'27.02.2021 1:55 pm +0000' | into datetime",
|
example: "'27.02.2021 1:55 pm +0000' | into datetime",
|
||||||
#[allow(clippy::inconsistent_digit_grouping)]
|
#[allow(clippy::inconsistent_digit_grouping)]
|
||||||
result: example_result_1(1614434100_000000000),
|
result: example_result_1(1614434100_000000000),
|
||||||
},
|
},
|
||||||
Example {
|
Example {
|
||||||
description: "Convert any standard timestamp string to datetime",
|
description: "Convert standard timestamp string to datetime with timezone offset",
|
||||||
example: "'2021-02-27T13:55:40.2246+00:00' | into datetime",
|
example: "'2021-02-27T13:55:40.2246+00:00' | into datetime",
|
||||||
#[allow(clippy::inconsistent_digit_grouping)]
|
#[allow(clippy::inconsistent_digit_grouping)]
|
||||||
result: example_result_1(1614434140_224600000),
|
result: example_result_1(1614434140_224600000),
|
||||||
},
|
},
|
||||||
Example {
|
Example {
|
||||||
description:
|
description:
|
||||||
"Convert non-standard timestamp string to datetime using a custom format",
|
"Convert non-standard timestamp string, with timezone offset, to datetime using a custom format",
|
||||||
example: "'20210227_135540+0000' | into datetime --format '%Y%m%d_%H%M%S%z'",
|
example: "'20210227_135540+0000' | into datetime --format '%Y%m%d_%H%M%S%z'",
|
||||||
#[allow(clippy::inconsistent_digit_grouping)]
|
#[allow(clippy::inconsistent_digit_grouping)]
|
||||||
result: example_result_1(1614434140_000000000),
|
result: example_result_1(1614434140_000000000),
|
||||||
},
|
},
|
||||||
|
Example {
|
||||||
|
description: "Convert non-standard timestamp string, without timezone offset, to datetime with custom formatting",
|
||||||
|
example: "'16.11.1984 8:00 am' | into datetime --format '%d.%m.%Y %H:%M %P'",
|
||||||
|
#[allow(clippy::inconsistent_digit_grouping)]
|
||||||
|
result: Some(Value::date(
|
||||||
|
DateTime::from_naive_utc_and_offset(
|
||||||
|
NaiveDateTime::parse_from_str("16.11.1984 8:00 am", "%d.%m.%Y %H:%M %P")
|
||||||
|
.expect("date calculation should not fail in test"),
|
||||||
|
*Local::now().offset(),
|
||||||
|
),
|
||||||
|
Span::test_data(),
|
||||||
|
)),
|
||||||
|
},
|
||||||
Example {
|
Example {
|
||||||
description:
|
description:
|
||||||
"Convert nanosecond-precision unix timestamp to a datetime with offset from UTC",
|
"Convert nanosecond-precision unix timestamp to a datetime with offset from UTC",
|
||||||
@ -372,10 +385,21 @@ fn action(input: &Value, args: &Arguments, head: Span) -> Value {
|
|||||||
Some(dt) => match DateTime::parse_from_str(val, &dt.0) {
|
Some(dt) => match DateTime::parse_from_str(val, &dt.0) {
|
||||||
Ok(d) => Value::date ( d, head ),
|
Ok(d) => Value::date ( d, head ),
|
||||||
Err(reason) => {
|
Err(reason) => {
|
||||||
Value::error (
|
match NaiveDateTime::parse_from_str(val, &dt.0) {
|
||||||
ShellError::CantConvert { to_type: format!("could not parse as datetime using format '{}'", dt.0), from_type: reason.to_string(), span: head, help: Some("you can use `into datetime` without a format string to enable flexible parsing".to_string()) },
|
Ok(d) => Value::date (
|
||||||
head,
|
DateTime::from_naive_utc_and_offset(
|
||||||
)
|
d,
|
||||||
|
*Local::now().offset(),
|
||||||
|
),
|
||||||
|
head,
|
||||||
|
),
|
||||||
|
Err(_) => {
|
||||||
|
Value::error (
|
||||||
|
ShellError::CantConvert { to_type: format!("could not parse as datetime using format '{}'", dt.0), from_type: reason.to_string(), span: head, help: Some("you can use `into datetime` without a format string to enable flexible parsing".to_string()) },
|
||||||
|
head,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -457,7 +481,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn takes_a_date_format() {
|
fn takes_a_date_format_with_timezone() {
|
||||||
let date_str = Value::test_string("16.11.1984 8:00 am +0000");
|
let date_str = Value::test_string("16.11.1984 8:00 am +0000");
|
||||||
let fmt_options = Some(DatetimeFormat("%d.%m.%Y %H:%M %P %z".to_string()));
|
let fmt_options = Some(DatetimeFormat("%d.%m.%Y %H:%M %P %z".to_string()));
|
||||||
let args = Arguments {
|
let args = Arguments {
|
||||||
@ -473,6 +497,26 @@ mod tests {
|
|||||||
assert_eq!(actual, expected)
|
assert_eq!(actual, expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn takes_a_date_format_without_timezone() {
|
||||||
|
let date_str = Value::test_string("16.11.1984 8:00 am");
|
||||||
|
let fmt_options = Some(DatetimeFormat("%d.%m.%Y %H:%M %P".to_string()));
|
||||||
|
let args = Arguments {
|
||||||
|
zone_options: None,
|
||||||
|
format_options: fmt_options,
|
||||||
|
cell_paths: None,
|
||||||
|
};
|
||||||
|
let actual = action(&date_str, &args, Span::test_data());
|
||||||
|
let expected = Value::date(
|
||||||
|
DateTime::from_naive_utc_and_offset(
|
||||||
|
NaiveDateTime::parse_from_str("16.11.1984 8:00 am", "%d.%m.%Y %H:%M %P").unwrap(),
|
||||||
|
*Local::now().offset(),
|
||||||
|
),
|
||||||
|
Span::test_data(),
|
||||||
|
);
|
||||||
|
assert_eq!(actual, expected)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn takes_iso8601_date_format() {
|
fn takes_iso8601_date_format() {
|
||||||
let date_str = Value::test_string("2020-08-04T16:39:18+00:00");
|
let date_str = Value::test_string("2020-08-04T16:39:18+00:00");
|
||||||
|
Loading…
Reference in New Issue
Block a user