diff options
author | Miro Hron?ok <miro@hroncok.cz> | 2018-06-08 18:49:42 +0200 |
---|---|---|
committer | Miro Hron?ok <miro@hroncok.cz> | 2018-06-08 18:49:42 +0200 |
commit | bb9bdf7e5b5cb0d3458242c5b8ba6134efb282a4 (patch) | |
tree | e3f03e7ce1f234e0c91075da6d0b56040f693162 /paste/util/dateinterval.py | |
download | paste-git-bb9bdf7e5b5cb0d3458242c5b8ba6134efb282a4.tar.gz |
Don't raise StopIteration from generator, return instead
See https://www.python.org/dev/peps/pep-0479/
Diffstat (limited to 'paste/util/dateinterval.py')
-rw-r--r-- | paste/util/dateinterval.py | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/paste/util/dateinterval.py b/paste/util/dateinterval.py new file mode 100644 index 0000000..023bce4 --- /dev/null +++ b/paste/util/dateinterval.py @@ -0,0 +1,104 @@ +""" +DateInterval.py + +Convert interval strings (in the form of 1w2d, etc) to +seconds, and back again. Is not exactly about months or +years (leap years in particular). + +Accepts (y)ear, (b)month, (w)eek, (d)ay, (h)our, (m)inute, (s)econd. + +Exports only timeEncode and timeDecode functions. +""" + +import re + +__all__ = ['interval_decode', 'interval_encode'] + +second = 1 +minute = second*60 +hour = minute*60 +day = hour*24 +week = day*7 +month = day*30 +year = day*365 +timeValues = { + 'y': year, + 'b': month, + 'w': week, + 'd': day, + 'h': hour, + 'm': minute, + 's': second, + } +timeOrdered = list(timeValues.items()) +timeOrdered.sort(key=lambda x: x[1], reverse=True) + + +def interval_encode(seconds, include_sign=False): + """Encodes a number of seconds (representing a time interval) + into a form like 1h2d3s. + + >>> interval_encode(10) + '10s' + >>> interval_encode(493939) + '5d17h12m19s' + """ + s = '' + orig = seconds + seconds = abs(seconds) + for char, amount in timeOrdered: + if seconds >= amount: + i, seconds = divmod(seconds, amount) + s += '%i%s' % (i, char) + if orig < 0: + s = '-' + s + elif not orig: + return '0' + elif include_sign: + s = '+' + s + return s + +_timeRE = re.compile(r'[0-9]+[a-zA-Z]') +def interval_decode(s): + """Decodes a number in the format 1h4d3m (1 hour, 3 days, 3 minutes) + into a number of seconds + + >>> interval_decode('40s') + 40 + >>> interval_decode('10000s') + 10000 + >>> interval_decode('3d1w45s') + 864045 + """ + time = 0 + sign = 1 + s = s.strip() + if s.startswith('-'): + s = s[1:] + sign = -1 + elif s.startswith('+'): + s = s[1:] + for match in allMatches(s, _timeRE): + char = match.group(0)[-1].lower() + if char not in timeValues: + # @@: should signal error + continue + time += int(match.group(0)[:-1]) * timeValues[char] + return time + +# @@-sgd 2002-12-23 - this function does not belong in this module, find a better place. +def allMatches(source, regex): + """Return a list of matches for regex in source + """ + pos = 0 + end = len(source) + rv = [] + match = regex.search(source, pos) + while match: + rv.append(match) + match = regex.search(source, match.end() ) + return rv + +if __name__ == '__main__': + import doctest + doctest.testmod() |