Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1)

Unified Diff: Lib/datetime.py

Issue 15873: "datetime" cannot parse ISO 8601 dates and times
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | Lib/test/datetimetester.py » ('j') | Lib/test/datetimetester.py » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
--- a/Lib/datetime.py Sun Feb 14 03:25:48 2016 +0000
+++ b/Lib/datetime.py Mon Feb 15 22:01:39 2016 +1030
@@ -6,6 +6,7 @@
import time as _time
import math as _math
+import re
def _cmp(x, y):
return 0 if x == y else 1 if x > y else -1
@@ -146,6 +147,12 @@
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
_DAYNAMES = [None, "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
+datetime_re = re.compile(
Martin Panter 2016/02/16 04:21:50 IMO this would be better moved closer to where it
+ r'(?P<year>\d{4})-(?P<month>\d{1,2})-(?P<day>\d{1,2})'
+ r'[T ](?P<hour>\d{1,2}):(?P<minute>\d{1,2})'
+ r'(?::(?P<second>\d{1,2})(?:(?P<microsecond>\.\d{1,7})\d*)?)?'
Martin Panter 2016/02/16 04:21:50 If we want to round half to even, reading one extr
+ r'(?P<tzinfo>Z|[+-]\d{2}(?::?\d{2})?)?$'
+)
Martin Panter 2016/02/16 05:50:03 Should probably add case-insensitive flag to allow
def _build_struct_time(y, m, d, hh, mm, ss, dstflag):
wday = (_ymd2ord(y, m, d) + 6) % 7
@@ -1401,6 +1408,38 @@
return result
@classmethod
+ def fromisoformat(cls, value):
+ """Parses a string and return a datetime.datetime.
+
+ This function supports time zone offsets. When the input contains one,
+ the output uses a timezone with a fixed offset from UTC.
+ Microseconds values after 6 digits are discared.
Martin Panter 2016/02/16 04:21:50 Spelling: discarded. But it seems we are changing
+
+ Raises ValueError if the input is not well formatted or not a valid datetime.
+ """
+ match = datetime_re.match(value)
+ if not match:
+ raise ValueError('invalid {} iso8601 string : {}'.format(cls.__name__, value))
Martin Panter 2016/02/16 04:21:50 This could be a bit confusing if the string was ac
+ kw = match.groupdict()
+ tzinfo = kw.pop('tzinfo')
+ if tzinfo == 'Z':
+ tzinfo = timezone.utc
+ elif tzinfo is not None:
+ offset_mins = int(tzinfo[-2:]) if len(tzinfo) > 3 else 0
+ offset_hours = int(tzinfo[1:3])
+ offset = timedelta(hours=offset_hours, minutes=offset_mins)
+ if tzinfo[0] == '-':
+ offset = -offset
+ tzinfo = timezone(offset)
+ us = kw.pop('microsecond', None)
+ kw = {k: int(v) for k, v in kw.items() if v is not None}
+ if us:
+ us = round(float(us), 6)
+ kw['microsecond'] = int(us * 1e6)
haypo 2016/02/15 17:29:59 I suggest: kw['microsecond'] = round(float(us) /
deronnax 2016/08/05 14:09:51 Doesn't work, make the tests fails, microseconds a
+ kw['tzinfo'] = tzinfo
+ return cls(**kw)
+
+ @classmethod
def utcfromtimestamp(cls, t):
"""Construct a naive UTC datetime from a POSIX timestamp."""
return cls._fromtimestamp(t, True, None)
« no previous file with comments | « no previous file | Lib/test/datetimetester.py » ('j') | Lib/test/datetimetester.py » ('J')

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+