Skip to content

Commit

Permalink
Format negative datetimes with rfc3339 (nushell#9501) (nushell#9502)
Browse files Browse the repository at this point in the history
- fixes nushell#9501 

# Description

`chrono::Datetime::to_rfc2822()` panics when it would format a negative
year. 3339 does not. This makes negative-year datetimes inconsistent
compared to positive ones, but it's better than a panic.
  • Loading branch information
Taylor C. Richberger committed Jun 25, 2023
1 parent 971f9ae commit 08449e1
Showing 1 changed file with 52 additions and 2 deletions.
54 changes: 52 additions & 2 deletions crates/nu-protocol/src/value/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ use crate::ast::{Math, Operator};
use crate::engine::EngineState;
use crate::ShellError;
use crate::{did_you_mean, BlockId, Config, Span, Spanned, Type, VarId};

use byte_unit::ByteUnit;
use chrono::{DateTime, Duration, FixedOffset, Locale, TimeZone};
use chrono::{DateTime, Datelike, Duration, FixedOffset, Locale, TimeZone};
use chrono_humanize::HumanTime;
pub use custom_value::CustomValue;
use fancy_regex::Regex;
Expand Down Expand Up @@ -536,10 +537,19 @@ impl Value {
Value::Float { val, .. } => val.to_string(),
Value::Filesize { val, .. } => format_filesize_from_conf(*val, config),
Value::Duration { val, .. } => format_duration(*val),

Value::Date { val, .. } => match &config.datetime_normal_format {
Some(format) => self.format_datetime(val, format),
None => {
format!("{} ({})", val.to_rfc2822(), HumanTime::from(*val))
format!(
"{} ({})",
if val.year() >= 0 {
val.to_rfc2822()
} else {
val.to_rfc3339()
},
HumanTime::from(*val),
)
}
},
Value::Range { val, .. } => {
Expand Down Expand Up @@ -3889,4 +3899,44 @@ mod tests {
);
}
}

mod into_string {
use chrono::{DateTime, FixedOffset, NaiveDateTime};

use super::*;

#[test]
fn test_datetime() {
let string = Value::Date {
val: DateTime::from_utc(
NaiveDateTime::from_timestamp_millis(-123456789).unwrap(),
FixedOffset::east_opt(0).unwrap(),
),
span: Span::unknown(),
}
.into_string("", &Default::default());

// We need to cut the humanized part off for tests to work, because
// it is relative to current time.
let formatted = string.split("(").next().unwrap();
assert_eq!("Tue, 30 Dec 1969 13:42:23 +0000 ", formatted);
}

#[test]
fn test_negative_year_datetime() {
let string = Value::Date {
val: DateTime::from_utc(
NaiveDateTime::from_timestamp_millis(-72135596800000).unwrap(),
FixedOffset::east_opt(0).unwrap(),
),
span: Span::unknown(),
}
.into_string("", &Default::default());

// We need to cut the humanized part off for tests to work, because
// it is relative to current time.
let formatted = string.split(" ").next().unwrap();
assert_eq!("-0316-02-11T06:13:20+00:00", formatted);
}
}
}

0 comments on commit 08449e1

Please sign in to comment.