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

chore(rust): fix chrono deprecation warnings #14928

Merged
merged 2 commits into from
Mar 8, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 19 additions & 79 deletions crates/polars-arrow/src/temporal_conversions.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Conversion methods for dates and times.

use chrono::format::{parse, Parsed, StrftimeItems};
use chrono::{Duration, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime};
use chrono::{DateTime, Duration, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime, TimeDelta};
use polars_error::{polars_err, PolarsResult};

use crate::array::{PrimitiveArray, Utf8ViewArray};
Expand Down Expand Up @@ -29,7 +29,8 @@ pub fn date32_to_datetime(v: i32) -> NaiveDateTime {
/// converts a `i32` representing a `date32` to [`NaiveDateTime`]
#[inline]
pub fn date32_to_datetime_opt(v: i32) -> Option<NaiveDateTime> {
NaiveDateTime::from_timestamp_opt(v as i64 * SECONDS_IN_DAY, 0)
let delta = TimeDelta::try_days(v.into())?;
NaiveDateTime::UNIX_EPOCH.checked_add_signed(delta)
}

/// converts a `i32` representing a `date32` to [`NaiveDate`]
Expand All @@ -47,13 +48,9 @@ pub fn date32_to_date_opt(days: i32) -> Option<NaiveDate> {
/// converts a `i64` representing a `date64` to [`NaiveDateTime`]
#[inline]
pub fn date64_to_datetime(v: i64) -> NaiveDateTime {
NaiveDateTime::from_timestamp_opt(
// extract seconds from milliseconds
v / MILLISECONDS,
// discard extracted seconds and convert milliseconds to nanoseconds
(v % MILLISECONDS * MICROSECONDS) as u32,
)
.expect("invalid or out-of-range datetime")
TimeDelta::try_milliseconds(v)
.and_then(|delta| NaiveDateTime::UNIX_EPOCH.checked_add_signed(delta))
.expect("invalid or out-of-range datetime")
}

/// converts a `i64` representing a `date64` to [`NaiveDate`]
Expand All @@ -71,13 +68,13 @@ pub fn time32s_to_time(v: i32) -> NaiveTime {
/// converts a `i64` representing a `duration(s)` to [`Duration`]
#[inline]
pub fn duration_s_to_duration(v: i64) -> Duration {
Duration::seconds(v)
Duration::try_seconds(v).expect("out-of-range duration")
}

/// converts a `i64` representing a `duration(ms)` to [`Duration`]
#[inline]
pub fn duration_ms_to_duration(v: i64) -> Duration {
Duration::milliseconds(v)
Duration::try_milliseconds(v).expect("out-of-range in duration conversion")
}

/// converts a `i64` representing a `duration(us)` to [`Duration`]
Expand Down Expand Up @@ -148,7 +145,7 @@ pub fn timestamp_s_to_datetime(seconds: i64) -> NaiveDateTime {
/// converts a `i64` representing a `timestamp(s)` to [`NaiveDateTime`]
#[inline]
pub fn timestamp_s_to_datetime_opt(seconds: i64) -> Option<NaiveDateTime> {
NaiveDateTime::from_timestamp_opt(seconds, 0)
Some(DateTime::from_timestamp(seconds, 0)?.naive_utc())
}

/// converts a `i64` representing a `timestamp(ms)` to [`NaiveDateTime`]
Expand All @@ -160,27 +157,8 @@ pub fn timestamp_ms_to_datetime(v: i64) -> NaiveDateTime {
/// converts a `i64` representing a `timestamp(ms)` to [`NaiveDateTime`]
#[inline]
pub fn timestamp_ms_to_datetime_opt(v: i64) -> Option<NaiveDateTime> {
if v >= 0 {
NaiveDateTime::from_timestamp_opt(
// extract seconds from milliseconds
v / MILLISECONDS,
// discard extracted seconds and convert milliseconds to nanoseconds
(v % MILLISECONDS * MICROSECONDS) as u32,
)
} else {
let secs_rem = (v / MILLISECONDS, v % MILLISECONDS);
if secs_rem.1 == 0 {
// whole/integer seconds; no adjustment required
NaiveDateTime::from_timestamp_opt(secs_rem.0, 0)
} else {
// negative values with fractional seconds require 'div_floor' rounding behaviour.
// (which isn't yet stabilised: https://github.com/rust-lang/rust/issues/88581)
NaiveDateTime::from_timestamp_opt(
secs_rem.0 - 1,
(NANOSECONDS + (v % MILLISECONDS * MICROSECONDS)) as u32,
)
}
}
let delta = TimeDelta::try_milliseconds(v)?;
NaiveDateTime::UNIX_EPOCH.checked_add_signed(delta)
Comment on lines -163 to +161
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so satisfying 😍

}

/// converts a `i64` representing a `timestamp(us)` to [`NaiveDateTime`]
Expand All @@ -192,27 +170,8 @@ pub fn timestamp_us_to_datetime(v: i64) -> NaiveDateTime {
/// converts a `i64` representing a `timestamp(us)` to [`NaiveDateTime`]
#[inline]
pub fn timestamp_us_to_datetime_opt(v: i64) -> Option<NaiveDateTime> {
if v >= 0 {
NaiveDateTime::from_timestamp_opt(
// extract seconds from microseconds
v / MICROSECONDS,
// discard extracted seconds and convert microseconds to nanoseconds
(v % MICROSECONDS * MILLISECONDS) as u32,
)
} else {
let secs_rem = (v / MICROSECONDS, v % MICROSECONDS);
if secs_rem.1 == 0 {
// whole/integer seconds; no adjustment required
NaiveDateTime::from_timestamp_opt(secs_rem.0, 0)
} else {
// negative values with fractional seconds require 'div_floor' rounding behaviour.
// (which isn't yet stabilised: https://github.com/rust-lang/rust/issues/88581)
NaiveDateTime::from_timestamp_opt(
secs_rem.0 - 1,
(NANOSECONDS + (v % MICROSECONDS * MILLISECONDS)) as u32,
)
}
}
let delta = TimeDelta::microseconds(v);
NaiveDateTime::UNIX_EPOCH.checked_add_signed(delta)
}

/// converts a `i64` representing a `timestamp(ns)` to [`NaiveDateTime`]
Expand All @@ -224,27 +183,8 @@ pub fn timestamp_ns_to_datetime(v: i64) -> NaiveDateTime {
/// converts a `i64` representing a `timestamp(ns)` to [`NaiveDateTime`]
#[inline]
pub fn timestamp_ns_to_datetime_opt(v: i64) -> Option<NaiveDateTime> {
if v >= 0 {
NaiveDateTime::from_timestamp_opt(
// extract seconds from nanoseconds
v / NANOSECONDS,
// discard extracted seconds
(v % NANOSECONDS) as u32,
)
} else {
let secs_rem = (v / NANOSECONDS, v % NANOSECONDS);
if secs_rem.1 == 0 {
// whole/integer seconds; no adjustment required
NaiveDateTime::from_timestamp_opt(secs_rem.0, 0)
} else {
// negative values with fractional seconds require 'div_floor' rounding behaviour.
// (which isn't yet stabilised: https://github.com/rust-lang/rust/issues/88581)
NaiveDateTime::from_timestamp_opt(
secs_rem.0 - 1,
(NANOSECONDS + (v % NANOSECONDS)) as u32,
)
}
}
let delta = TimeDelta::nanoseconds(v);
NaiveDateTime::UNIX_EPOCH.checked_add_signed(delta)
}

/// Converts a timestamp in `time_unit` and `timezone` into [`chrono::DateTime`].
Expand Down Expand Up @@ -362,10 +302,10 @@ pub fn utf8_to_naive_timestamp_scalar(value: &str, fmt: &str, tu: &TimeUnit) ->
parsed
.to_naive_datetime_with_offset(0)
.map(|x| match tu {
TimeUnit::Second => x.timestamp(),
TimeUnit::Millisecond => x.timestamp_millis(),
TimeUnit::Microsecond => x.timestamp_micros(),
TimeUnit::Nanosecond => x.timestamp_nanos_opt().unwrap(),
TimeUnit::Second => x.and_utc().timestamp(),
TimeUnit::Millisecond => x.and_utc().timestamp_millis(),
TimeUnit::Microsecond => x.and_utc().timestamp_micros(),
TimeUnit::Nanosecond => x.and_utc().timestamp_nanos_opt().unwrap(),
})
.ok()
}
Expand Down
12 changes: 5 additions & 7 deletions crates/polars-core/src/chunked_array/temporal/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ impl From<&AnyValue<'_>> for NaiveDateTime {
fn from(v: &AnyValue) -> Self {
match v {
#[cfg(feature = "dtype-date")]
AnyValue::Date(v) => {
NaiveDateTime::from_timestamp_opt(*v as i64 * SECONDS_IN_DAY, 0).unwrap()
},
AnyValue::Date(v) => date32_to_datetime(*v),
#[cfg(feature = "dtype-datetime")]
AnyValue::Datetime(v, tu, _) => match tu {
TimeUnit::Nanoseconds => timestamp_ns_to_datetime(*v),
Expand All @@ -36,18 +34,18 @@ impl From<&AnyValue<'_>> for NaiveTime {

// Used by lazy for literal conversion
pub fn datetime_to_timestamp_ns(v: NaiveDateTime) -> i64 {
v.timestamp_nanos_opt().unwrap()
v.and_utc().timestamp_nanos_opt().unwrap()
}

// Used by lazy for literal conversion
pub fn datetime_to_timestamp_ms(v: NaiveDateTime) -> i64 {
v.timestamp_millis()
v.and_utc().timestamp_millis()
}

// Used by lazy for literal conversion
pub fn datetime_to_timestamp_us(v: NaiveDateTime) -> i64 {
let us = v.timestamp() * 1_000_000;
us + v.timestamp_subsec_micros() as i64
let us = v.and_utc().timestamp() * 1_000_000;
us + v.and_utc().timestamp_subsec_micros() as i64
}

pub(crate) fn naive_datetime_to_date(v: NaiveDateTime) -> i32 {
Expand Down
4 changes: 0 additions & 4 deletions crates/polars-core/src/chunked_array/temporal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ pub use self::conversion::*;
#[cfg(feature = "timezones")]
use crate::prelude::{polars_bail, PolarsResult};

pub fn unix_time() -> NaiveDateTime {
NaiveDateTime::from_timestamp_opt(0, 0).unwrap()
}

#[cfg(feature = "timezones")]
static FIXED_OFFSET_PATTERN: &str = r#"(?x)
^
Expand Down
6 changes: 3 additions & 3 deletions crates/polars-lazy/src/tests/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,9 +437,9 @@ fn test_lazy_query_10() {
let z: Series = DurationChunked::from_duration(
"z",
[
ChronoDuration::hours(1),
ChronoDuration::hours(2),
ChronoDuration::hours(3),
ChronoDuration::try_hours(1).unwrap(),
ChronoDuration::try_hours(2).unwrap(),
ChronoDuration::try_hours(3).unwrap(),
],
TimeUnit::Nanoseconds,
)
Expand Down
6 changes: 3 additions & 3 deletions crates/polars-plan/src/dsl/function_expr/temporal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,9 @@ pub(super) fn datetime(
NaiveDate::from_ymd_opt(y, m, d)
.and_then(|nd| nd.and_hms_micro_opt(h, mnt, s, us))
.map(|ndt| match time_unit {
TimeUnit::Milliseconds => ndt.timestamp_millis(),
TimeUnit::Microseconds => ndt.timestamp_micros(),
TimeUnit::Nanoseconds => ndt.timestamp_nanos_opt().unwrap(),
TimeUnit::Milliseconds => ndt.and_utc().timestamp_millis(),
TimeUnit::Microseconds => ndt.and_utc().timestamp_micros(),
TimeUnit::Nanoseconds => ndt.and_utc().timestamp_nanos_opt().unwrap(),
})
} else {
None
Expand Down
4 changes: 2 additions & 2 deletions crates/polars-plan/src/logical_plan/lit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,13 +260,13 @@ impl Literal for NaiveDateTime {
fn lit(self) -> Expr {
if in_nanoseconds_window(&self) {
Expr::Literal(LiteralValue::DateTime(
self.timestamp_nanos_opt().unwrap(),
self.and_utc().timestamp_nanos_opt().unwrap(),
TimeUnit::Nanoseconds,
None,
))
} else {
Expr::Literal(LiteralValue::DateTime(
self.timestamp_micros(),
self.and_utc().timestamp_micros(),
TimeUnit::Microseconds,
None,
))
Expand Down
4 changes: 0 additions & 4 deletions crates/polars-time/src/chunkedarray/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ pub use string::StringMethods;
#[cfg(feature = "dtype-time")]
pub use time::TimeMethods;

pub fn unix_time() -> NaiveDateTime {
NaiveDateTime::from_timestamp_opt(0, 0).unwrap()
}

// a separate function so that it is not compiled twice
#[cfg(any(feature = "dtype-date", feature = "dtype-datetime"))]
pub(crate) fn months_to_quarters(mut ca: Int8Chunked) -> Int8Chunked {
Expand Down
14 changes: 10 additions & 4 deletions crates/polars-time/src/date_range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,17 @@ pub fn date_range(
) -> PolarsResult<DatetimeChunked> {
let (start, end) = match tu {
TimeUnit::Nanoseconds => (
start.timestamp_nanos_opt().unwrap(),
end.timestamp_nanos_opt().unwrap(),
start.and_utc().timestamp_nanos_opt().unwrap(),
end.and_utc().timestamp_nanos_opt().unwrap(),
),
TimeUnit::Microseconds => (
start.and_utc().timestamp_micros(),
end.and_utc().timestamp_micros(),
),
TimeUnit::Milliseconds => (
start.and_utc().timestamp_millis(),
end.and_utc().timestamp_millis(),
),
TimeUnit::Microseconds => (start.timestamp_micros(), end.timestamp_micros()),
TimeUnit::Milliseconds => (start.timestamp_millis(), end.timestamp_millis()),
};
datetime_range_impl(name, start, end, interval, closed, tu, tz)
}
Expand Down
8 changes: 8 additions & 0 deletions crates/polars-time/src/group_by/dynamic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -802,11 +802,13 @@ mod test {
.unwrap()
.and_hms_opt(0, 0, 0)
.unwrap()
.and_utc()
.timestamp_millis();
let stop = NaiveDate::from_ymd_opt(2021, 12, 16)
.unwrap()
.and_hms_opt(3, 0, 0)
.unwrap()
.and_utc()
.timestamp_millis();
let range = datetime_range_impl(
"date",
Expand Down Expand Up @@ -855,11 +857,13 @@ mod test {
.unwrap()
.and_hms_opt(1, 0, 0)
.unwrap()
.and_utc()
.timestamp_millis();
let stop = NaiveDate::from_ymd_opt(2021, 12, 16)
.unwrap()
.and_hms_opt(3, 0, 0)
.unwrap()
.and_utc()
.timestamp_millis();
let range = datetime_range_impl(
"_upper_boundary",
Expand All @@ -878,11 +882,13 @@ mod test {
.unwrap()
.and_hms_opt(0, 0, 0)
.unwrap()
.and_utc()
.timestamp_millis();
let stop = NaiveDate::from_ymd_opt(2021, 12, 16)
.unwrap()
.and_hms_opt(2, 0, 0)
.unwrap()
.and_utc()
.timestamp_millis();
let range = datetime_range_impl(
"_lower_boundary",
Expand Down Expand Up @@ -917,11 +923,13 @@ mod test {
.unwrap()
.and_hms_opt(12, 0, 0)
.unwrap()
.and_utc()
.timestamp_millis();
let stop = NaiveDate::from_ymd_opt(2021, 3, 7)
.unwrap()
.and_hms_opt(12, 0, 0)
.unwrap()
.and_utc()
.timestamp_millis();
let range = datetime_range_impl(
"date",
Expand Down
Loading
Loading