Fixed #27699 -- Added negative timedelta support to parse_duration()

This commit is contained in:
Jinank Jain 2017-01-14 11:17:54 +01:00 committed by Claude Paroz
parent 8ade277ab1
commit f4c0eec713
2 changed files with 9 additions and 3 deletions

View File

@ -30,9 +30,9 @@ datetime_re = re.compile(
standard_duration_re = re.compile(
r'^'
r'(?:(?P<days>-?\d+) (days?, )?)?'
r'((?:(?P<hours>\d+):)(?=\d+:\d+))?'
r'(?:(?P<minutes>\d+):)?'
r'(?P<seconds>\d+)'
r'((?:(?P<hours>-?\d+):)(?=\d+:\d+))?'
r'(?:(?P<minutes>-?\d+):)?'
r'(?P<seconds>-?\d+)'
r'(?:\.(?P<microseconds>\d{1,6})\d{0,6})?'
r'$'
)
@ -125,5 +125,7 @@ def parse_duration(value):
sign = -1 if kw.pop('sign', '+') == '-' else 1
if kw.get('microseconds'):
kw['microseconds'] = kw['microseconds'].ljust(6, '0')
if kw.get('seconds') and kw.get('microseconds') and kw['seconds'].startswith('-'):
kw['microseconds'] = '-' + kw['microseconds']
kw = {k: float(v) for k, v in six.iteritems(kw) if v is not None}
return sign * datetime.timedelta(**kw)

View File

@ -108,6 +108,10 @@ class DurationParseTests(unittest.TestCase):
def test_negative(self):
self.assertEqual(parse_duration('-4 15:30'), timedelta(days=-4, minutes=15, seconds=30))
self.assertEqual(parse_duration('-172800'), timedelta(days=-2))
self.assertEqual(parse_duration('-15:30'), timedelta(minutes=-15, seconds=30))
self.assertEqual(parse_duration('-1:15:30'), timedelta(hours=-1, minutes=15, seconds=30))
self.assertEqual(parse_duration('-30.1'), timedelta(seconds=-30, milliseconds=-100))
def test_iso_8601(self):
self.assertIsNone(parse_duration('P4Y'))