@@ -37,6 +37,7 @@ from pandas._libs.tslibs.np_datetime cimport (
37
37
NPY_FR_us,
38
38
check_dts_bounds,
39
39
convert_reso,
40
+ get_conversion_factor,
40
41
get_datetime64_unit,
41
42
get_datetime64_value,
42
43
get_implementation_bounds,
@@ -83,9 +84,9 @@ TD64NS_DTYPE = np.dtype("m8[ns]")
83
84
# Unit Conversion Helpers
84
85
85
86
cdef int64_t cast_from_unit(
86
- object ts,
87
- str unit,
88
- NPY_DATETIMEUNIT out_reso = NPY_FR_ns
87
+ object ts,
88
+ str unit,
89
+ NPY_DATETIMEUNIT out_reso = NPY_FR_ns
89
90
) except ? - 1 :
90
91
"""
91
92
Return a casting of the unit represented to nanoseconds
@@ -104,12 +105,6 @@ cdef int64_t cast_from_unit(
104
105
int64_t m
105
106
int p
106
107
107
- m, p = precision_from_unit(unit, out_reso)
108
-
109
- # just give me the unit back
110
- if ts is None :
111
- return m
112
-
113
108
if unit in [" Y" , " M" ]:
114
109
if is_float_object(ts) and not ts.is_integer():
115
110
# GH#47267 it is clear that 2 "M" corresponds to 1970-02-01,
@@ -126,6 +121,8 @@ cdef int64_t cast_from_unit(
126
121
dt64obj = np.datetime64(ts, unit)
127
122
return get_datetime64_nanos(dt64obj, out_reso)
128
123
124
+ m, p = precision_from_unit(unit, out_reso)
125
+
129
126
# cast the unit, multiply base/frac separately
130
127
# to avoid precision issues from float -> int
131
128
try :
@@ -148,8 +145,8 @@ cdef int64_t cast_from_unit(
148
145
149
146
150
147
cpdef inline (int64_t, int ) precision_from_unit(
151
- str unit,
152
- NPY_DATETIMEUNIT out_reso = NPY_DATETIMEUNIT.NPY_FR_ns,
148
+ str unit,
149
+ NPY_DATETIMEUNIT out_reso = NPY_DATETIMEUNIT.NPY_FR_ns,
153
150
):
154
151
"""
155
152
Return a casting of the unit represented to nanoseconds + the precision
@@ -166,34 +163,21 @@ cpdef inline (int64_t, int) precision_from_unit(
166
163
int p
167
164
NPY_DATETIMEUNIT reso = abbrev_to_npy_unit(unit)
168
165
169
- multiplier = periods_per_second(out_reso)
170
-
166
+ if reso == NPY_DATETIMEUNIT.NPY_FR_GENERIC:
167
+ reso = NPY_DATETIMEUNIT.NPY_FR_ns
171
168
if reso == NPY_DATETIMEUNIT.NPY_FR_Y:
172
169
# each 400 years we have 97 leap years, for an average of 97/400=.2425
173
170
# extra days each year. We get 31556952 by writing
174
171
# 3600*24*365.2425=31556952
172
+ multiplier = periods_per_second(out_reso)
175
173
m = multiplier * 31556952
176
174
elif reso == NPY_DATETIMEUNIT.NPY_FR_M:
177
175
# 2629746 comes from dividing the "Y" case by 12.
176
+ multiplier = periods_per_second(out_reso)
178
177
m = multiplier * 2629746
179
- elif reso == NPY_DATETIMEUNIT.NPY_FR_W:
180
- m = multiplier * 3600 * 24 * 7
181
- elif reso == NPY_DATETIMEUNIT.NPY_FR_D:
182
- m = multiplier * 3600 * 24
183
- elif reso == NPY_DATETIMEUNIT.NPY_FR_h:
184
- m = multiplier * 3600
185
- elif reso == NPY_DATETIMEUNIT.NPY_FR_m:
186
- m = multiplier * 60
187
- elif reso == NPY_DATETIMEUNIT.NPY_FR_s:
188
- m = multiplier
189
- elif reso == NPY_DATETIMEUNIT.NPY_FR_ms:
190
- m = multiplier // 1 _000
191
- elif reso == NPY_DATETIMEUNIT.NPY_FR_us:
192
- m = multiplier // 1 _000_000
193
- elif reso == NPY_DATETIMEUNIT.NPY_FR_ns or reso == NPY_DATETIMEUNIT.NPY_FR_GENERIC:
194
- m = multiplier // 1 _000_000_000
195
178
else :
196
- raise ValueError (f" cannot cast unit {unit}" )
179
+ m = get_conversion_factor(reso, out_reso)
180
+
197
181
p = < int > log10(m) # number of digits in 'm' minus 1
198
182
return m, p
199
183
0 commit comments