|
10 | 10 |
|
11 | 11 |
|
12 | 12 | class Parser(object):
|
| 13 | + """ |
| 14 | + Parser which parses common formats (like RFC3339 and ISO8601). |
| 15 | + """ |
| 16 | + |
13 | 17 | COMMON = re.compile(
|
14 | 18 | # Date (optional)
|
15 | 19 | '^'
|
16 |
| - '(' |
17 |
| - ' (?P<date>' # Classic date (YYYY-MM-DD) or ordinal (YYYY-DDD) |
| 20 | + '(?P<date>' |
| 21 | + ' (?P<classic>' # Classic date (YYYY-MM-DD) or ordinal (YYYY-DDD) |
18 | 22 | ' (?P<year>\d{4})' # Year
|
19 | 23 | ' (?P<monthday>'
|
20 | 24 | ' (?P<monthsep>-|/)?(?P<month>\d{2})' # Month (optional)
|
@@ -81,58 +85,57 @@ def parse_common(self, text):
|
81 | 85 | has_date = False
|
82 | 86 |
|
83 | 87 | if m:
|
84 |
| - if m.group('isocalendar'): |
85 |
| - date = self._get_iso_8601_week( |
86 |
| - m.group('isoyear'), |
87 |
| - m.group('isoweek'), |
88 |
| - m.group('isoweekday') |
89 |
| - ) |
90 |
| - |
91 |
| - year = date['year'] |
92 |
| - month = date['month'] |
93 |
| - day = date['day'] |
94 |
| - |
95 |
| - parsed.update({ |
96 |
| - 'year': year, |
97 |
| - 'month': month, |
98 |
| - 'day': day, |
99 |
| - }) |
100 |
| - elif m.group('date'): |
101 |
| - has_date = True |
| 88 | + if m.group('date'): |
102 | 89 | # A date has been specified
|
103 |
| - year = int(m.group('year')) |
| 90 | + has_date = True |
| 91 | + |
| 92 | + if m.group('isocalendar'): |
| 93 | + # We have a ISO 8601 string defined |
| 94 | + # by week number |
| 95 | + date = self._get_iso_8601_week( |
| 96 | + m.group('isoyear'), |
| 97 | + m.group('isoweek'), |
| 98 | + m.group('isoweekday') |
| 99 | + ) |
104 | 100 |
|
105 |
| - if not m.group('monthday'): |
106 |
| - # No month and day |
107 |
| - month = 1 |
108 |
| - day = 1 |
| 101 | + year = date['year'] |
| 102 | + month = date['month'] |
| 103 | + day = date['day'] |
109 | 104 | else:
|
110 |
| - if m.group('month') and m.group('day'): |
111 |
| - # Month and day |
112 |
| - if len(m.group('day')) == 1: |
113 |
| - # Ordinal day |
114 |
| - dt = datetime.strptime( |
115 |
| - '{}-{}'.format(year, m.group('month') + m.group('day')), |
116 |
| - '%Y-%j' |
117 |
| - ) |
118 |
| - month = dt.month |
119 |
| - day = dt.day |
120 |
| - elif self._options['day_first']: |
121 |
| - month = int(m.group('day')) |
122 |
| - day = int(m.group('month')) |
| 105 | + # We have a classic date representation |
| 106 | + year = int(m.group('year')) |
| 107 | + |
| 108 | + if not m.group('monthday'): |
| 109 | + # No month and day |
| 110 | + month = 1 |
| 111 | + day = 1 |
| 112 | + else: |
| 113 | + if m.group('month') and m.group('day'): |
| 114 | + # Month and day |
| 115 | + if len(m.group('day')) == 1: |
| 116 | + # Ordinal day |
| 117 | + dt = datetime.strptime( |
| 118 | + '{}-{}'.format(year, m.group('month') + m.group('day')), |
| 119 | + '%Y-%j' |
| 120 | + ) |
| 121 | + month = dt.month |
| 122 | + day = dt.day |
| 123 | + elif self._options['day_first']: |
| 124 | + month = int(m.group('day')) |
| 125 | + day = int(m.group('month')) |
| 126 | + else: |
| 127 | + month = int(m.group('month')) |
| 128 | + day = int(m.group('day')) |
123 | 129 | else:
|
| 130 | + # Only month |
| 131 | + if not m.group('monthsep'): |
| 132 | + # The date looks like 201207 |
| 133 | + # which is invalid for a date |
| 134 | + # But it might be a time in the form hhmmss |
| 135 | + ambiguous_date = True |
| 136 | + |
124 | 137 | month = int(m.group('month'))
|
125 |
| - day = int(m.group('day')) |
126 |
| - else: |
127 |
| - # Only month |
128 |
| - if not m.group('monthsep'): |
129 |
| - # The date looks like 201207 |
130 |
| - # which is invalid for a date |
131 |
| - # But it might be a time in the form hhmmss |
132 |
| - ambiguous_date = True |
133 |
| - |
134 |
| - month = int(m.group('month')) |
135 |
| - day = 1 |
| 138 | + day = 1 |
136 | 139 |
|
137 | 140 | parsed.update({
|
138 | 141 | 'year': year,
|
@@ -271,6 +274,8 @@ def _parse(self, text):
|
271 | 274 | if parsed:
|
272 | 275 | return parsed
|
273 | 276 |
|
| 277 | + # We couldn't parse the string |
| 278 | + # so we fallback on the dateutil parser |
274 | 279 | try:
|
275 | 280 | dt = parser.parse(text, dayfirst=self._options['day_first'])
|
276 | 281 | except ValueError:
|
|
0 commit comments