Skip to content

Commit 143104e

Browse files
committed
Adds a strict keyword argument to parse() to get the type matching the parsed string.
1 parent 84739a8 commit 143104e

File tree

8 files changed

+485
-81
lines changed

8 files changed

+485
-81
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Added
66

77
- Added `on()` and `at()` methods which replace `with_date()` and `with_time()`.
8+
- Added a `strict` keyword argument to `parse()` to get the type matching the parsed string.
89

910
### Changed
1011

docs/_docs/instantiation.rst

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,118 @@ you can create a ``Pendulum`` instance via the ``instance()`` function.
138138
p = pendulum.instance(dt)
139139
print(p.to_datetime_string())
140140
'2008-01-01 00:00:00'
141+
142+
Parsing
143+
-------
144+
145+
You can also instantiate ``Pendulum`` instances by passing a string to the ``parse()`` method.
146+
147+
.. code-block:: python
148+
149+
import pendulum
150+
151+
dt = pendulum.parse('1975-05-21 22:00:00')
152+
print(dt)
153+
'1975-05-21T22:00:00+00:00
154+
155+
The library natively supports the RFC 3339 format, most ISO 8601 formats and some other common formats. If you pass a non-standard or more complicated
156+
string, the library will fallback on the `dateutil <https://dateutil.readthedocs.io>`_ parser.
157+
158+
RFC 3339
159+
~~~~~~~~
160+
161+
+-----------------------------------+-------------------------------------------+
162+
|String |Output |
163+
+===================================+===========================================+
164+
|1996-12-19T16:39:57-08:00 |1996-12-19T16:39:57-08:00 |
165+
+-----------------------------------+-------------------------------------------+
166+
|1990-12-31T23:59:59Z |1990-12-31T23:59:59+00:00 |
167+
+-----------------------------------+-------------------------------------------+
168+
169+
ISO 8601
170+
~~~~~~~~
171+
172+
Datetime
173+
++++++++
174+
175+
+-----------------------------------+-------------------------------------------+
176+
|String |Output |
177+
+===================================+===========================================+
178+
|20161001T143028+0530 |2016-10-01T14:30:28+05:30 |
179+
+-----------------------------------+-------------------------------------------+
180+
|20161001T14 |2016-10-01T14:00:00+00:00 |
181+
+-----------------------------------+-------------------------------------------+
182+
183+
Date
184+
++++
185+
186+
+-----------------------------------+-------------------------------------------+
187+
|String |Output |
188+
+===================================+===========================================+
189+
|2012 |2012-01-01T00:00:00+00:00 |
190+
+-----------------------------------+-------------------------------------------+
191+
|2012-05-03 |2012-05-03T00:00:00+00:00 |
192+
+-----------------------------------+-------------------------------------------+
193+
|20120503 |2012-05-03T00:00:00+00:00 |
194+
+-----------------------------------+-------------------------------------------+
195+
|2012-05 |2016-10-01T14:00:00+00:00 |
196+
+-----------------------------------+-------------------------------------------+
197+
198+
Ordinal day
199+
+++++++++++
200+
201+
+-----------------------------------+-------------------------------------------+
202+
|String |Output |
203+
+===================================+===========================================+
204+
|2012-007 |2012-01-07T00:00:00+00:00 |
205+
+-----------------------------------+-------------------------------------------+
206+
|2012007 |2012-01-07T00:00:00+00:00 |
207+
+-----------------------------------+-------------------------------------------+
208+
209+
Week number
210+
+++++++++++
211+
212+
+-----------------------------------+-------------------------------------------+
213+
|String |Output |
214+
+===================================+===========================================+
215+
|2012-W05 |2012-01-30T00:00:00+00:00 |
216+
+-----------------------------------+-------------------------------------------+
217+
|2012W05 |2012-01-30T00:00:00+00:00 |
218+
+-----------------------------------+-------------------------------------------+
219+
|2012-W05-5 |2012-02-03T00:00:00+00:00 |
220+
+-----------------------------------+-------------------------------------------+
221+
|2012W055 |2012-02-03T00:00:00+00:00 |
222+
+-----------------------------------+-------------------------------------------+
223+
224+
Time
225+
++++
226+
227+
When passing only time information the date will default to today.
228+
229+
+-----------------------------------+-------------------------------------------+
230+
|String |Output |
231+
+===================================+===========================================+
232+
|00:00 |2016-12-17T00:00:00+00:00 |
233+
+-----------------------------------+-------------------------------------------+
234+
|12:04:23 |2016-12-17T12:04:23+00:00 |
235+
+-----------------------------------+-------------------------------------------+
236+
|120423 |2016-12-17T12:04:23+00:00 |
237+
+-----------------------------------+-------------------------------------------+
238+
|12:04:23.45 |2016-12-17T12:04:23.450000+00:00 |
239+
+-----------------------------------+-------------------------------------------+
240+
241+
242+
.. note::
243+
244+
You can pass the ``strict`` keyword argument to ``parse()`` to get the exact time
245+
that the string represents:
246+
247+
.. code-block:: python
248+
249+
import pendulum
250+
251+
pendulum.parse('2012-05-03', strict=True)
252+
# <Date [2012-05-03]>
253+
254+
pendulum.parse('12:04:23', strict=True)
255+
# <Time [12:04:23]>

pendulum/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# -*- coding: utf-8 -*-
22

3+
# Types
34
from .pendulum import Pendulum
45
from .date import Date
56
from .time import Time
@@ -44,8 +45,9 @@
4445
get_formatter = Global.get_formatter
4546

4647
# Helpers
48+
from .parser import parse
49+
4750
instance = Pendulum.instance
48-
parse = Pendulum.parse
4951
now = Pendulum.now
5052
utcnow = Pendulum.utcnow
5153
today = Pendulum.today

pendulum/parser.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# -*- coding: utf-8 -*-
2+
3+
from __future__ import division
4+
5+
from .parsing import Parser as BaseParser
6+
from .tz import UTC
7+
from .pendulum import Pendulum
8+
from .date import Date
9+
from .time import Time
10+
from ._global import Global
11+
12+
13+
class Parser(BaseParser):
14+
"""
15+
Parser that returns known types (Pendulum, Date, Time)
16+
"""
17+
18+
def parse(self, text):
19+
"""
20+
Parses a string with the given options.
21+
22+
:param text: The string to parse.
23+
:type text: str
24+
25+
:rtype: mixed
26+
"""
27+
parsed = super(Parser, self).parse(text)
28+
29+
if not self.is_strict():
30+
return self._create_pendulum_object(parsed)
31+
32+
# Checking for date
33+
if 'year' in parsed:
34+
# Checking for time
35+
if 'hour' in parsed:
36+
return self._create_pendulum_object(parsed)
37+
else:
38+
return self._create_date_object(parsed)
39+
40+
return self._create_time_object(parsed)
41+
42+
def _create_pendulum_object(self, parsed):
43+
if parsed['offset'] is None:
44+
tz = self._options.get('tz', UTC)
45+
else:
46+
tz = parsed['offset'] / 3600
47+
48+
return Pendulum(
49+
parsed['year'], parsed['month'], parsed['day'],
50+
parsed['hour'], parsed['minute'], parsed['second'],
51+
parsed['subsecond'] // 1000,
52+
tzinfo=tz
53+
)
54+
55+
def _create_date_object(self, parsed):
56+
return Date(
57+
parsed['year'], parsed['month'], parsed['day']
58+
)
59+
60+
def _create_time_object(self, parsed):
61+
return Time(
62+
parsed['hour'], parsed['minute'], parsed['second'],
63+
parsed['subsecond'] // 1000
64+
)
65+
66+
67+
def parse(text, **options):
68+
# Use the mock now value if it exists
69+
options['now'] = options.get('now', Global.get_test_now())
70+
71+
return Parser(**options).parse(text)

pendulum/parsing/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def parse(text, **options):
1313
:param options: The parsing options.
1414
:type options: dict
1515
16-
:rtype: Pendulum or Span
16+
:rtype: dict
1717
1818
:raises: ParserError
1919
"""

0 commit comments

Comments
 (0)