Skip to content

Commit fbd39d9

Browse files
jbrockmendeljreback
authored andcommitted
Have DTA._simple_new take dtype instead of tz (#24665)
1 parent 4e7f074 commit fbd39d9

File tree

5 files changed

+46
-31
lines changed

5 files changed

+46
-31
lines changed

pandas/core/arrays/datetimelike.py

+6-11
Original file line numberDiff line numberDiff line change
@@ -296,12 +296,11 @@ def _round(self, freq, mode, ambiguous, nonexistent):
296296
result = round_nsint64(values, mode, freq)
297297
result = self._maybe_mask_results(result, fill_value=NaT)
298298

299-
attribs = self._get_attributes_dict()
300-
attribs['freq'] = None
301-
if 'tz' in attribs:
302-
attribs['tz'] = None
299+
dtype = self.dtype
300+
if is_datetime64tz_dtype(self):
301+
dtype = None
303302
return self._ensure_localized(
304-
self._simple_new(result, **attribs), ambiguous, nonexistent
303+
self._simple_new(result, dtype=dtype), ambiguous, nonexistent
305304
)
306305

307306
@Appender((_round_doc + _round_example).format(op="round"))
@@ -434,8 +433,6 @@ def __getitem__(self, key):
434433
else:
435434
key = lib.maybe_booleans_to_slice(key.view(np.uint8))
436435

437-
attribs = self._get_attributes_dict()
438-
439436
is_period = is_period_dtype(self)
440437
if is_period:
441438
freq = self.freq
@@ -451,17 +448,15 @@ def __getitem__(self, key):
451448
# should preserve `freq` attribute
452449
freq = self.freq
453450

454-
attribs['freq'] = freq
455-
456451
result = getitem(key)
457452
if result.ndim > 1:
458453
# To support MPL which performs slicing with 2 dim
459454
# even though it only has 1 dim by definition
460455
if is_period:
461-
return self._simple_new(result, **attribs)
456+
return self._simple_new(result, dtype=self.dtype, freq=freq)
462457
return result
463458

464-
return self._simple_new(result, **attribs)
459+
return self._simple_new(result, dtype=self.dtype, freq=freq)
465460

466461
def __setitem__(
467462
self,

pandas/core/arrays/datetimes.py

+30-13
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,24 @@
3535
_midnight = time(0, 0)
3636

3737

38+
def tz_to_dtype(tz):
39+
"""
40+
Return a datetime64[ns] dtype appropriate for the given timezone.
41+
42+
Parameters
43+
----------
44+
tz : tzinfo or None
45+
46+
Returns
47+
-------
48+
np.dtype or Datetime64TZDType
49+
"""
50+
if tz is None:
51+
return _NS_DTYPE
52+
else:
53+
return DatetimeTZDtype(tz=tz)
54+
55+
3856
def _to_M8(key, tz=None):
3957
"""
4058
Timestamp-like => dt64
@@ -305,13 +323,7 @@ def __init__(self, values, dtype=_NS_DTYPE, freq=None, copy=False):
305323
self._freq = freq
306324

307325
@classmethod
308-
def _simple_new(cls, values, freq=None, tz=None):
309-
"""
310-
we require the we have a dtype compat for the values
311-
if we are passed a non-dtype compat, then coerce using the constructor
312-
"""
313-
dtype = DatetimeTZDtype(tz=tz) if tz else _NS_DTYPE
314-
326+
def _simple_new(cls, values, freq=None, dtype=None):
315327
return cls(values, freq=freq, dtype=dtype)
316328

317329
@classmethod
@@ -328,7 +340,8 @@ def _from_sequence(cls, data, dtype=None, copy=False,
328340
freq, freq_infer = dtl.validate_inferred_freq(freq, inferred_freq,
329341
freq_infer)
330342

331-
result = cls._simple_new(subarr, freq=freq, tz=tz)
343+
dtype = tz_to_dtype(tz)
344+
result = cls._simple_new(subarr, freq=freq, dtype=dtype)
332345

333346
if inferred_freq is None and freq is not None:
334347
# this condition precludes `freq_infer`
@@ -395,7 +408,7 @@ def _generate_range(cls, start, end, periods, freq, tz=None,
395408
end = end.tz_localize(None)
396409
# TODO: consider re-implementing _cached_range; GH#17914
397410
values, _tz = generate_regular_range(start, end, periods, freq)
398-
index = cls._simple_new(values, freq=freq, tz=_tz)
411+
index = cls._simple_new(values, freq=freq, dtype=tz_to_dtype(_tz))
399412

400413
if tz is not None and index.tz is None:
401414
arr = conversion.tz_localize_to_utc(
@@ -418,16 +431,18 @@ def _generate_range(cls, start, end, periods, freq, tz=None,
418431
arr = np.linspace(
419432
0, end.value - start.value,
420433
periods, dtype='int64') + start.value
434+
dtype = tz_to_dtype(tz)
421435
index = cls._simple_new(
422-
arr.astype('M8[ns]', copy=False), freq=None, tz=tz
436+
arr.astype('M8[ns]', copy=False), freq=None, dtype=dtype
423437
)
424438

425439
if not left_closed and len(index) and index[0] == start:
426440
index = index[1:]
427441
if not right_closed and len(index) and index[-1] == end:
428442
index = index[:-1]
429443

430-
return cls._simple_new(index.asi8, freq=freq, tz=tz)
444+
dtype = tz_to_dtype(tz)
445+
return cls._simple_new(index.asi8, freq=freq, dtype=dtype)
431446

432447
# -----------------------------------------------------------------
433448
# DatetimeLike Interface
@@ -806,7 +821,8 @@ def tz_convert(self, tz):
806821
'tz_localize to localize')
807822

808823
# No conversion since timestamps are all UTC to begin with
809-
return self._simple_new(self.asi8, tz=tz, freq=self.freq)
824+
dtype = tz_to_dtype(tz)
825+
return self._simple_new(self.asi8, dtype=dtype, freq=self.freq)
810826

811827
def tz_localize(self, tz, ambiguous='raise', nonexistent='raise',
812828
errors=None):
@@ -995,7 +1011,8 @@ def tz_localize(self, tz, ambiguous='raise', nonexistent='raise',
9951011
self.asi8, tz, ambiguous=ambiguous, nonexistent=nonexistent,
9961012
)
9971013
new_dates = new_dates.view(_NS_DTYPE)
998-
return self._simple_new(new_dates, tz=tz, freq=self.freq)
1014+
dtype = tz_to_dtype(tz)
1015+
return self._simple_new(new_dates, dtype=dtype, freq=self.freq)
9991016

10001017
# ----------------------------------------------------------------
10011018
# Conversion Methods - Vectorized analogues of Timestamp methods

pandas/core/indexes/datetimes.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
from pandas.core.accessor import delegate_names
2424
from pandas.core.arrays.datetimes import (
25-
DatetimeArray, _to_M8, validate_tz_from_dtype)
25+
DatetimeArray, _to_M8, tz_to_dtype, validate_tz_from_dtype)
2626
from pandas.core.base import _shared_docs
2727
import pandas.core.common as com
2828
from pandas.core.indexes.base import Index
@@ -326,7 +326,9 @@ def _simple_new(cls, values, name=None, freq=None, tz=None, dtype=None):
326326
# DatetimeArray._simple_new will accept either i8 or M8[ns] dtypes
327327
if isinstance(values, DatetimeIndex):
328328
values = values._data
329-
dtarr = DatetimeArray._simple_new(values, freq=freq, tz=tz)
329+
330+
dtype = tz_to_dtype(tz)
331+
dtarr = DatetimeArray._simple_new(values, freq=freq, dtype=dtype)
330332
assert isinstance(dtarr, DatetimeArray)
331333

332334
result = object.__new__(cls)
@@ -401,7 +403,8 @@ def __setstate__(self, state):
401403

402404
freq = own_state[1]
403405
tz = timezones.tz_standardize(own_state[2])
404-
dtarr = DatetimeArray._simple_new(data, freq=freq, tz=tz)
406+
dtype = tz_to_dtype(tz)
407+
dtarr = DatetimeArray._simple_new(data, freq=freq, dtype=dtype)
405408

406409
self.name = own_state[0]
407410

pandas/core/internals/blocks.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2389,7 +2389,7 @@ def _try_coerce_result(self, result):
23892389
result = result.reshape(np.prod(result.shape))
23902390
# GH#24096 new values invalidates a frequency
23912391
result = self._holder._simple_new(result, freq=None,
2392-
tz=self.values.tz)
2392+
dtype=self.values.dtype)
23932393

23942394
return result
23952395

pandas/tseries/offsets.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -935,7 +935,7 @@ def apply_index(self, i):
935935
shifted = liboffsets.shift_months(i.asi8, self.n, self._day_opt)
936936
# TODO: going through __new__ raises on call to _validate_frequency;
937937
# are we passing incorrect freq?
938-
return type(i)._simple_new(shifted, freq=i.freq, tz=i.tz)
938+
return type(i)._simple_new(shifted, freq=i.freq, dtype=i.dtype)
939939

940940

941941
class MonthEnd(MonthOffset):
@@ -1642,7 +1642,7 @@ def apply_index(self, dtindex):
16421642
# TODO: going through __new__ raises on call to _validate_frequency;
16431643
# are we passing incorrect freq?
16441644
return type(dtindex)._simple_new(shifted, freq=dtindex.freq,
1645-
tz=dtindex.tz)
1645+
dtype=dtindex.dtype)
16461646

16471647

16481648
class BQuarterEnd(QuarterOffset):
@@ -1722,7 +1722,7 @@ def apply_index(self, dtindex):
17221722
# TODO: going through __new__ raises on call to _validate_frequency;
17231723
# are we passing incorrect freq?
17241724
return type(dtindex)._simple_new(shifted, freq=dtindex.freq,
1725-
tz=dtindex.tz)
1725+
dtype=dtindex.dtype)
17261726

17271727
def onOffset(self, dt):
17281728
if self.normalize and not _is_normalized(dt):

0 commit comments

Comments
 (0)