diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index cfb697b3c357ab..a6d9fef3f5baf5 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -1018,7 +1018,7 @@ def _add_nat(self): # and datetime dtypes result = np.zeros(len(self), dtype=np.int64) result.fill(iNaT) - return type(self)(result, dtype=self.dtype, freq=None) + return type(self)._simple_new(result, dtype=self.dtype, freq=None) def _sub_nat(self): """ diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index efa1757a989fc8..8d1eb22e6a63a3 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -141,7 +141,7 @@ def wrapper(self, other): else: if isinstance(other, list): try: - other = type(self)._from_sequence(other) + other = type(self)._from_sequence_dti(other) except ValueError: other = np.array(other, dtype=np.object_) elif not isinstance(other, (np.ndarray, ABCIndexClass, ABCSeries, @@ -173,7 +173,7 @@ def wrapper(self, other): not hasattr(other, 'asi8')): # e.g. other.dtype == 'datetime64[s]' # or an object-dtype ndarray - other = type(self)._from_sequence(other) + other = type(self)._from_sequence_dti(other) result = op(self.view('i8'), other.view('i8')) o_mask = other._isnan @@ -327,9 +327,13 @@ def _simple_new(cls, values, freq=None, dtype=None): return cls(values, freq=freq, dtype=dtype) @classmethod - def _from_sequence(cls, data, dtype=None, copy=False, - tz=None, freq=None, - dayfirst=False, yearfirst=False, ambiguous='raise'): + def _from_sequence(cls, scalars, dtype=None, copy=False): + assert all(isinstance(x, Timestamp) for x in scalars) + + @classmethod + def _from_sequence_dti(cls, data, dtype=None, copy=False, + tz=None, freq=None, + dayfirst=False, yearfirst=False, ambiguous='raise'): freq, freq_infer = dtl.maybe_infer_freq(freq) @@ -735,7 +739,9 @@ def _add_delta(self, delta): result : DatetimeArray """ new_values = super(DatetimeArray, self)._add_delta(delta) - return type(self)._from_sequence(new_values, tz=self.tz, freq='infer') + result = type(self)(new_values, dtype=self.dtype) + result._freq = result.inferred_freq + return result # ----------------------------------------------------------------- # Timezone Conversion and Localization Methods @@ -1074,8 +1080,8 @@ def normalize(self): new_values[not_null] = new_values[not_null] - adjustment else: new_values = conversion.normalize_i8_timestamps(self.asi8, self.tz) - return type(self)._from_sequence(new_values, - freq='infer').tz_localize(self.tz) + result = type(self)._from_sequence_dti(new_values, freq='infer') + resutn result.tz_localize(self.tz) def to_period(self, freq=None): """ @@ -1664,6 +1670,7 @@ def sequence_to_dt64ns(data, dtype=None, copy=False, """ inferred_freq = None + inferred_tz = None dtype = _validate_dt64_dtype(dtype) @@ -1712,9 +1719,18 @@ def sequence_to_dt64ns(data, dtype=None, copy=False, tz = maybe_infer_tz(tz, data.tz) result = data._data - elif is_datetime64_dtype(data): + elif inferred_tz is not None: + # data returned from objects_to_datetime64ns represenet unix# + # timestamps + assert data.dtype == 'i8', data.dtype + result = data.view(_NS_DTYPE) + + elif is_datetime64_dtype(data) or data.dtype == 'i8': # tz-naive DatetimeArray or ndarray[datetime64] data = getattr(data, "_data", data) + if data.dtype == 'i8': + data = data.view(_NS_DTYPE) + if data.dtype != _NS_DTYPE: data = conversion.ensure_datetime64ns(data)