Skip to content

Commit cc000e1

Browse files
FIX: Timestamp.replace now reflects changes onto Timestamp.unit (pandas-dev#57749)
1 parent 33af3b8 commit cc000e1

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

pandas/_libs/tslibs/timestamps.pyx

+21-5
Original file line numberDiff line numberDiff line change
@@ -2439,10 +2439,12 @@ default 'raise'
24392439
datetime ts_input
24402440
tzinfo_type tzobj
24412441
_TSObject ts
2442+
NPY_DATETIMEUNIT rep_reso
24422443

24432444
# set to naive if needed
24442445
tzobj = self.tzinfo
24452446
value = self._value
2447+
rep_reso = self._creso
24462448

24472449
# GH 37610. Preserve fold when replacing.
24482450
if fold is None:
@@ -2466,40 +2468,54 @@ default 'raise'
24662468

24672469
if year is not None:
24682470
dts.year = validate("year", year)
2471+
rep_reso = NPY_DATETIMEUNIT.NPY_FR_Y
24692472
if month is not None:
24702473
dts.month = validate("month", month)
2474+
rep_reso = NPY_DATETIMEUNIT.NPY_FR_M
24712475
if day is not None:
24722476
dts.day = validate("day", day)
2477+
rep_reso = NPY_DATETIMEUNIT.NPY_FR_D
24732478
if hour is not None:
24742479
dts.hour = validate("hour", hour)
2480+
rep_reso = NPY_DATETIMEUNIT.NPY_FR_h
24752481
if minute is not None:
24762482
dts.min = validate("minute", minute)
2483+
rep_reso = NPY_DATETIMEUNIT.NPY_FR_m
24772484
if second is not None:
24782485
dts.sec = validate("second", second)
2486+
rep_reso = NPY_DATETIMEUNIT.NPY_FR_s
24792487
if microsecond is not None:
24802488
dts.us = validate("microsecond", microsecond)
2489+
if microsecond > 999:
2490+
rep_reso = NPY_DATETIMEUNIT.NPY_FR_us
2491+
else:
2492+
rep_reso = NPY_DATETIMEUNIT.NPY_FR_ms
24812493
if nanosecond is not None:
24822494
dts.ps = validate("nanosecond", nanosecond) * 1000
2495+
rep_reso = NPY_DATETIMEUNIT.NPY_FR_ns
24832496
if tzinfo is not object:
24842497
tzobj = tzinfo
24852498

2499+
if rep_reso < self._creso:
2500+
rep_reso = self._creso
2501+
24862502
# reconstruct & check bounds
24872503
if tzobj is None:
24882504
# We can avoid going through pydatetime paths, which is robust
24892505
# to datetimes outside of pydatetime range.
24902506
ts = _TSObject()
24912507
try:
2492-
ts.value = npy_datetimestruct_to_datetime(self._creso, &dts)
2508+
ts.value = npy_datetimestruct_to_datetime(rep_reso, &dts)
24932509
except OverflowError as err:
24942510
fmt = dts_to_iso_string(&dts)
24952511
raise OutOfBoundsDatetime(
24962512
f"Out of bounds timestamp: {fmt} with frequency '{self.unit}'"
24972513
) from err
24982514
ts.dts = dts
2499-
ts.creso = self._creso
2515+
ts.creso = rep_reso
25002516
ts.fold = fold
25012517
return create_timestamp_from_ts(
2502-
ts.value, dts, tzobj, fold, reso=self._creso
2518+
ts.value, dts, tzobj, fold, reso=rep_reso
25032519
)
25042520

25052521
elif tzobj is not None and treat_tz_as_pytz(tzobj):
@@ -2518,10 +2534,10 @@ default 'raise'
25182534
ts_input = datetime(**kwargs)
25192535

25202536
ts = convert_datetime_to_tsobject(
2521-
ts_input, tzobj, nanos=dts.ps // 1000, reso=self._creso
2537+
ts_input, tzobj, nanos=dts.ps // 1000, reso=rep_reso
25222538
)
25232539
return create_timestamp_from_ts(
2524-
ts.value, dts, tzobj, fold, reso=self._creso
2540+
ts.value, dts, tzobj, fold, reso=rep_reso
25252541
)
25262542

25272543
def to_julian_date(self) -> np.float64:

0 commit comments

Comments
 (0)