Skip to content
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
13 changes: 13 additions & 0 deletions pandas/_libs/tslibs/timedeltas.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -2026,6 +2026,19 @@ class Timedelta(_Timedelta):
"milliseconds, microseconds, nanoseconds]"
)

if (
unit is not None
and not (is_float_object(value) or is_integer_object(value))
):
# GH#53198
warnings.warn(
"The 'unit' keyword is only used when the Timedelta input is "
f"an integer or float, not {type(value).__name__}. "
"To specify the storage unit of the output use `td.as_unit(unit)`",
UserWarning,
stacklevel=find_stack_level(),
)

if value is _no_input:
if not len(kwargs):
raise ValueError("cannot construct a Timedelta without a "
Expand Down
14 changes: 14 additions & 0 deletions pandas/_libs/tslibs/timestamps.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ from pandas._libs.tslibs.dtypes cimport (
)
from pandas._libs.tslibs.util cimport (
is_array,
is_float_object,
is_integer_object,
)

Expand Down Expand Up @@ -2654,6 +2655,19 @@ class Timestamp(_Timestamp):
if hasattr(ts_input, "fold"):
ts_input = ts_input.replace(fold=fold)

if (
unit is not None
and not (is_float_object(ts_input) or is_integer_object(ts_input))
):
# GH#53198
warnings.warn(
"The 'unit' keyword is only used when the Timestamp input is "
f"an integer or float, not {type(ts_input).__name__}. "
"To specify the storage unit of the output use `ts.as_unit(unit)`",
UserWarning,
stacklevel=find_stack_level(),
)

# GH 30543 if pd.Timestamp already passed, return it
# check that only ts_input is passed
# checking verbosely, because cython doesn't optimize
Expand Down
5 changes: 4 additions & 1 deletion pandas/core/computation/pytables.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import numpy as np

from pandas._libs import lib
from pandas._libs.tslibs import (
Timedelta,
Timestamp,
Expand Down Expand Up @@ -227,8 +228,10 @@ def stringify(value):
elif kind in ("timedelta64", "timedelta"):
if isinstance(conv_val, str):
conv_val = Timedelta(conv_val)
else:
elif lib.is_integer(conv_val) or lib.is_float(conv_val):
conv_val = Timedelta(conv_val, unit="s")
else:
conv_val = Timedelta(conv_val)
conv_val = conv_val.as_unit("ns")._value
return TermValue(int(conv_val), conv_val, kind)
elif meta == "category":
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/resample.py
Original file line number Diff line number Diff line change
Expand Up @@ -2650,7 +2650,7 @@ def _adjust_bin_edges(
edges_dti = binner.tz_localize(None)
edges_dti = (
edges_dti
+ Timedelta(days=1, unit=edges_dti.unit).as_unit(edges_dti.unit)
+ Timedelta(days=1).as_unit(edges_dti.unit)
- Timedelta(1, unit=edges_dti.unit).as_unit(edges_dti.unit)
)
bin_edges = edges_dti.tz_localize(binner.tz).asi8
Expand Down
5 changes: 4 additions & 1 deletion pandas/core/tools/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,10 @@ def _adjust_to_origin(arg, origin, unit):

# we are going to offset back to unix / epoch time
try:
offset = Timestamp(origin, unit=unit)
if lib.is_integer(origin) or lib.is_float(origin):
offset = Timestamp(origin, unit=unit)
else:
offset = Timestamp(origin)
except OutOfBoundsDatetime as err:
raise OutOfBoundsDatetime(f"origin {origin} is Out of Bounds") from err
except ValueError as err:
Expand Down
11 changes: 9 additions & 2 deletions pandas/tests/scalar/timedelta/test_constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,15 @@ def test_construct_from_td64_with_unit():
# results, and in non-overflow cases is irrelevant GH#46827
obj = np.timedelta64(123456789000000000, "h")

msg = "The 'unit' keyword is only used when the Timedelta input is"

with pytest.raises(OutOfBoundsTimedelta, match="123456789000000000 hours"):
Timedelta(obj, unit="ps")
with tm.assert_produces_warning(UserWarning, match=msg):
Timedelta(obj, unit="ps")

with pytest.raises(OutOfBoundsTimedelta, match="123456789000000000 hours"):
Timedelta(obj, unit="ns")
with tm.assert_produces_warning(UserWarning, match=msg):
Timedelta(obj, unit="ns")

with pytest.raises(OutOfBoundsTimedelta, match="123456789000000000 hours"):
Timedelta(obj)
Expand Down Expand Up @@ -633,6 +637,9 @@ def test_timedelta_pass_td_and_kwargs_raises():
Timedelta(td, days=2)


@pytest.mark.filterwarnings(
"ignore:The 'unit' keyword is only used when the Timedelta input:UserWarning"
)
@pytest.mark.parametrize(
"constructor, value, unit",
[
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/scalar/timedelta/test_timedelta.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def test_mul_preserves_reso(self, td, unit):

def test_cmp_cross_reso(self, td):
# numpy gets this wrong because of silent overflow
other = Timedelta(days=106751, unit="ns")
other = Timedelta(days=106751)
assert other < td
assert td > other
assert not other == td
Expand Down
4 changes: 3 additions & 1 deletion pandas/tests/scalar/timestamp/test_constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -1076,7 +1076,9 @@ def test_timestamp_nano_range(nano):

def test_non_nano_value():
# https://github.com/pandas-dev/pandas/issues/49076
result = Timestamp("1800-01-01", unit="s").value
msg = "The 'unit' keyword is only used when"
with tm.assert_produces_warning(UserWarning, match=msg):
result = Timestamp("1800-01-01", unit="s").value
# `.value` shows nanoseconds, even though unit is 's'
assert result == -5364662400000000000

Expand Down
Loading