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