diff --git a/crates/nu-command/src/strings/format/date.rs b/crates/nu-command/src/strings/format/date.rs index fd398753d7..658823aa6a 100644 --- a/crates/nu-command/src/strings/format/date.rs +++ b/crates/nu-command/src/strings/format/date.rs @@ -88,7 +88,25 @@ impl Command for FormatDate { ) -> Result { let list = call.has_flag(engine_state, stack, "list")?; let format = call.opt::>(engine_state, stack, 0)?; - run(engine_state, call, input, list, format) + + // get the locale first so we can use the proper get_env_var functions since this is a const command + // we can override the locale by setting $env.NU_TEST_LOCALE_OVERRIDE or $env.LC_TIME + let locale = if let Some(loc) = engine_state + .get_env_var(LOCALE_OVERRIDE_ENV_VAR) + .or_else(|| engine_state.get_env_var("LC_TIME")) + { + let locale_str = loc.as_str()?.split('.').next().unwrap_or("en_US"); + locale_str.try_into().unwrap_or(Locale::en_US) + } else { + get_system_locale_string() + .map(|l| l.replace('-', "_")) + .unwrap_or_else(|| String::from("en_US")) + .as_str() + .try_into() + .unwrap_or(Locale::en_US) + }; + + run(engine_state, call, input, list, format, locale) } fn run_const( @@ -99,7 +117,25 @@ impl Command for FormatDate { ) -> Result { let list = call.has_flag_const(working_set, "list")?; let format = call.opt_const::>(working_set, 0)?; - run(working_set.permanent(), call, input, list, format) + + // get the locale first so we can use the proper get_env_var functions since this is a const command + // we can override the locale by setting $env.NU_TEST_LOCALE_OVERRIDE or $env.LC_TIME + let locale = if let Some(loc) = working_set + .get_env_var(LOCALE_OVERRIDE_ENV_VAR) + .or_else(|| working_set.get_env_var("LC_TIME")) + { + let locale_str = loc.as_str()?.split('.').next().unwrap_or("en_US"); + locale_str.try_into().unwrap_or(Locale::en_US) + } else { + get_system_locale_string() + .map(|l| l.replace('-', "_")) + .unwrap_or_else(|| String::from("en_US")) + .as_str() + .try_into() + .unwrap_or(Locale::en_US) + }; + + run(working_set.permanent(), call, input, list, format, locale) } } @@ -109,6 +145,7 @@ fn run( input: PipelineData, list: bool, format: Option>, + locale: Locale, ) -> Result { let head = call.head; if list { @@ -124,34 +161,23 @@ fn run( } input.map( move |value| match &format { - Some(format) => format_helper(value, format.item.as_str(), format.span, head), + Some(format) => format_helper(value, format.item.as_str(), format.span, head, locale), None => format_helper_rfc2822(value, head), }, engine_state.signals(), ) } -fn format_from(date_time: DateTime, formatter: &str, span: Span) -> Value +fn format_from( + date_time: DateTime, + formatter: &str, + span: Span, + locale: Locale, +) -> Value where Tz::Offset: Display, { let mut formatter_buf = String::new(); - // Format using locale LC_TIME - let locale = if let Ok(l) = - std::env::var(LOCALE_OVERRIDE_ENV_VAR).or_else(|_| std::env::var("LC_TIME")) - { - let locale_str = l.split('.').next().unwrap_or("en_US"); - locale_str.try_into().unwrap_or(Locale::en_US) - } else { - // LC_ALL > LC_CTYPE > LANG - // Not locale present, default to en_US - get_system_locale_string() - .map(|l| l.replace('-', "_")) // `chrono::Locale` needs something like `xx_xx`, rather than `xx-xx` - .unwrap_or_else(|| String::from("en_US")) - .as_str() - .try_into() - .unwrap_or(Locale::en_US) - }; let format = date_time.format_localized(formatter, locale); match formatter_buf.write_fmt(format_args!("{format}")) { @@ -166,14 +192,20 @@ where } } -fn format_helper(value: Value, formatter: &str, formatter_span: Span, head_span: Span) -> Value { +fn format_helper( + value: Value, + formatter: &str, + formatter_span: Span, + head_span: Span, + locale: Locale, +) -> Value { match value { - Value::Date { val, .. } => format_from(val, formatter, formatter_span), + Value::Date { val, .. } => format_from(val, formatter, formatter_span, locale), Value::String { val, .. } => { let dt = parse_date_from_string(&val, formatter_span); match dt { - Ok(x) => format_from(x, formatter, formatter_span), + Ok(x) => format_from(x, formatter, formatter_span, locale), Err(e) => e, } }