This is an automated email from the ASF dual-hosted git repository.

tustvold pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/master by this push:
     new d2be733f44 More chrono deprecations (#4822)
d2be733f44 is described below

commit d2be733f447c252e0f655201f4cb0fc8015448e5
Author: Raphael Taylor-Davies <[email protected]>
AuthorDate: Fri Sep 15 18:14:14 2023 +0100

    More chrono deprecations (#4822)
---
 arrow-cast/src/parse.rs                  | 29 +++++++++++----------------
 arrow-csv/src/reader/mod.rs              | 34 +++++++++++++++++++-------------
 arrow-json/src/reader/timestamp_array.rs |  9 ++++++++-
 arrow-json/src/writer.rs                 |  6 ++++--
 4 files changed, 44 insertions(+), 34 deletions(-)

diff --git a/arrow-cast/src/parse.rs b/arrow-cast/src/parse.rs
index ac3b89e0ba..3806f0adc5 100644
--- a/arrow-cast/src/parse.rs
+++ b/arrow-cast/src/parse.rs
@@ -277,16 +277,11 @@ pub fn string_to_timestamp_nanos(s: &str) -> Result<i64, 
ArrowError> {
     to_timestamp_nanos(string_to_datetime(&Utc, s)?.naive_utc())
 }
 
-/// Defensive check to prevent chrono-rs panics when nanosecond conversion 
happens on non-supported dates
+/// Fallible conversion of [`NaiveDateTime`] to `i64` nanoseconds
 #[inline]
 fn to_timestamp_nanos(dt: NaiveDateTime) -> Result<i64, ArrowError> {
-    if dt.timestamp().checked_mul(1_000_000_000).is_none() {
-        return Err(ArrowError::ParseError(
-            ERR_NANOSECONDS_NOT_SUPPORTED.to_string(),
-        ));
-    }
-
-    Ok(dt.timestamp_nanos())
+    dt.timestamp_nanos_opt()
+        .ok_or_else(|| 
ArrowError::ParseError(ERR_NANOSECONDS_NOT_SUPPORTED.to_string()))
 }
 
 /// Accepts a string in ISO8601 standard format and some
@@ -1313,12 +1308,12 @@ mod tests {
 
         // Ensure both T and ' ' variants work
         assert_eq!(
-            naive_datetime.timestamp_nanos(),
+            naive_datetime.timestamp_nanos_opt().unwrap(),
             parse_timestamp("2020-09-08T13:42:29.190855").unwrap()
         );
 
         assert_eq!(
-            naive_datetime.timestamp_nanos(),
+            naive_datetime.timestamp_nanos_opt().unwrap(),
             parse_timestamp("2020-09-08 13:42:29.190855").unwrap()
         );
 
@@ -1331,12 +1326,12 @@ mod tests {
 
         // Ensure both T and ' ' variants work
         assert_eq!(
-            naive_datetime_whole_secs.timestamp_nanos(),
+            naive_datetime_whole_secs.timestamp_nanos_opt().unwrap(),
             parse_timestamp("2020-09-08T13:42:29").unwrap()
         );
 
         assert_eq!(
-            naive_datetime_whole_secs.timestamp_nanos(),
+            naive_datetime_whole_secs.timestamp_nanos_opt().unwrap(),
             parse_timestamp("2020-09-08 13:42:29").unwrap()
         );
 
@@ -1349,7 +1344,7 @@ mod tests {
         );
 
         assert_eq!(
-            naive_datetime_no_time.timestamp_nanos(),
+            naive_datetime_no_time.timestamp_nanos_opt().unwrap(),
             parse_timestamp("2020-09-08").unwrap()
         )
     }
@@ -1463,12 +1458,12 @@ mod tests {
 
         // Ensure both T and ' ' variants work
         assert_eq!(
-            naive_datetime.timestamp_nanos(),
+            naive_datetime.timestamp_nanos_opt().unwrap(),
             parse_timestamp("2020-09-08T13:42:29.190855").unwrap()
         );
 
         assert_eq!(
-            naive_datetime.timestamp_nanos(),
+            naive_datetime.timestamp_nanos_opt().unwrap(),
             parse_timestamp("2020-09-08 13:42:29.190855").unwrap()
         );
 
@@ -1479,12 +1474,12 @@ mod tests {
 
         // Ensure both T and ' ' variants work
         assert_eq!(
-            naive_datetime.timestamp_nanos(),
+            naive_datetime.timestamp_nanos_opt().unwrap(),
             parse_timestamp("2020-09-08T13:42:29").unwrap()
         );
 
         assert_eq!(
-            naive_datetime.timestamp_nanos(),
+            naive_datetime.timestamp_nanos_opt().unwrap(),
             parse_timestamp("2020-09-08 13:42:29").unwrap()
         );
 
diff --git a/arrow-csv/src/reader/mod.rs b/arrow-csv/src/reader/mod.rs
index 695e3d4796..17db7a34e0 100644
--- a/arrow-csv/src/reader/mod.rs
+++ b/arrow-csv/src/reader/mod.rs
@@ -984,20 +984,26 @@ fn build_timestamp_array_impl<T: ArrowTimestampType, Tz: 
TimeZone>(
                 return Ok(None);
             }
 
-            let date = string_to_datetime(timezone, s).map_err(|e| {
-                ArrowError::ParseError(format!(
-                    "Error parsing column {col_idx} at line {}: {}",
-                    line_number + row_index,
-                    e
-                ))
-            })?;
-
-            Ok(Some(match T::UNIT {
-                TimeUnit::Second => date.timestamp(),
-                TimeUnit::Millisecond => date.timestamp_millis(),
-                TimeUnit::Microsecond => date.timestamp_micros(),
-                TimeUnit::Nanosecond => date.timestamp_nanos(),
-            }))
+            let date = string_to_datetime(timezone, s)
+                .and_then(|date| match T::UNIT {
+                    TimeUnit::Second => Ok(date.timestamp()),
+                    TimeUnit::Millisecond => Ok(date.timestamp_millis()),
+                    TimeUnit::Microsecond => Ok(date.timestamp_micros()),
+                    TimeUnit::Nanosecond => 
date.timestamp_nanos_opt().ok_or_else(|| {
+                        ArrowError::ParseError(format!(
+                            "{} would overflow 64-bit signed nanoseconds",
+                            date.to_rfc3339(),
+                        ))
+                    }),
+                })
+                .map_err(|e| {
+                    ArrowError::ParseError(format!(
+                        "Error parsing column {col_idx} at line {}: {}",
+                        line_number + row_index,
+                        e
+                    ))
+                })?;
+            Ok(Some(date))
         })
         .collect()
 }
diff --git a/arrow-json/src/reader/timestamp_array.rs 
b/arrow-json/src/reader/timestamp_array.rs
index ef69deabce..b80915f6a5 100644
--- a/arrow-json/src/reader/timestamp_array.rs
+++ b/arrow-json/src/reader/timestamp_array.rs
@@ -71,7 +71,14 @@ where
                         TimeUnit::Second => date.timestamp(),
                         TimeUnit::Millisecond => date.timestamp_millis(),
                         TimeUnit::Microsecond => date.timestamp_micros(),
-                        TimeUnit::Nanosecond => date.timestamp_nanos(),
+                        TimeUnit::Nanosecond => {
+                            date.timestamp_nanos_opt().ok_or_else(|| {
+                                ArrowError::ParseError(format!(
+                                    "{} would overflow 64-bit signed 
nanoseconds",
+                                    date.to_rfc3339(),
+                                ))
+                            })?
+                        }
                     };
                     builder.append_value(value)
                 }
diff --git a/arrow-json/src/writer.rs b/arrow-json/src/writer.rs
index a5b5a78190..db371b5908 100644
--- a/arrow-json/src/writer.rs
+++ b/arrow-json/src/writer.rs
@@ -757,7 +757,8 @@ mod tests {
         let ts_nanos = ts_string
             .parse::<chrono::NaiveDateTime>()
             .unwrap()
-            .timestamp_nanos();
+            .timestamp_nanos_opt()
+            .unwrap();
         let ts_micros = ts_nanos / 1000;
         let ts_millis = ts_micros / 1000;
         let ts_secs = ts_millis / 1000;
@@ -809,7 +810,8 @@ mod tests {
         let ts_nanos = ts_string
             .parse::<chrono::NaiveDateTime>()
             .unwrap()
-            .timestamp_nanos();
+            .timestamp_nanos_opt()
+            .unwrap();
         let ts_micros = ts_nanos / 1000;
         let ts_millis = ts_micros / 1000;
         let ts_secs = ts_millis / 1000;

Reply via email to