|
1 | 1 | # -*- coding: utf-8 -*- |
2 | 2 | # cython: profile=False |
3 | 3 |
|
4 | | -from cpython cimport Py_EQ, Py_NE, Py_GE, Py_GT, Py_LT, Py_LE |
| 4 | +from cpython cimport (Py_EQ, Py_NE, Py_GE, Py_GT, Py_LT, Py_LE, |
| 5 | + PyUnicode_Check, PyUnicode_AsASCIIString) |
5 | 6 |
|
6 | 7 | from cpython.datetime cimport (datetime, date, |
7 | 8 | PyDateTime_IMPORT, |
@@ -33,6 +34,11 @@ cdef extern from "../src/datetime/np_datetime.h": |
33 | 34 |
|
34 | 35 | pandas_datetimestruct _NS_MIN_DTS, _NS_MAX_DTS |
35 | 36 |
|
| 37 | +cdef extern from "../src/datetime/np_datetime_strings.h": |
| 38 | + int parse_iso_8601_datetime(char *str, int len, |
| 39 | + pandas_datetimestruct *out, |
| 40 | + int *out_local, int *out_tzoffset) |
| 41 | + |
36 | 42 | # ---------------------------------------------------------------------- |
37 | 43 | # numpy object inspection |
38 | 44 |
|
@@ -161,3 +167,35 @@ cdef inline int64_t pydate_to_dt64(date val, |
161 | 167 | dts.hour = dts.min = dts.sec = dts.us = 0 |
162 | 168 | dts.ps = dts.as = 0 |
163 | 169 | return dtstruct_to_dt64(dts) |
| 170 | + |
| 171 | + |
| 172 | +cdef inline int _string_to_dts(object val, pandas_datetimestruct* dts, |
| 173 | + int* out_local, int* out_tzoffset) except? -1: |
| 174 | + cdef: |
| 175 | + int result |
| 176 | + char *tmp |
| 177 | + |
| 178 | + if PyUnicode_Check(val): |
| 179 | + val = PyUnicode_AsASCIIString(val) |
| 180 | + |
| 181 | + tmp = val |
| 182 | + result = _cstring_to_dts(tmp, len(val), dts, out_local, out_tzoffset) |
| 183 | + |
| 184 | + if result == -1: |
| 185 | + raise ValueError('Unable to parse %s' % str(val)) |
| 186 | + return result |
| 187 | + |
| 188 | + |
| 189 | +cdef inline int _cstring_to_dts(char *val, int length, |
| 190 | + pandas_datetimestruct* dts, |
| 191 | + int* out_local, int* out_tzoffset) except? -1: |
| 192 | + # Note: without this "extra layer" between _string_to_dts |
| 193 | + # and parse_iso_8601_datetime, calling _string_to_dts raises |
| 194 | + # `SystemError: <class 'str'> returned a result with an error set` |
| 195 | + # in Python3 |
| 196 | + cdef: |
| 197 | + int result |
| 198 | + |
| 199 | + result = parse_iso_8601_datetime(val, length, |
| 200 | + dts, out_local, out_tzoffset) |
| 201 | + return result |
0 commit comments