@@ -802,6 +802,8 @@ def _add_offset(self, offset: BaseOffset) -> Self:
802802 else :
803803 values = self
804804
805+ units = ["ns" , "us" , "ms" , "s" ]
806+
805807 try :
806808 res_values = offset ._apply_array (values ._ndarray )
807809 if res_values .dtype .kind == "i" :
@@ -814,45 +816,27 @@ def _add_offset(self, offset: BaseOffset) -> Self:
814816 PerformanceWarning ,
815817 stacklevel = find_stack_level (),
816818 )
817-
818819 # Handle non-vectorized DateOffsets with both calendar and
819820 # timedelta parts, preserving time resolution.
820- if getattr (offset , "offset" , None ):
821- try :
822- kwds = offset .kwds .copy ()
823- if "offset" in kwds :
824- del kwds ["offset" ]
825- base_offset = type (offset )(** kwds )
826- result = self ._add_offset (base_offset ) + offset .offset
827-
828- offset_td = Timedelta (offset .offset )
829- offset_unit = offset_td .unit
830- if offset_unit == "ns" :
831- res_str = offset_td .resolution_string
832- if res_str in ["ms" , "us" , "s" ]:
833- offset_unit = res_str
834-
835- units = ["ns" , "us" , "ms" , "s" ]
836- if self .unit in units and offset_unit in units :
837- idx_self = units .index (self .unit )
838- idx_offset = units .index (offset_unit )
839- res_unit = units [min (idx_self , idx_offset )]
840- return result .as_unit (res_unit )
841-
842- return result
843- except Exception :
844- pass
845-
846- res_values = self .astype ("O" ) + offset
847- result = type (self )._from_sequence (res_values , dtype = self .dtype )
821+ values_ns = values .as_unit ("ns" ) if values .unit != "ns" else values
822+ res_values = np .array ([ts + offset for ts in values_ns ], dtype = object )
823+
824+ res_unit = self .unit
825+
826+ off = getattr (offset , "offset" , None )
827+ if off is not None :
828+ offset_td = Timedelta (off )
829+ if offset_td .value != 0 :
830+ offset_unit = offset_td .resolution_string
831+ if self .unit in units and offset_unit in units :
832+ idx_self = units .index (self .unit )
833+ idx_offset = units .index (offset_unit )
834+ res_unit = units [min (idx_self , idx_offset )]
835+
836+ dtype = np .dtype (f"datetime64[{ res_unit } ]" )
837+ result = type (self )._from_sequence (res_values , dtype = dtype )
848838
849839 else :
850- units = [
851- "ns" ,
852- "us" ,
853- "ms" ,
854- "s" ,
855- ]
856840 res_unit = self .unit
857841 if type (offset ) is DateOffset :
858842 if "nanoseconds" in offset .kwds :
@@ -869,12 +853,12 @@ def _add_offset(self, offset: BaseOffset) -> Self:
869853 result = type (self )._simple_new (res_values , dtype = res_values .dtype )
870854 result = result .as_unit (res_unit )
871855
872- if offset .normalize :
873- result = result .normalize ()
874- result ._freq = None
856+ if offset .normalize :
857+ result = result .normalize ()
858+ result ._freq = None
875859
876- if self .tz is not None :
877- result = result .tz_localize (self .tz )
860+ if self .tz is not None :
861+ result = result .tz_localize (self .tz )
878862
879863 return result
880864
0 commit comments