Skip to content

Commit

Permalink
fix: replace_time_zone with single-null-element "ambiguous" was panic…
Browse files Browse the repository at this point in the history
…king (#14971)
  • Loading branch information
MarcoGorelli committed Mar 11, 2024
1 parent 78dc628 commit 8c2eca9
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 4 deletions.
Expand Up @@ -19,8 +19,7 @@ pub fn replace_time_zone(
let from_tz = parse_time_zone(from_time_zone)?;
let to_tz = parse_time_zone(time_zone.unwrap_or("UTC"))?;
if (from_tz == to_tz)
& ((from_tz == UTC)
| ((ambiguous.len() == 1) & (unsafe { ambiguous.get_unchecked(0) } == Some("raise"))))
& ((from_tz == UTC) | ((ambiguous.len() == 1) & (ambiguous.get(0) == Some("raise"))))
{
let mut out = datetime
.0
Expand All @@ -40,7 +39,7 @@ pub fn replace_time_zone(
TimeUnit::Nanoseconds => datetime_to_timestamp_ns,
};
let out = match ambiguous.len() {
1 => match unsafe { ambiguous.get_unchecked(0) } {
1 => match ambiguous.get(0) {
Some(ambiguous) => datetime.0.try_apply(|timestamp| {
let ndt = timestamp_to_datetime(timestamp);
Ok(datetime_to_timestamp(convert_to_naive_local(
Expand Down Expand Up @@ -68,7 +67,7 @@ pub fn replace_time_zone(
}),
};
let mut out = out?.into_datetime(datetime.time_unit(), time_zone.map(|x| x.to_string()));
if from_time_zone == "UTC" && ambiguous.len() == 1 && ambiguous.get(0).unwrap() == "raise" {
if from_time_zone == "UTC" && ambiguous.len() == 1 && ambiguous.get(0) == Some("raise") {
// In general, the sortedness flag can't be preserved.
// To be safe, we only do so in the simplest case when we know for sure that there is no "daylight savings weirdness" going on, i.e.:
// - `from_tz` is guaranteed to not observe daylight savings time;
Expand Down
13 changes: 13 additions & 0 deletions py-polars/tests/unit/datatypes/test_temporal.py
Expand Up @@ -1831,6 +1831,19 @@ def test_ambiguous_expressions() -> None:
assert_series_equal(result, expected)


def test_single_ambiguous_null() -> None:
df = pl.DataFrame(
{"ts": [datetime(2020, 10, 2, 1, 1)], "ambiguous": [None]},
schema_overrides={"ambiguous": pl.String},
)
result = df.select(
pl.col("ts").dt.replace_time_zone(
"Europe/London", ambiguous=pl.col("ambiguous")
)
)["ts"].item()
assert result is None


def test_unlocalize() -> None:
tz_naive = pl.Series(["2020-01-01 03:00:00"]).str.strptime(pl.Datetime)
tz_aware = tz_naive.dt.replace_time_zone("UTC").dt.convert_time_zone(
Expand Down

0 comments on commit 8c2eca9

Please sign in to comment.