From 05e570aa71eac53cd6900f3fd02b699c13ace758 Mon Sep 17 00:00:00 2001 From: Skyler Hawthorne Date: Tue, 8 Jul 2025 15:42:55 -0400 Subject: [PATCH] polars: fix datetime type conversion (#16133) # Description Conversion from `AnyType::DatetimeOwned` was missing, so datetime objects could not be represented in Nushell Values. This adds the conversion. A slight refactor of the `datetime_from_epoch_nanos` was needed. # User-Facing Changes All datetime types can be represented in Nushell. --- .../values/nu_dataframe/conversion.rs | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/crates/nu_plugin_polars/src/dataframe/values/nu_dataframe/conversion.rs b/crates/nu_plugin_polars/src/dataframe/values/nu_dataframe/conversion.rs index 63979e8ac2..0cc1878823 100644 --- a/crates/nu_plugin_polars/src/dataframe/values/nu_dataframe/conversion.rs +++ b/crates/nu_plugin_polars/src/dataframe/values/nu_dataframe/conversion.rs @@ -1181,7 +1181,7 @@ fn series_to_values( .map(|v| match v { Some(a) => { let nanos = nanos_per_day(a); - let datetime = datetime_from_epoch_nanos(nanos, &None, span)?; + let datetime = datetime_from_epoch_nanos(nanos, None, span)?; Ok(Value::date(datetime, span)) } None => Ok(Value::nothing(span)), @@ -1208,7 +1208,7 @@ fn series_to_values( Some(a) => { // elapsed time in nano/micro/milliseconds since 1970-01-01 let nanos = nanos_from_timeunit(a, *time_unit)?; - let datetime = datetime_from_epoch_nanos(nanos, tz, span)?; + let datetime = datetime_from_epoch_nanos(nanos, tz.as_ref(), span)?; Ok(Value::date(datetime, span)) } None => Ok(Value::nothing(span)), @@ -1298,7 +1298,7 @@ fn series_to_values( error: "Error creating Dataframe".into(), msg: "".to_string(), span: None, - help: Some(format!("Value not supported in nushell: {e}")), + help: Some(format!("Value not supported in nushell: {e:?}")), inner: vec![], }), } @@ -1321,12 +1321,16 @@ fn any_value_to_value(any_value: &AnyValue, span: Span) -> Result Ok(Value::float(*f, span)), AnyValue::Date(d) => { let nanos = nanos_per_day(*d); - datetime_from_epoch_nanos(nanos, &None, span) - .map(|datetime| Value::date(datetime, span)) + datetime_from_epoch_nanos(nanos, None, span).map(|datetime| Value::date(datetime, span)) } AnyValue::Datetime(a, time_unit, tz) => { let nanos = nanos_from_timeunit(*a, *time_unit)?; - datetime_from_epoch_nanos(nanos, &tz.cloned(), span) + datetime_from_epoch_nanos(nanos, tz.cloned().as_ref(), span) + .map(|datetime| Value::date(datetime, span)) + } + AnyValue::DatetimeOwned(a, time_unit, tz) => { + let nanos = nanos_from_timeunit(*a, *time_unit)?; + datetime_from_epoch_nanos(nanos, tz.as_ref().map(|tz| tz.as_ref()), span) .map(|datetime| Value::date(datetime, span)) } AnyValue::Duration(a, time_unit) => { @@ -1402,7 +1406,7 @@ fn any_value_to_value(any_value: &AnyValue, span: Span) -> Result Result { fn datetime_from_epoch_nanos( nanos: i64, - timezone: &Option, + timezone: Option<&PolarsTimeZone>, span: Span, ) -> Result, ShellError> { let tz: Tz = if let Some(polars_tz) = timezone {