Merge pull request #4 from catherinedevlin/granularity

Accept "granularity" argument
This commit is contained in:
Will Roberts 2014-04-23 03:20:26 +02:00
commit 632d22637e
2 changed files with 49 additions and 1 deletions

View File

@ -119,6 +119,22 @@ class TestTimeparse(unittest.TestCase):
self.assertAlmostEqual(timeparse.timeparse('2:04:13:02.266'),
187982.266)
def test_timeparse_granularity_1(self):
'''Check that minute-level granularity applies correctly.'''
self.assertEqual(timeparse.timeparse('4:32', granularity='minutes'), 272*60)
def test_timeparse_granularity_2(self):
'''Check that minute-level granularity does not apply inappropriately.'''
self.assertEqual(timeparse.timeparse('4:32:02', granularity='minutes'), 272*60+2)
def test_timeparse_granularity_3(self):
'''Check that minute-level granularity does not apply inappropriately.'''
self.assertAlmostEqual(timeparse.timeparse('7:02.223', granularity='minutes'), 7*60 + 2.223)
def test_timeparse_granularity_4(self):
'''Check that minute-level granularity does not apply inappropriately.'''
self.assertEqual(timeparse.timeparse('0:02', granularity='seconds'), 2)
def test_timeparse_11(self):
'''timeparse test case 11.'''
# uptime format

View File

@ -84,7 +84,29 @@ MULTIPLIERS = dict([
('secs', 1)
])
def timeparse(sval):
def _interpret_as_minutes(sval, mdict):
"""
Times like "1:22" are ambiguous; do they represent minutes and seconds
or hours and minutes? By default, timeparse assumes the latter. Call
this function after parsing out a dictionary to change that assumption.
>>> import pprint
>>> pprint.pprint(_interpret_as_minutes('1:24', {'secs': '24', 'mins': '1'}))
{'hours': '1', 'mins': '24'}
"""
if ( sval.count(':') == 1
and '.' not in sval
and (('hours' not in mdict) or (mdict['hours'] is None))
and (('days' not in mdict) or (mdict['days'] is None))
and (('weeks' not in mdict) or (mdict['weeks'] is None))
):
mdict['hours'] = mdict['mins']
mdict['mins'] = mdict['secs']
mdict.pop('secs')
pass
return mdict
def timeparse(sval, granularity='seconds'):
'''
Parse a time expression, returning it as a number of seconds. If
possible, the return value will be an `int`; if this is not
@ -106,11 +128,21 @@ def timeparse(sval):
72
>>> timeparse('1.2 seconds')
1.2
If granularity is specified as ``minutes``, then ambiguous digits following
a colon will be interpreted as minutes; otherwise they are considered seconds.
>>> timeparse('1:30')
90
>>> timeparse('1:30', granularity='minutes')
5400
'''
for timefmt in TIMEFORMATS:
match = re.match(r'\s*' + timefmt + r'\s*$', sval, re.I)
if match and match.group(0).strip():
mdict = match.groupdict()
if granularity == 'minutes':
mdict = _interpret_as_minutes(sval, mdict)
# if all of the fields are integer numbers
if all(v.isdigit() for v in list(mdict.values()) if v):
return sum([MULTIPLIERS[k] * int(v, 10) for (k, v) in