Skip to content

Commit

Permalink
More chrono deprecations (#4822)
Browse files Browse the repository at this point in the history
  • Loading branch information
tustvold authored Sep 15, 2023
1 parent 7355e83 commit d2be733
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 34 deletions.
29 changes: 12 additions & 17 deletions arrow-cast/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
);

Expand All @@ -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()
);

Expand All @@ -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()
)
}
Expand Down Expand Up @@ -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()
);

Expand All @@ -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()
);

Expand Down
34 changes: 20 additions & 14 deletions arrow-csv/src/reader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
9 changes: 8 additions & 1 deletion arrow-json/src/reader/timestamp_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
6 changes: 4 additions & 2 deletions arrow-json/src/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit d2be733

Please sign in to comment.