Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replace from_timestamp by from_timestamp_opt #2894

Merged
merged 1 commit into from Oct 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 16 additions & 3 deletions arrow-array/src/array/primitive_array.rs
Expand Up @@ -1362,11 +1362,24 @@ mod tests {
}

#[test]
#[should_panic(expected = "invalid time")]
fn test_time32second_invalid_neg() {
// The panic should come from chrono, not from arrow
// chrono::NaiveDatetime::from_timestamp_opt returns None while input is invalid
let arr: PrimitiveArray<Time32SecondType> = vec![-7201, -60054].into();
println!("{:?}", arr);
assert_eq!(
"PrimitiveArray<Time32(Second)>\n[\n null,\n null,\n]",
format!("{:?}", arr)
)
}

#[test]
fn test_timestamp_micros_out_of_range() {
// replicate the issue from https://github.com/apache/arrow-datafusion/issues/3832
let arr: PrimitiveArray<TimestampMicrosecondType> =
vec![9065525203050843594].into();
assert_eq!(
"PrimitiveArray<Timestamp(Microsecond, None)>\n[\n null,\n]",
format!("{:?}", arr)
)
}

#[test]
Expand Down
76 changes: 38 additions & 38 deletions arrow-array/src/temporal_conversions.rs
Expand Up @@ -37,16 +37,16 @@ pub const EPOCH_DAYS_FROM_CE: i32 = 719_163;

/// converts a `i32` representing a `date32` to [`NaiveDateTime`]
#[inline]
pub fn date32_to_datetime(v: i32) -> NaiveDateTime {
NaiveDateTime::from_timestamp(v as i64 * SECONDS_IN_DAY, 0)
pub fn date32_to_datetime(v: i32) -> Option<NaiveDateTime> {
NaiveDateTime::from_timestamp_opt(v as i64 * SECONDS_IN_DAY, 0)
}

/// converts a `i64` representing a `date64` to [`NaiveDateTime`]
#[inline]
pub fn date64_to_datetime(v: i64) -> NaiveDateTime {
pub fn date64_to_datetime(v: i64) -> Option<NaiveDateTime> {
let (sec, milli_sec) = split_second(v, MILLISECONDS);

NaiveDateTime::from_timestamp(
NaiveDateTime::from_timestamp_opt(
// extract seconds from milliseconds
sec,
// discard extracted seconds and convert milliseconds to nanoseconds
Expand All @@ -56,15 +56,15 @@ pub fn date64_to_datetime(v: i64) -> NaiveDateTime {

/// converts a `i32` representing a `time32(s)` to [`NaiveDateTime`]
#[inline]
pub fn time32s_to_time(v: i32) -> NaiveTime {
NaiveTime::from_num_seconds_from_midnight(v as u32, 0)
pub fn time32s_to_time(v: i32) -> Option<NaiveTime> {
NaiveTime::from_num_seconds_from_midnight_opt(v as u32, 0)
}

/// converts a `i32` representing a `time32(ms)` to [`NaiveDateTime`]
#[inline]
pub fn time32ms_to_time(v: i32) -> NaiveTime {
pub fn time32ms_to_time(v: i32) -> Option<NaiveTime> {
let v = v as i64;
NaiveTime::from_num_seconds_from_midnight(
NaiveTime::from_num_seconds_from_midnight_opt(
// extract seconds from milliseconds
(v / MILLISECONDS) as u32,
// discard extracted seconds and convert milliseconds to
Expand All @@ -75,8 +75,8 @@ pub fn time32ms_to_time(v: i32) -> NaiveTime {

/// converts a `i64` representing a `time64(us)` to [`NaiveDateTime`]
#[inline]
pub fn time64us_to_time(v: i64) -> NaiveTime {
NaiveTime::from_num_seconds_from_midnight(
pub fn time64us_to_time(v: i64) -> Option<NaiveTime> {
NaiveTime::from_num_seconds_from_midnight_opt(
// extract seconds from microseconds
(v / MICROSECONDS) as u32,
// discard extracted seconds and convert microseconds to
Expand All @@ -87,8 +87,8 @@ pub fn time64us_to_time(v: i64) -> NaiveTime {

/// converts a `i64` representing a `time64(ns)` to [`NaiveDateTime`]
#[inline]
pub fn time64ns_to_time(v: i64) -> NaiveTime {
NaiveTime::from_num_seconds_from_midnight(
pub fn time64ns_to_time(v: i64) -> Option<NaiveTime> {
NaiveTime::from_num_seconds_from_midnight_opt(
// extract seconds from nanoseconds
(v / NANOSECONDS) as u32,
// discard extracted seconds
Expand All @@ -98,16 +98,16 @@ pub fn time64ns_to_time(v: i64) -> NaiveTime {

/// converts a `i64` representing a `timestamp(s)` to [`NaiveDateTime`]
#[inline]
pub fn timestamp_s_to_datetime(v: i64) -> NaiveDateTime {
NaiveDateTime::from_timestamp(v, 0)
pub fn timestamp_s_to_datetime(v: i64) -> Option<NaiveDateTime> {
NaiveDateTime::from_timestamp_opt(v, 0)
}

/// converts a `i64` representing a `timestamp(ms)` to [`NaiveDateTime`]
#[inline]
pub fn timestamp_ms_to_datetime(v: i64) -> NaiveDateTime {
pub fn timestamp_ms_to_datetime(v: i64) -> Option<NaiveDateTime> {
let (sec, milli_sec) = split_second(v, MILLISECONDS);

NaiveDateTime::from_timestamp(
NaiveDateTime::from_timestamp_opt(
// extract seconds from milliseconds
sec,
// discard extracted seconds and convert milliseconds to nanoseconds
Expand All @@ -117,10 +117,10 @@ pub fn timestamp_ms_to_datetime(v: i64) -> NaiveDateTime {

/// converts a `i64` representing a `timestamp(us)` to [`NaiveDateTime`]
#[inline]
pub fn timestamp_us_to_datetime(v: i64) -> NaiveDateTime {
pub fn timestamp_us_to_datetime(v: i64) -> Option<NaiveDateTime> {
let (sec, micro_sec) = split_second(v, MICROSECONDS);

NaiveDateTime::from_timestamp(
NaiveDateTime::from_timestamp_opt(
// extract seconds from microseconds
sec,
// discard extracted seconds and convert microseconds to nanoseconds
Expand All @@ -130,10 +130,10 @@ pub fn timestamp_us_to_datetime(v: i64) -> NaiveDateTime {

/// converts a `i64` representing a `timestamp(ns)` to [`NaiveDateTime`]
#[inline]
pub fn timestamp_ns_to_datetime(v: i64) -> NaiveDateTime {
pub fn timestamp_ns_to_datetime(v: i64) -> Option<NaiveDateTime> {
let (sec, nano_sec) = split_second(v, NANOSECONDS);

NaiveDateTime::from_timestamp(
NaiveDateTime::from_timestamp_opt(
// extract seconds from nanoseconds
sec, // discard extracted seconds
nano_sec,
Expand Down Expand Up @@ -172,14 +172,14 @@ pub fn duration_ns_to_duration(v: i64) -> Duration {
/// Converts an [`ArrowPrimitiveType`] to [`NaiveDateTime`]
pub fn as_datetime<T: ArrowPrimitiveType>(v: i64) -> Option<NaiveDateTime> {
match T::DATA_TYPE {
DataType::Date32 => Some(date32_to_datetime(v as i32)),
DataType::Date64 => Some(date64_to_datetime(v)),
DataType::Date32 => date32_to_datetime(v as i32),
DataType::Date64 => date64_to_datetime(v),
DataType::Time32(_) | DataType::Time64(_) => None,
DataType::Timestamp(unit, _) => match unit {
TimeUnit::Second => Some(timestamp_s_to_datetime(v)),
TimeUnit::Millisecond => Some(timestamp_ms_to_datetime(v)),
TimeUnit::Microsecond => Some(timestamp_us_to_datetime(v)),
TimeUnit::Nanosecond => Some(timestamp_ns_to_datetime(v)),
TimeUnit::Second => timestamp_s_to_datetime(v),
TimeUnit::Millisecond => timestamp_ms_to_datetime(v),
TimeUnit::Microsecond => timestamp_us_to_datetime(v),
TimeUnit::Nanosecond => timestamp_ns_to_datetime(v),
},
// interval is not yet fully documented [ARROW-3097]
DataType::Interval(_) => None,
Expand All @@ -199,14 +199,14 @@ pub fn as_time<T: ArrowPrimitiveType>(v: i64) -> Option<NaiveTime> {
// safe to immediately cast to u32 as `self.value(i)` is positive i32
let v = v as u32;
match unit {
TimeUnit::Second => Some(time32s_to_time(v as i32)),
TimeUnit::Millisecond => Some(time32ms_to_time(v as i32)),
TimeUnit::Second => time32s_to_time(v as i32),
TimeUnit::Millisecond => time32ms_to_time(v as i32),
_ => None,
}
}
DataType::Time64(unit) => match unit {
TimeUnit::Microsecond => Some(time64us_to_time(v)),
TimeUnit::Nanosecond => Some(time64ns_to_time(v)),
TimeUnit::Microsecond => time64us_to_time(v),
TimeUnit::Nanosecond => time64ns_to_time(v),
_ => None,
},
DataType::Timestamp(_, _) => as_datetime::<T>(v).map(|datetime| datetime.time()),
Expand Down Expand Up @@ -241,51 +241,51 @@ mod tests {
fn negative_input_timestamp_ns_to_datetime() {
assert_eq!(
timestamp_ns_to_datetime(-1),
NaiveDateTime::from_timestamp(-1, 999_999_999)
NaiveDateTime::from_timestamp_opt(-1, 999_999_999)
);

assert_eq!(
timestamp_ns_to_datetime(-1_000_000_001),
NaiveDateTime::from_timestamp(-2, 999_999_999)
NaiveDateTime::from_timestamp_opt(-2, 999_999_999)
);
}

#[test]
fn negative_input_timestamp_us_to_datetime() {
assert_eq!(
timestamp_us_to_datetime(-1),
NaiveDateTime::from_timestamp(-1, 999_999_000)
NaiveDateTime::from_timestamp_opt(-1, 999_999_000)
);

assert_eq!(
timestamp_us_to_datetime(-1_000_001),
NaiveDateTime::from_timestamp(-2, 999_999_000)
NaiveDateTime::from_timestamp_opt(-2, 999_999_000)
);
}

#[test]
fn negative_input_timestamp_ms_to_datetime() {
assert_eq!(
timestamp_ms_to_datetime(-1),
NaiveDateTime::from_timestamp(-1, 999_000_000)
NaiveDateTime::from_timestamp_opt(-1, 999_000_000)
);

assert_eq!(
timestamp_ms_to_datetime(-1_001),
NaiveDateTime::from_timestamp(-2, 999_000_000)
NaiveDateTime::from_timestamp_opt(-2, 999_000_000)
);
}

#[test]
fn negative_input_date64_to_datetime() {
assert_eq!(
date64_to_datetime(-1),
NaiveDateTime::from_timestamp(-1, 999_000_000)
NaiveDateTime::from_timestamp_opt(-1, 999_000_000)
);

assert_eq!(
date64_to_datetime(-1_001),
NaiveDateTime::from_timestamp(-2, 999_000_000)
NaiveDateTime::from_timestamp_opt(-2, 999_000_000)
);
}

Expand Down