From b3f6b4f078bcc1bb3bd7cbdf47fbc40a3ece27d0 Mon Sep 17 00:00:00 2001 From: eitsupi Date: Sat, 2 Mar 2024 07:18:57 +0000 Subject: [PATCH] fix!: POSIXct without tzone -> Polars datetime --- src/rust/src/conversion_r_to_s.rs | 42 ++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/rust/src/conversion_r_to_s.rs b/src/rust/src/conversion_r_to_s.rs index d5aeb31fe..51630be9f 100644 --- a/src/rust/src/conversion_r_to_s.rs +++ b/src/rust/src/conversion_r_to_s.rs @@ -1,3 +1,4 @@ +use crate::robj_to; use crate::series::RPolarsSeries; use crate::utils::collect_hinted_result; use extendr_api::prelude::*; @@ -6,6 +7,8 @@ use extendr_api::prelude::*; use polars::prelude as pl; use polars::prelude::IntoSeries; use polars::prelude::NamedFrom; +use polars_lazy::dsl::col; +use polars_lazy::frame::IntoLazy; // Internal tree structure to contain Series of fully parsed nested Robject. // It is easier to resolve concatenated datatype after all elements have been parsed // because empty lists have no type in R, but the corrosponding polars type must be known before @@ -210,10 +213,41 @@ fn recursive_robjname2series_tree(x: &Robj, name: &str) -> pl::PolarsResult { + Ok(SeriesTree::Series( + (s * 1_000f64).cast(&pl::DataType::Int64)?.cast( + &pl::DataType::Datetime(pl::TimeUnit::Milliseconds, Some(tz)), + )?, + )) + } + // sys time + None => { + let sys_tz_robj = R!("Sys.timezone()") + .map_err(|err| pl::PolarsError::ComputeError(err.to_string().into()))?; + let sys_tz = robj_to!(String, sys_tz_robj) + .map_err(|err| pl::PolarsError::ComputeError(err.to_string().into()))?; + let utc_s = (s * 1_000f64).cast(&pl::DataType::Int64)?.cast( + &pl::DataType::Datetime( + pl::TimeUnit::Milliseconds, + Some("UTC".to_string()), + ), + )?; + Ok(SeriesTree::Series( + pl::DataFrame::new(vec![utc_s.clone()])? + .lazy() + .select([col("") + .dt() + .convert_time_zone(sys_tz) + .dt() + .replace_time_zone(None, pl::lit("raise"))]) + .collect()? + .column("")? + .clone(), + )) + } + } } Ok(SeriesTree::Series(s)) if x.inherits("Date") => { Ok(SeriesTree::Series(s.cast(&pl::DataType::Date)?))