@@ -7,9 +7,9 @@ import re
77import time
88
99from libc.string cimport strchr
10- from cpython.datetime cimport datetime, PyDateTime_IMPORT, PyDateTimeAPI
1110
12- PyDateTime_IMPORT
11+ from cpython.datetime cimport datetime, datetime_new, import_datetime
12+ import_datetime()
1313
1414import numpy as np
1515
@@ -50,27 +50,29 @@ class DateParseError(ValueError):
5050
5151_DEFAULT_DATETIME = datetime(1 , 1 , 1 ).replace(hour = 0 , minute = 0 ,
5252 second = 0 , microsecond = 0 )
53- _DEFAULT_TZINFO = _DEFAULT_DATETIME.tzinfo
5453
5554cdef:
5655 object _TIMEPAT = re.compile(r ' ^ ( [01 ]? [0-9 ]| 2[0-3 ]) :( [0-5 ][0-9 ]) ' )
5756
5857 set _not_datelike_strings = {' a' , ' A' , ' m' , ' M' , ' p' , ' P' , ' t' , ' T' }
5958
6059# ----------------------------------------------------------------------
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+
6464
6565cdef bint _is_not_delimiter(const char ch):
6666 return strchr(delimiters, ch) == NULL
6767
68+
6869cdef inline int _parse_2digit(const char * s):
6970 cdef int result = 0
7071 result += getdigit_ascii(s[0 ], - 10 ) * 10
7172 result += getdigit_ascii(s[1 ], - 100 ) * 1
7273 return result
7374
75+
7476cdef inline int _parse_4digit(const char * s):
7577 cdef int result = 0
7678 result += getdigit_ascii(s[0 ], - 10 ) * 1000
@@ -79,14 +81,22 @@ cdef inline int _parse_4digit(const char* s):
7981 result += getdigit_ascii(s[3 ], - 10000 ) * 1
8082 return result
8183
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+ """
8495 cdef:
8596 const char * buf
8697 Py_ssize_t length
8798 int day = 1 , month = 1 , year
8899
89- assert isinstance (date_string, (str , unicode ))
90100 buf = get_c_string_buf_and_size(date_string, & length)
91101 if length == 10 :
92102 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,
112122 and (month <= MAX_MONTH or day <= MAX_MONTH):
113123 if month > MAX_MONTH or (day < MAX_MONTH and dayfirst):
114124 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
118126
119- raise DateParseError(" Invalid date specified (%d / %d ) " % (month, day))
127+ raise DateParseError(" Invalid date specified ({}/{}) " .format (month, day))
120128
121129
122130def parse_datetime_string (date_string , freq = None , dayfirst = False ,
@@ -141,7 +149,7 @@ def parse_datetime_string(date_string, freq=None, dayfirst=False,
141149 yearfirst = yearfirst, ** kwargs)
142150 return dt
143151
144- dt, _ = parse_delimited_date (date_string, dayfirst, _DEFAULT_TZINFO )
152+ dt, _ = _parse_delimited_date (date_string, dayfirst)
145153 if dt is not None :
146154 return dt
147155
@@ -225,7 +233,7 @@ cdef parse_datetime_string_with_reso(date_string, freq=None, dayfirst=False,
225233 if not _does_string_look_like_datetime(date_string):
226234 raise ValueError (' Given date string not likely a datetime.' )
227235
228- parsed, reso = parse_delimited_date (date_string, dayfirst, _DEFAULT_TZINFO )
236+ parsed, reso = _parse_delimited_date (date_string, dayfirst)
229237 if parsed is not None :
230238 return parsed, parsed, reso
231239
0 commit comments