27
27
import pandas .core .common as com
28
28
from pandas .core .indexes .base import Index
29
29
from pandas .core .indexes .datetimelike import (
30
- DatelikeIndexMixin , DatetimeIndexOpsMixin , DatetimelikeDelegateMixin )
30
+ DatelikeIndexMixin , DatetimeIndexOpsMixin , DatetimelikeDelegateMixin ,
31
+ ea_passthrough )
31
32
from pandas .core .indexes .numeric import Int64Index
32
33
from pandas .core .ops import get_op_result_name
33
34
import pandas .core .tools .datetimes as tools
@@ -91,11 +92,6 @@ class DatetimeDelegateMixin(DatetimelikeDelegateMixin):
91
92
_delegate_class = DatetimeArray
92
93
93
94
94
- @delegate_names (DatetimeArray , ["to_period" , "tz_localize" , "tz_convert" ,
95
- "day_name" , "month_name" ],
96
- typ = "method" , overwrite = True )
97
- @delegate_names (DatetimeArray ,
98
- DatetimeArray ._field_ops , typ = "property" , overwrite = True )
99
95
@delegate_names (DatetimeArray ,
100
96
DatetimeDelegateMixin ._delegated_properties ,
101
97
typ = "property" )
@@ -265,6 +261,7 @@ def _join_i8_wrapper(joinf, **kwargs):
265
261
_object_ops = DatetimeArray ._object_ops
266
262
_field_ops = DatetimeArray ._field_ops
267
263
_datetimelike_ops = DatetimeArray ._datetimelike_ops
264
+ _datetimelike_methods = DatetimeArray ._datetimelike_methods
268
265
269
266
# --------------------------------------------------------------------
270
267
# Constructors
@@ -283,16 +280,16 @@ def __new__(cls, data=None,
283
280
verify_integrity = True
284
281
285
282
if data is None :
286
- result = DatetimeArray ._generate_range (
283
+ dtarr = DatetimeArray ._generate_range (
287
284
start , end , periods ,
288
285
freq = freq , tz = tz , normalize = normalize ,
289
286
closed = closed , ambiguous = ambiguous )
290
287
warnings .warn ("Creating a DatetimeIndex by passing range "
291
288
"endpoints is deprecated. Use "
292
289
"`pandas.date_range` instead." ,
293
290
FutureWarning , stacklevel = 2 )
294
-
295
- return cls ( result , name = name )
291
+ return cls . _simple_new (
292
+ dtarr . _data , freq = dtarr . freq , tz = dtarr . tz , name = name )
296
293
297
294
if is_scalar (data ):
298
295
raise TypeError ("{cls}() must be called with a "
@@ -320,7 +317,11 @@ def _simple_new(cls, values, name=None, freq=None, tz=None, dtype=None):
320
317
# DatetimeArray._simple_new will accept either i8 or M8[ns] dtypes
321
318
values = DatetimeArray ._simple_new (values , freq = freq , tz = tz )
322
319
323
- result = super (DatetimeIndex , cls )._simple_new (values , freq , tz )
320
+ dtarr = DatetimeArray ._simple_new (values , freq = freq , tz = tz )
321
+ result = object .__new__ (cls )
322
+ result ._data = dtarr ._data
323
+ result ._freq = dtarr .freq
324
+ result ._tz = dtarr .tz
324
325
result .name = name
325
326
# For groupby perf. See note in indexes/base about _index_data
326
327
result ._index_data = values ._data
@@ -329,6 +330,32 @@ def _simple_new(cls, values, name=None, freq=None, tz=None, dtype=None):
329
330
330
331
# --------------------------------------------------------------------
331
332
333
+ @property
334
+ def dtype (self ):
335
+ return self ._eadata .dtype
336
+
337
+ @property
338
+ def _values (self ):
339
+ # tz-naive -> ndarray
340
+ # tz-aware -> DatetimeIndex
341
+ if self .tz is not None :
342
+ return self
343
+ else :
344
+ return self .values
345
+
346
+ @property
347
+ def tz (self ):
348
+ # GH 18595
349
+ return self ._tz
350
+
351
+ @tz .setter
352
+ def tz (self , value ):
353
+ # GH 3746: Prevent localizing or converting the index by setting tz
354
+ raise AttributeError ("Cannot directly set timezone. Use tz_localize() "
355
+ "or tz_convert() as appropriate" )
356
+
357
+ tzinfo = tz
358
+
332
359
@property
333
360
def size (self ):
334
361
# TODO: Remove this when we have a DatetimeTZArray
@@ -646,7 +673,7 @@ def intersection(self, other):
646
673
def _get_time_micros (self ):
647
674
values = self .asi8
648
675
if self .tz is not None and not timezones .is_utc (self .tz ):
649
- values = self ._local_timestamps ()
676
+ values = self ._eadata . _local_timestamps ()
650
677
return fields .get_time_micros (values )
651
678
652
679
def to_series (self , keep_tz = None , index = None , name = None ):
@@ -1115,12 +1142,64 @@ def _eadata(self):
1115
1142
_is_monotonic_increasing = Index .is_monotonic_increasing
1116
1143
_is_monotonic_decreasing = Index .is_monotonic_decreasing
1117
1144
_is_unique = Index .is_unique
1118
- astype = DatetimeIndexOpsMixin .astype
1119
1145
1120
1146
_timezone = cache_readonly (DatetimeArray ._timezone .fget )
1121
1147
is_normalized = cache_readonly (DatetimeArray .is_normalized .fget )
1122
1148
_resolution = cache_readonly (DatetimeArray ._resolution .fget )
1123
1149
1150
+ strftime = ea_passthrough ("strftime" )
1151
+ _has_same_tz = ea_passthrough ("_has_same_tz" )
1152
+ __array__ = ea_passthrough ("__array__" )
1153
+
1154
+ @property
1155
+ def offset (self ):
1156
+ """
1157
+ get/set the frequency of the instance
1158
+ """
1159
+ msg = ('{cls}.offset has been deprecated and will be removed '
1160
+ 'in a future version; use {cls}.freq instead.'
1161
+ .format (cls = type (self ).__name__ ))
1162
+ warnings .warn (msg , FutureWarning , stacklevel = 2 )
1163
+ return self .freq
1164
+
1165
+ @offset .setter
1166
+ def offset (self , value ):
1167
+ """
1168
+ get/set the frequency of the instance
1169
+ """
1170
+ msg = ('{cls}.offset has been deprecated and will be removed '
1171
+ 'in a future version; use {cls}.freq instead.'
1172
+ .format (cls = type (self ).__name__ ))
1173
+ warnings .warn (msg , FutureWarning , stacklevel = 2 )
1174
+ self .freq = value
1175
+
1176
+ @property
1177
+ def freq (self ):
1178
+ return self ._freq
1179
+
1180
+ @freq .setter
1181
+ def freq (self , value ):
1182
+ if value is not None :
1183
+ # let DatetimeArray to validation
1184
+ self ._eadata .freq = value
1185
+
1186
+ self ._freq = to_offset (value )
1187
+
1188
+ def __getitem__ (self , key ):
1189
+ result = self ._eadata .__getitem__ (key )
1190
+ if is_scalar (result ):
1191
+ return result
1192
+ elif result .ndim > 1 :
1193
+ # To support MPL which performs slicing with 2 dim
1194
+ # even though it only has 1 dim by definition
1195
+ assert isinstance (result , np .ndarray ), result
1196
+ return result
1197
+ return type (self )(result , name = self .name )
1198
+
1199
+ @property
1200
+ def _box_func (self ):
1201
+ return lambda x : Timestamp (x , tz = self .tz )
1202
+
1124
1203
# --------------------------------------------------------------------
1125
1204
1126
1205
@Substitution (klass = 'DatetimeIndex' )
@@ -1462,7 +1541,8 @@ def date_range(start=None, end=None, periods=None, freq=None, tz=None,
1462
1541
start = start , end = end , periods = periods ,
1463
1542
freq = freq , tz = tz , normalize = normalize ,
1464
1543
closed = closed , ** kwargs )
1465
- return DatetimeIndex (dtarr , name = name )
1544
+ return DatetimeIndex ._simple_new (
1545
+ dtarr ._data , tz = dtarr .tz , freq = dtarr .freq , name = name )
1466
1546
1467
1547
1468
1548
def bdate_range (start = None , end = None , periods = None , freq = 'B' , tz = None ,
0 commit comments