Merge pull request #9110 from remitamine/parse_duration

[utils] imporove parse_duration to handle more formats
This commit is contained in:
Sergey M 2016-04-21 22:53:16 +07:00
commit b6c0d4f431
2 changed files with 39 additions and 36 deletions

View file

@ -413,6 +413,7 @@ class TestUtil(unittest.TestCase):
self.assertEqual(parse_duration('01:02:03:04'), 93784) self.assertEqual(parse_duration('01:02:03:04'), 93784)
self.assertEqual(parse_duration('1 hour 3 minutes'), 3780) self.assertEqual(parse_duration('1 hour 3 minutes'), 3780)
self.assertEqual(parse_duration('87 Min.'), 5220) self.assertEqual(parse_duration('87 Min.'), 5220)
self.assertEqual(parse_duration('PT1H0.040S'), 3600.04)
def test_fix_xml_ampersands(self): def test_fix_xml_ampersands(self):
self.assertEqual( self.assertEqual(

View file

@ -1540,44 +1540,46 @@ def parse_duration(s):
s = s.strip() s = s.strip()
m = re.match( days, hours, mins, secs, ms = [None] * 5
r'''(?ix)(?:P?T)? m = re.match(r'(?:(?:(?:(?P<days>[0-9]+):)?(?P<hours>[0-9]+):)?(?P<mins>[0-9]+):)?(?P<secs>[0-9]+)(?P<ms>\.[0-9]+)?$', s)
(?: if m:
(?P<only_mins>[0-9.]+)\s*(?:mins?\.?|minutes?)\s*| days, hours, mins, secs, ms = m.groups()
(?P<only_hours>[0-9.]+)\s*(?:hours?)| else:
m = re.match(
\s*(?P<hours_reversed>[0-9]+)\s*(?:[:h]|hours?)\s*(?P<mins_reversed>[0-9]+)\s*(?:[:m]|mins?\.?|minutes?)\s*| r'''(?ix)(?:P?T)?
(?:
(?: (?:
(?:(?P<days>[0-9]+)\s*(?:[:d]|days?)\s*)? (?P<days>[0-9]+)\s*d(?:ays?)?\s*
(?P<hours>[0-9]+)\s*(?:[:h]|hours?)\s*
)? )?
(?P<mins>[0-9]+)\s*(?:[:m]|mins?|minutes?)\s* (?:
)? (?P<hours>[0-9]+)\s*h(?:ours?)?\s*
(?P<secs>[0-9]+)(?P<ms>\.[0-9]+)?\s*(?:s|secs?|seconds?)? )?
)$''', s) (?:
if not m: (?P<mins>[0-9]+)\s*m(?:in(?:ute)?s?)?\s*
return None )?
res = 0 (?:
if m.group('only_mins'): (?P<secs>[0-9]+)(?P<ms>\.[0-9]+)?\s*s(?:ec(?:ond)?s?)?\s*
return float_or_none(m.group('only_mins'), invscale=60) )?$''', s)
if m.group('only_hours'): if m:
return float_or_none(m.group('only_hours'), invscale=60 * 60) days, hours, mins, secs, ms = m.groups()
if m.group('secs'): else:
res += int(m.group('secs')) m = re.match(r'(?i)(?:(?P<hours>[0-9.]+)\s*(?:hours?)|(?P<mins>[0-9.]+)\s*(?:mins?\.?|minutes?)\s*)$', s)
if m.group('mins_reversed'): if m:
res += int(m.group('mins_reversed')) * 60 hours, mins = m.groups()
if m.group('mins'): else:
res += int(m.group('mins')) * 60 return None
if m.group('hours'):
res += int(m.group('hours')) * 60 * 60 duration = 0
if m.group('hours_reversed'): if secs:
res += int(m.group('hours_reversed')) * 60 * 60 duration += float(secs)
if m.group('days'): if mins:
res += int(m.group('days')) * 24 * 60 * 60 duration += float(mins) * 60
if m.group('ms'): if hours:
res += float(m.group('ms')) duration += float(hours) * 60 * 60
return res if days:
duration += float(days) * 24 * 60 * 60
if ms:
duration += float(ms)
return duration
def prepend_extension(filename, ext, expected_real_ext=None): def prepend_extension(filename, ext, expected_real_ext=None):