Skip to content

Commit e98fa3c

Browse files
committed
fix(pandas): fix integer wraparound when extracting epoch seconds
1 parent 7bb0470 commit e98fa3c

File tree

3 files changed

+20
-6
lines changed

3 files changed

+20
-6
lines changed

ibis/backends/dask/execution/temporal.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
execute_date_sub_diff_series_date,
3333
execute_day_of_week_index_series,
3434
execute_day_of_week_name_series,
35-
execute_epoch_seconds,
35+
execute_epoch_seconds_series,
3636
execute_extract_microsecond_series,
3737
execute_extract_millisecond_series,
3838
execute_extract_timestamp_field_series,
@@ -61,7 +61,7 @@
6161
ops.ExtractTemporalField: [((dd.Series,), execute_extract_timestamp_field_series)],
6262
ops.ExtractMicrosecond: [((dd.Series,), execute_extract_microsecond_series)],
6363
ops.ExtractMillisecond: [((dd.Series,), execute_extract_millisecond_series)],
64-
ops.ExtractEpochSeconds: [((dd.Series,), execute_epoch_seconds)],
64+
ops.ExtractEpochSeconds: [((dd.Series,), execute_epoch_seconds_series)],
6565
ops.IntervalFromInteger: [((dd.Series,), execute_interval_from_integer_series)],
6666
ops.IntervalAdd: [
6767
(

ibis/backends/pandas/execution/temporal.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,19 @@ def execute_extract_microsecond_series(op, data, **kwargs):
6565
return data.dt.microsecond.astype(np.int32)
6666

6767

68-
@execute_node.register(ops.ExtractEpochSeconds, (datetime.datetime, pd.Series))
69-
def execute_epoch_seconds(op, data, **kwargs):
70-
return data.astype("datetime64[s]").astype("int64").astype("int32")
68+
@execute_node.register(ops.ExtractEpochSeconds, pd.Series)
69+
def execute_epoch_seconds_series(op, data, **kwargs):
70+
return (
71+
data.astype("datetime64[ns]")
72+
.astype("int64")
73+
.floordiv(1_000_000_000)
74+
.astype("int32")
75+
)
76+
77+
78+
@execute_node.register(ops.ExtractEpochSeconds, (pd.Timestamp, datetime.datetime))
79+
def execute_epoch_seconds_literal(op, data, **kwargs):
80+
return pd.Timestamp(data).floor("s").value // 1_000_000_000
7181

7282

7383
@execute_node.register(

ibis/backends/tests/test_temporal.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,11 @@ def test_timestamp_extract_epoch_seconds(backend, alltypes, df):
354354
result = expr.execute()
355355

356356
expected = backend.default_series_rename(
357-
df.timestamp_col.astype("datetime64[s]").astype("int64").astype("int32")
357+
df.timestamp_col.astype("datetime64[ns]")
358+
.dt.floor("s")
359+
.astype("int64")
360+
.floordiv(1_000_000_000)
361+
.astype("int32")
358362
)
359363
backend.assert_series_equal(result, expected)
360364

0 commit comments

Comments
 (0)