@@ -7,9 +7,8 @@ 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
1312
1413import numpy as np
1514
@@ -50,27 +49,29 @@ class DateParseError(ValueError):
5049
5150_DEFAULT_DATETIME = datetime(1 , 1 , 1 ).replace(hour = 0 , minute = 0 ,
5251 second = 0 , microsecond = 0 )
53- _DEFAULT_TZINFO = _DEFAULT_DATETIME.tzinfo
5452
5553cdef:
5654 object _TIMEPAT = re.compile(r ' ^ ( [01 ]? [0-9 ]| 2[0-3 ]) :( [0-5 ][0-9 ]) ' )
5755
5856 set _not_datelike_strings = {' a' , ' A' , ' m' , ' M' , ' p' , ' P' , ' t' , ' T' }
5957
6058# ----------------------------------------------------------------------
61- DEF delimiters = b' /-\\ '
62- DEF MAX_DAYS_IN_MONTH = 31
63- DEF MAX_MONTH = 12
59+ cdef:
60+ const char * delimiters = " /-\\ ."
61+ int MAX_DAYS_IN_MONTH = 31 , MAX_MONTH = 12
62+
6463
6564cdef bint _is_not_delimiter(const char ch):
6665 return strchr(delimiters, ch) == NULL
6766
67+
6868cdef inline int _parse_2digit(const char * s):
6969 cdef int result = 0
7070 result += getdigit_ascii(s[0 ], - 10 ) * 10
7171 result += getdigit_ascii(s[1 ], - 100 ) * 1
7272 return result
7373
74+
7475cdef inline int _parse_4digit(const char * s):
7576 cdef int result = 0
7677 result += getdigit_ascii(s[0 ], - 10 ) * 1000
@@ -79,14 +80,22 @@ cdef inline int _parse_4digit(const char* s):
7980 result += getdigit_ascii(s[3 ], - 10000 ) * 1
8081 return result
8182
82- cdef inline object parse_delimited_date(object date_string, bint dayfirst,
83- object tzinfo):
83+
84+ cdef inline object _parse_delimited_date(object date_string, bint dayfirst):
85+ """
86+ Parse special cases of dates: MM/DD/YYYY, DD/MM/YYYY, MM/YYYY
87+ Delimiter can be a space or one of ./\-
88+
89+ Returns one of:
90+ ---------------
91+ * datetime and resolution
92+ * None, None if passed in not a handled date pattern
93+ """
8494 cdef:
8595 const char * buf
8696 Py_ssize_t length
8797 int day = 1 , month = 1 , year
8898
89- assert isinstance (date_string, (str , unicode ))
9099 buf = get_c_string_buf_and_size(date_string, & length)
91100 if length == 10 :
92101 if _is_not_delimiter(buf[2 ]) or _is_not_delimiter(buf[5 ]):
@@ -112,11 +121,9 @@ cdef inline object parse_delimited_date(object date_string, bint dayfirst,
112121 and (month <= MAX_MONTH or day <= MAX_MONTH):
113122 if month > MAX_MONTH or (day < MAX_MONTH and dayfirst):
114123 day, month = month, day
115- return PyDateTimeAPI.DateTime_FromDateAndTime(
116- year, month, day, 0 , 0 , 0 , 0 , tzinfo, PyDateTimeAPI.DateTimeType
117- ), reso
124+ return datetime_new(year, month, day, 0 , 0 , 0 , 0 , None ), reso
118125
119- raise DateParseError(" Invalid date specified (%d / %d ) " % (month, day))
126+ raise DateParseError(" Invalid date specified ({}/{}) " .format (month, day))
120127
121128
122129def parse_datetime_string (date_string , freq = None , dayfirst = False ,
@@ -141,7 +148,7 @@ def parse_datetime_string(date_string, freq=None, dayfirst=False,
141148 yearfirst = yearfirst, ** kwargs)
142149 return dt
143150
144- dt, _ = parse_delimited_date (date_string, dayfirst, _DEFAULT_TZINFO )
151+ dt, _ = _parse_delimited_date (date_string, dayfirst)
145152 if dt is not None :
146153 return dt
147154
@@ -225,7 +232,7 @@ cdef parse_datetime_string_with_reso(date_string, freq=None, dayfirst=False,
225232 if not _does_string_look_like_datetime(date_string):
226233 raise ValueError (' Given date string not likely a datetime.' )
227234
228- parsed, reso = parse_delimited_date (date_string, dayfirst, _DEFAULT_TZINFO )
235+ parsed, reso = _parse_delimited_date (date_string, dayfirst)
229236 if parsed is not None :
230237 return parsed, parsed, reso
231238
0 commit comments