Skip to content

Commit 0123245

Browse files
committed
Move to datetime_new, add docstring to _parse_delimited_date
1 parent d309aae commit 0123245

File tree

1 file changed

+22
-15
lines changed

1 file changed

+22
-15
lines changed

pandas/_libs/tslibs/parsing.pyx

+22-15
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ import re
77
import time
88

99
from 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

1413
import 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

5553
cdef:
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

6564
cdef bint _is_not_delimiter(const char ch):
6665
return strchr(delimiters, ch) == NULL
6766

67+
6868
cdef 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+
7475
cdef 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

122129
def 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

Comments
 (0)