From 97bacd4f103357b9b0c4ae8bd55a377a75ecf1ba Mon Sep 17 00:00:00 2001 From: Wenjun Liu Date: Mon, 9 Jan 2023 05:21:06 +0800 Subject: [PATCH 1/2] Fix: Added support casting strings without time to timestamp --- arrow-cast/src/parse.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arrow-cast/src/parse.rs b/arrow-cast/src/parse.rs index 6de336351426..e8f46b503215 100644 --- a/arrow-cast/src/parse.rs +++ b/arrow-cast/src/parse.rs @@ -121,6 +121,12 @@ pub fn string_to_timestamp_nanos(s: &str) -> Result { return Ok(ts.timestamp_nanos()); } + // without a timezone specifier as a local time, only date + // Example: 2020-09-08 + if let Ok(ts) = NaiveDateTime::parse_from_str(s, "%Y-%m-%d") { + return Ok(ts.timestamp_nanos()); + } + // Note we don't pass along the error message from the underlying // chrono parsing because we tried several different format // strings and we don't know which the user was trying to @@ -494,6 +500,19 @@ mod tests { naive_datetime_whole_secs.timestamp_nanos(), parse_timestamp("2020-09-08 13:42:29").unwrap() ); + + // ensure without time work + // no time, should be the nano second at + // 2020-09-08 0:0:0 + let naive_datetime_no_time = NaiveDateTime::new( + NaiveDate::from_ymd_opt(2020, 9, 8).unwrap(), + NaiveTime::from_hms_opt(0, 0, 0).unwrap() + ); + + assert_eq!( + naive_datetime_no_time.timestamp_nanos(), + parse_timestamp("2020-09-08").unwrap() + ) } #[test] From ba7e3059e2ca365ddffdb3a201c5cadcd07883b0 Mon Sep 17 00:00:00 2001 From: Wenjun Liu Date: Mon, 9 Jan 2023 05:21:06 +0800 Subject: [PATCH 2/2] Fix: Added support casting strings without time to timestamp --- arrow-cast/src/parse.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arrow-cast/src/parse.rs b/arrow-cast/src/parse.rs index e8f46b503215..e885ec5b67a8 100644 --- a/arrow-cast/src/parse.rs +++ b/arrow-cast/src/parse.rs @@ -37,6 +37,7 @@ use chrono::prelude::*; /// * `1997-01-31T09:26:56.123` # close to RCF3339 but no timezone offset specified /// * `1997-01-31 09:26:56.123` # close to RCF3339 but uses a space and no timezone offset /// * `1997-01-31 09:26:56` # close to RCF3339, no fractional seconds +/// * `1997-01-31` # close to RCF3339, only date no time // /// Internally, this function uses the `chrono` library for the /// datetime parsing @@ -123,8 +124,10 @@ pub fn string_to_timestamp_nanos(s: &str) -> Result { // without a timezone specifier as a local time, only date // Example: 2020-09-08 - if let Ok(ts) = NaiveDateTime::parse_from_str(s, "%Y-%m-%d") { - return Ok(ts.timestamp_nanos()); + if let Ok(dt) = NaiveDate::parse_from_str(s, "%Y-%m-%d") { + if let Some(ts) = dt.and_hms_opt(0, 0, 0) { + return Ok(ts.timestamp_nanos()); + } } // Note we don't pass along the error message from the underlying @@ -506,7 +509,7 @@ mod tests { // 2020-09-08 0:0:0 let naive_datetime_no_time = NaiveDateTime::new( NaiveDate::from_ymd_opt(2020, 9, 8).unwrap(), - NaiveTime::from_hms_opt(0, 0, 0).unwrap() + NaiveTime::from_hms_opt(0, 0, 0).unwrap(), ); assert_eq!(