Skip to content
23 changes: 22 additions & 1 deletion pandas/core/arrays/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
NaT,
NaTType,
Resolution,
Timedelta,
Timestamp,
astype_overflowsafe,
fields,
Expand Down Expand Up @@ -70,6 +71,7 @@

from pandas.tseries.frequencies import get_period_alias
from pandas.tseries.offsets import (
DateOffset as TSeriesDateOffset,
Day,
Tick,
)
Expand All @@ -93,7 +95,6 @@

from pandas import (
DataFrame,
Timedelta,
)
from pandas.core.arrays import PeriodArray

Expand Down Expand Up @@ -817,7 +818,27 @@ def _add_offset(self, offset: BaseOffset) -> Self:
result = type(self)._from_sequence(res_values, dtype=self.dtype)

else:
units = [
"ns",
"us",
"ms",
"s",
]
res_unit = self.unit
if isinstance(offset, TSeriesDateOffset):
micro = offset.kwds.get("microseconds", 0)
if micro and self.unit != "ns":
res_unit = "us"
elif hasattr(offset, "offset") and offset.offset is not None:
offset_td = Timedelta(offset.offset)
if offset_td.value != 0:
offset_unit = offset_td.unit
idx_self = units.index(self.unit)
idx_offset = units.index(offset_unit)
res_unit = units[min(idx_self, idx_offset)]
result = type(self)._simple_new(res_values, dtype=res_values.dtype)
result = result.as_unit(res_unit)

if offset.normalize:
result = result.normalize()
result._freq = None
Expand Down
17 changes: 17 additions & 0 deletions pandas/tests/arrays/test_datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -844,3 +844,20 @@ def test_factorize_sort_without_freq():
tda = dta - dta[0]
with pytest.raises(NotImplementedError, match=msg):
tda.factorize(sort=True)


def test_dt64_non_nano_offset_no_rounding():
# GH#56586
dti = pd.date_range("2016-01-01", periods=3, unit="s")
offset = pd.offsets.CustomBusinessDay(offset=pd.Timedelta("1ms"))
result = dti + offset

assert result.dtype == np.dtype("datetime64[ms]")
expected = pd.DatetimeIndex(
[
pd.Timestamp("2016-01-02 00:00:00.001"),
pd.Timestamp("2016-01-03 00:00:00.001"),
pd.Timestamp("2016-01-04 00:00:00.001"),
]
)
tm.assert_index_equal(result, expected)
Loading