From 67a63162b2b780c2d0ab6a112cdb05b11b1937ed Mon Sep 17 00:00:00 2001 From: nils-degroot <53556985+nils-degroot@users.noreply.github.com> Date: Sat, 24 Feb 2024 14:25:51 +0100 Subject: [PATCH] Add date support in `from xlsx` (#11952) # Description This PR add date support when using the `open` command on a xlsx file, and the using `from xlsx` on a xlsx file. # User-Facing Changes Currently dates in xlsx files are read as nulls, after this PR this would be regular dates. # Tests + Formatting # After Submitting --- Cargo.lock | 2 ++ crates/nu-command/Cargo.toml | 4 ++-- crates/nu-command/src/formats/from/xlsx.rs | 15 +++++++++++++++ .../nu-command/tests/format_conversions/xlsx.rs | 14 ++++++++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 03302add9d..77e78354f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -583,9 +583,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a3a315226fdc5b1c3e33521073e1712a05944bc0664d665ff1f6ff0396334da" dependencies = [ "byteorder", + "chrono", "codepage", "encoding_rs", "log", + "once_cell", "quick-xml", "serde", "zip", diff --git a/crates/nu-command/Cargo.toml b/crates/nu-command/Cargo.toml index 30fc110fad..0eb145a679 100644 --- a/crates/nu-command/Cargo.toml +++ b/crates/nu-command/Cargo.toml @@ -32,8 +32,8 @@ alphanumeric-sort = "1.5" base64 = "0.21" byteorder = "1.5" bytesize = "1.3" -calamine = "0.24.0" -chrono = { version = "0.4.34", features = ["std", "unstable-locales"], default-features = false } +calamine = { version = "0.24.0", features = ["dates"] } +chrono = { version = "0.4.34", features = ["std", "unstable-locales", "clock"], default-features = false } chrono-humanize = "0.2.3" chrono-tz = "0.8" crossterm = "0.27" diff --git a/crates/nu-command/src/formats/from/xlsx.rs b/crates/nu-command/src/formats/from/xlsx.rs index 4abecc66f4..d2fe3cfa0b 100644 --- a/crates/nu-command/src/formats/from/xlsx.rs +++ b/crates/nu-command/src/formats/from/xlsx.rs @@ -1,4 +1,6 @@ use calamine::*; +use chrono::offset::Utc; +use chrono::{Local, LocalResult, Offset, TimeZone}; use indexmap::map::IndexMap; use nu_engine::CallExt; use nu_protocol::ast::Call; @@ -130,6 +132,11 @@ fn from_xlsx( sheet_names.retain(|e| sel_sheets.contains(e)); } + let tz = match Local.timestamp_opt(0, 0) { + LocalResult::Single(tz) => *tz.offset(), + _ => Utc.fix(), + }; + for sheet_name in sheet_names { let mut sheet_output = vec![]; @@ -145,6 +152,14 @@ fn from_xlsx( Data::Float(f) => Value::float(*f, head), Data::Int(i) => Value::int(*i, head), Data::Bool(b) => Value::bool(*b, head), + Data::DateTime(d) => d + .as_datetime() + .and_then(|d| match tz.from_local_datetime(&d) { + LocalResult::Single(d) => Some(d), + _ => None, + }) + .map(|d| Value::date(d, head)) + .unwrap_or(Value::nothing(head)), _ => Value::nothing(head), }; diff --git a/crates/nu-command/tests/format_conversions/xlsx.rs b/crates/nu-command/tests/format_conversions/xlsx.rs index fdd7dca875..06c07e7135 100644 --- a/crates/nu-command/tests/format_conversions/xlsx.rs +++ b/crates/nu-command/tests/format_conversions/xlsx.rs @@ -29,3 +29,17 @@ fn from_excel_file_to_table_select_sheet() { assert_eq!(actual.out, "SalesOrders"); } + +#[test] +fn from_excel_file_to_date() { + let actual = nu!( + cwd: "tests/fixtures/formats", pipeline( + r#" + open sample_data.xlsx + | get SalesOrders.4.column0 + | format date "%Y-%m-%d" + "# + )); + + assert_eq!(actual.out, "2018-02-26"); +}