@@ -49,10 +49,10 @@ TD_DTYPE = np.dtype('m8[ns]')
49
49
50
50
UTC = pytz.UTC
51
51
52
+
52
53
# ----------------------------------------------------------------------
53
54
# Misc Helpers
54
55
55
- # TODO: How to declare np.datetime64 as the input type?
56
56
cdef inline int64_t get_datetime64_nanos(object val) except ? - 1 :
57
57
"""
58
58
Extract the value and unit from a np.datetime64 object, then convert the
@@ -74,7 +74,7 @@ cdef inline int64_t get_datetime64_nanos(object val) except? -1:
74
74
return ival
75
75
76
76
77
- def ensure_datetime64ns (ndarray arr , copy = True ):
77
+ def ensure_datetime64ns (arr: ndarray , copy: bint = True ):
78
78
"""
79
79
Ensure a np.datetime64 array has dtype specifically 'datetime64[ns]'
80
80
@@ -121,7 +121,7 @@ def ensure_datetime64ns(ndarray arr, copy=True):
121
121
return result
122
122
123
123
124
- def ensure_timedelta64ns (ndarray arr , copy = True ):
124
+ def ensure_timedelta64ns (arr: ndarray , copy: bint = True ):
125
125
"""
126
126
Ensure a np.timedelta64 array has dtype specifically 'timedelta64[ns]'
127
127
@@ -133,23 +133,23 @@ def ensure_timedelta64ns(ndarray arr, copy=True):
133
133
Returns
134
134
-------
135
135
result : ndarray with dtype timedelta64[ns]
136
-
137
136
"""
138
137
return arr.astype(TD_DTYPE, copy = copy)
138
+ # TODO: check for overflows when going from a lower-resolution to nanos
139
139
140
140
141
- def datetime_to_datetime64 (object[:] values ):
141
+ def datetime_to_datetime64 (values: object[:]):
142
142
"""
143
143
Convert ndarray of datetime-like objects to int64 array representing
144
144
nanosecond timestamps.
145
145
146
146
Parameters
147
147
----------
148
- values : ndarray
148
+ values : ndarray[object]
149
149
150
150
Returns
151
151
-------
152
- result : ndarray with dtype int64
152
+ result : ndarray[int64_t]
153
153
inferred_tz : tzinfo or None
154
154
"""
155
155
cdef:
@@ -225,6 +225,7 @@ cdef class _TSObject:
225
225
226
226
@property
227
227
def value (self ):
228
+ # This is needed in order for `value` to be accessible in lib.pyx
228
229
return self .value
229
230
230
231
@@ -849,10 +850,11 @@ def tz_localize_to_utc(ndarray[int64_t] vals, object tz, object ambiguous=None,
849
850
ndarray[int64_t] trans
850
851
int64_t[:] deltas, idx_shifted
851
852
ndarray ambiguous_array
852
- Py_ssize_t i, idx, pos, ntrans, n = len (vals)
853
+ Py_ssize_t i, idx, pos, pos_left, pos_right, ntrans, n = len (vals)
853
854
int64_t * tdata
854
- int64_t v, left, right, val, v_left, v_right
855
- ndarray[int64_t] result, result_a, result_b, dst_hours
855
+ int64_t v, left, right, val, v_left, v_right, delta_idx
856
+ int64_t[:] result, dst_hours, idx_shifted_left, idx_shifted_right
857
+ ndarray[int64_t] result_a, result_b
856
858
npy_datetimestruct dts
857
859
bint infer_dst = False , is_dst = False , fill = False
858
860
bint shift = False , fill_nonexist = False
@@ -867,7 +869,7 @@ def tz_localize_to_utc(ndarray[int64_t] vals, object tz, object ambiguous=None,
867
869
for i in range (n):
868
870
v = vals[i]
869
871
result[i] = _tz_convert_tzlocal_utc(v, tz, to_utc = True )
870
- return result
872
+ return result.base # `.base` to access underlying np.array
871
873
872
874
if is_string_object(ambiguous):
873
875
if ambiguous == ' infer' :
@@ -929,7 +931,7 @@ def tz_localize_to_utc(ndarray[int64_t] vals, object tz, object ambiguous=None,
929
931
930
932
if infer_dst:
931
933
dst_hours = np.empty(n, dtype = np.int64)
932
- dst_hours.fill( NPY_NAT)
934
+ dst_hours[:] = NPY_NAT
933
935
934
936
# Get the ambiguous hours (given the above, these are the hours
935
937
# where result_a != result_b and neither of them are NAT)
@@ -970,7 +972,13 @@ def tz_localize_to_utc(ndarray[int64_t] vals, object tz, object ambiguous=None,
970
972
# Pull the only index and adjust
971
973
a_idx = grp[:switch_idx]
972
974
b_idx = grp[switch_idx:]
973
- dst_hours[grp] = np.hstack((result_a[a_idx], result_b[b_idx]))
975
+
976
+ # __setitem__ on dst_hours.base because indexing with
977
+ # an ndarray (grp) directly on a memoryview is not supported
978
+ # TODO: is `grp` necessarily contiguous? i.e. could we
979
+ # equivalently write dst_hours[grp[0]:grp[-1]] = ... ?
980
+ dst_hours.base[grp] = np.hstack((result_a[a_idx],
981
+ result_b[b_idx]))
974
982
975
983
for i in range (n):
976
984
val = vals[i]
@@ -1015,7 +1023,7 @@ def tz_localize_to_utc(ndarray[int64_t] vals, object tz, object ambiguous=None,
1015
1023
stamp = _render_tstamp(val)
1016
1024
raise pytz.NonExistentTimeError(stamp)
1017
1025
1018
- return result
1026
+ return result.base # `.base` to access underlying np.array
1019
1027
1020
1028
1021
1029
cdef inline bisect_right_i8(int64_t * data, int64_t val, Py_ssize_t n):
@@ -1051,7 +1059,7 @@ cdef inline str _render_tstamp(int64_t val):
1051
1059
# Normalization
1052
1060
1053
1061
1054
- def normalize_date (object dt ) :
1062
+ def normalize_date (dt: object ) -> datetime :
1055
1063
"""
1056
1064
Normalize datetime.datetime value to midnight. Returns datetime.date as a
1057
1065
datetime.datetime at midnight
@@ -1085,7 +1093,7 @@ def normalize_date(object dt):
1085
1093
1086
1094
@ cython.wraparound (False )
1087
1095
@ cython.boundscheck (False )
1088
- def normalize_i8_timestamps (int64_t[:] stamps , tz = None ):
1096
+ def normalize_i8_timestamps (int64_t[:] stamps , object tz = None ):
1089
1097
"""
1090
1098
Normalize each of the (nanosecond) timestamps in the given array by
1091
1099
rounding down to the beginning of the day (i.e. midnight). If `tz`
@@ -1122,7 +1130,7 @@ def normalize_i8_timestamps(int64_t[:] stamps, tz=None):
1122
1130
1123
1131
@ cython.wraparound (False )
1124
1132
@ cython.boundscheck (False )
1125
- cdef int64_t[:] _normalize_local(int64_t[:] stamps, object tz):
1133
+ cdef int64_t[:] _normalize_local(int64_t[:] stamps, tzinfo tz):
1126
1134
"""
1127
1135
Normalize each of the (nanosecond) timestamps in the given array by
1128
1136
rounding down to the beginning of the day (i.e. midnight) for the
@@ -1131,7 +1139,7 @@ cdef int64_t[:] _normalize_local(int64_t[:] stamps, object tz):
1131
1139
Parameters
1132
1140
----------
1133
1141
stamps : int64 ndarray
1134
- tz : tzinfo or None
1142
+ tz : tzinfo
1135
1143
1136
1144
Returns
1137
1145
-------
@@ -1207,7 +1215,7 @@ cdef inline int64_t _normalized_stamp(npy_datetimestruct *dts) nogil:
1207
1215
return dtstruct_to_dt64(dts)
1208
1216
1209
1217
1210
- def is_date_array_normalized (int64_t[:] stamps , tz = None ):
1218
+ def is_date_array_normalized (int64_t[:] stamps , object tz = None ):
1211
1219
"""
1212
1220
Check if all of the given (nanosecond) timestamps are normalized to
1213
1221
midnight, i.e. hour == minute == second == 0. If the optional timezone
0 commit comments