@@ -7,9 +7,9 @@ import re
7
7
import time
8
8
9
9
from libc.string cimport strchr
10
- from cpython.datetime cimport datetime, PyDateTime_IMPORT, PyDateTimeAPI
11
10
12
- PyDateTime_IMPORT
11
+ from cpython.datetime cimport datetime, datetime_new, import_datetime
12
+ import_datetime()
13
13
14
14
import numpy as np
15
15
@@ -50,27 +50,29 @@ class DateParseError(ValueError):
50
50
51
51
_DEFAULT_DATETIME = datetime(1 , 1 , 1 ).replace(hour = 0 , minute = 0 ,
52
52
second = 0 , microsecond = 0 )
53
- _DEFAULT_TZINFO = _DEFAULT_DATETIME.tzinfo
54
53
55
54
cdef:
56
55
object _TIMEPAT = re.compile(r ' ^ ( [01 ]? [0-9 ]| 2[0-3 ]) :( [0-5 ][0-9 ]) ' )
57
56
58
57
set _not_datelike_strings = {' a' , ' A' , ' m' , ' M' , ' p' , ' P' , ' t' , ' T' }
59
58
60
59
# ----------------------------------------------------------------------
61
- DEF delimiters = b' /-\\ '
62
- DEF MAX_DAYS_IN_MONTH = 31
63
- DEF MAX_MONTH = 12
60
+ cdef:
61
+ const char * delimiters = " /-\\ ."
62
+ int MAX_DAYS_IN_MONTH = 31 , MAX_MONTH = 12
63
+
64
64
65
65
cdef bint _is_not_delimiter(const char ch):
66
66
return strchr(delimiters, ch) == NULL
67
67
68
+
68
69
cdef inline int _parse_2digit(const char * s):
69
70
cdef int result = 0
70
71
result += getdigit_ascii(s[0 ], - 10 ) * 10
71
72
result += getdigit_ascii(s[1 ], - 100 ) * 1
72
73
return result
73
74
75
+
74
76
cdef inline int _parse_4digit(const char * s):
75
77
cdef int result = 0
76
78
result += getdigit_ascii(s[0 ], - 10 ) * 1000
@@ -79,14 +81,22 @@ cdef inline int _parse_4digit(const char* s):
79
81
result += getdigit_ascii(s[3 ], - 10000 ) * 1
80
82
return result
81
83
82
- cdef inline object parse_delimited_date(object date_string, bint dayfirst,
83
- object tzinfo):
84
+
85
+ cdef inline object _parse_delimited_date(object date_string, bint dayfirst):
86
+ """
87
+ Parse special cases of dates: MM/DD/YYYY, DD/MM/YYYY, MM/YYYY
88
+ Delimiter can be a space or one of ./\-
89
+
90
+ Returns one of:
91
+ ---------------
92
+ * datetime and resolution
93
+ * None, None if passed in not a handled date pattern
94
+ """
84
95
cdef:
85
96
const char * buf
86
97
Py_ssize_t length
87
98
int day = 1 , month = 1 , year
88
99
89
- assert isinstance (date_string, (str , unicode ))
90
100
buf = get_c_string_buf_and_size(date_string, & length)
91
101
if length == 10 :
92
102
if _is_not_delimiter(buf[2 ]) or _is_not_delimiter(buf[5 ]):
@@ -112,11 +122,9 @@ cdef inline object parse_delimited_date(object date_string, bint dayfirst,
112
122
and (month <= MAX_MONTH or day <= MAX_MONTH):
113
123
if month > MAX_MONTH or (day < MAX_MONTH and dayfirst):
114
124
day, month = month, day
115
- return PyDateTimeAPI.DateTime_FromDateAndTime(
116
- year, month, day, 0 , 0 , 0 , 0 , tzinfo, PyDateTimeAPI.DateTimeType
117
- ), reso
125
+ return datetime_new(year, month, day, 0 , 0 , 0 , 0 , None ), reso
118
126
119
- raise DateParseError(" Invalid date specified (%d / %d ) " % (month, day))
127
+ raise DateParseError(" Invalid date specified ({}/{}) " .format (month, day))
120
128
121
129
122
130
def parse_datetime_string (date_string , freq = None , dayfirst = False ,
@@ -141,7 +149,7 @@ def parse_datetime_string(date_string, freq=None, dayfirst=False,
141
149
yearfirst = yearfirst, ** kwargs)
142
150
return dt
143
151
144
- dt, _ = parse_delimited_date (date_string, dayfirst, _DEFAULT_TZINFO )
152
+ dt, _ = _parse_delimited_date (date_string, dayfirst)
145
153
if dt is not None :
146
154
return dt
147
155
@@ -225,7 +233,7 @@ cdef parse_datetime_string_with_reso(date_string, freq=None, dayfirst=False,
225
233
if not _does_string_look_like_datetime(date_string):
226
234
raise ValueError (' Given date string not likely a datetime.' )
227
235
228
- parsed, reso = parse_delimited_date (date_string, dayfirst, _DEFAULT_TZINFO )
236
+ parsed, reso = _parse_delimited_date (date_string, dayfirst)
229
237
if parsed is not None :
230
238
return parsed, parsed, reso
231
239
0 commit comments