summaryrefslogtreecommitdiffstats
path: root/Lib/_strptime.py
diff options
context:
space:
mode:
authorMario Corchero <mariocj89@gmail.com>2017-10-26 00:35:41 (GMT)
committerAlexander Belopolsky <abalkin@users.noreply.github.com>2017-10-26 00:35:41 (GMT)
commit32318930da70ff03320ec50813b843e7db6fbc2e (patch)
tree7284607df837403a99207f4f807f222c518fea9f /Lib/_strptime.py
parent0f261583bae7e60e410709ed96398dd1b14c5454 (diff)
downloadcpython-32318930da70ff03320ec50813b843e7db6fbc2e.zip
cpython-32318930da70ff03320ec50813b843e7db6fbc2e.tar.gz
cpython-32318930da70ff03320ec50813b843e7db6fbc2e.tar.bz2
Closes bpo-31800: Support for colon when parsing time offsets (#4015)
Add support to strptime to parse time offsets with a colon between the hour and the minutes.
Diffstat (limited to 'Lib/_strptime.py')
-rw-r--r--Lib/_strptime.py36
1 files changed, 24 insertions, 12 deletions
diff --git a/Lib/_strptime.py b/Lib/_strptime.py
index 284175d..f5195af 100644
--- a/Lib/_strptime.py
+++ b/Lib/_strptime.py
@@ -210,7 +210,7 @@ class TimeRE(dict):
#XXX: Does 'Y' need to worry about having less or more than
# 4 digits?
'Y': r"(?P<Y>\d\d\d\d)",
- 'z': r"(?P<z>[+-]\d\d[0-5]\d)",
+ 'z': r"(?P<z>[+-]\d\d:?[0-5]\d(:?[0-5]\d(\.\d{1,6})?)?|Z)",
'A': self.__seqToRE(self.locale_time.f_weekday, 'A'),
'a': self.__seqToRE(self.locale_time.a_weekday, 'a'),
'B': self.__seqToRE(self.locale_time.f_month[1:], 'B'),
@@ -365,7 +365,8 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
month = day = 1
hour = minute = second = fraction = 0
tz = -1
- tzoffset = None
+ gmtoff = None
+ gmtoff_fraction = 0
# Default to -1 to signify that values not known; not critical to have,
# though
iso_week = week_of_year = None
@@ -455,9 +456,24 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
iso_week = int(found_dict['V'])
elif group_key == 'z':
z = found_dict['z']
- tzoffset = int(z[1:3]) * 60 + int(z[3:5])
- if z.startswith("-"):
- tzoffset = -tzoffset
+ if z == 'Z':
+ gmtoff = 0
+ else:
+ if z[3] == ':':
+ z = z[:3] + z[4:]
+ if len(z) > 5:
+ if z[5] != ':':
+ msg = f"Unconsistent use of : in {found_dict['z']}"
+ raise ValueError(msg)
+ z = z[:5] + z[6:]
+ hours = int(z[1:3])
+ minutes = int(z[3:5])
+ seconds = int(z[5:7] or 0)
+ gmtoff = (hours * 60 * 60) + (minutes * 60) + seconds
+ gmtoff_fraction = int(z[8:] or 0)
+ if z.startswith("-"):
+ gmtoff = -gmtoff
+ gmtoff_fraction = -gmtoff_fraction
elif group_key == 'Z':
# Since -1 is default value only need to worry about setting tz if
# it can be something other than -1.
@@ -535,10 +551,6 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
weekday = datetime_date(year, month, day).weekday()
# Add timezone info
tzname = found_dict.get("Z")
- if tzoffset is not None:
- gmtoff = tzoffset * 60
- else:
- gmtoff = None
if leap_year_fix:
# the caller didn't supply a year but asked for Feb 29th. We couldn't
@@ -548,7 +560,7 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
return (year, month, day,
hour, minute, second,
- weekday, julian, tz, tzname, gmtoff), fraction
+ weekday, julian, tz, tzname, gmtoff), fraction, gmtoff_fraction
def _strptime_time(data_string, format="%a %b %d %H:%M:%S %Y"):
"""Return a time struct based on the input string and the
@@ -559,11 +571,11 @@ def _strptime_time(data_string, format="%a %b %d %H:%M:%S %Y"):
def _strptime_datetime(cls, data_string, format="%a %b %d %H:%M:%S %Y"):
"""Return a class cls instance based on the input string and the
format string."""
- tt, fraction = _strptime(data_string, format)
+ tt, fraction, gmtoff_fraction = _strptime(data_string, format)
tzname, gmtoff = tt[-2:]
args = tt[:6] + (fraction,)
if gmtoff is not None:
- tzdelta = datetime_timedelta(seconds=gmtoff)
+ tzdelta = datetime_timedelta(seconds=gmtoff, microseconds=gmtoff_fraction)
if tzname:
tz = datetime_timezone(tzdelta, tzname)
else: