# HG changeset patch # User Paul Boddie # Date 1439672237 -7200 # Node ID 7a2cf3dead31215aa0c328657c0e661922cb2bd3 # Parent 0549289186cde22e9ea191ceeb3776857e7da6a4 Added functions for correcting invalid datetimes. diff -r 0549289186cd -r 7a2cf3dead31 imiptools/dates.py --- a/imiptools/dates.py Sat Aug 15 22:56:51 2015 +0200 +++ b/imiptools/dates.py Sat Aug 15 22:57:17 2015 +0200 @@ -19,6 +19,7 @@ this program. If not, see . """ +from bisect import bisect_left from datetime import date, datetime, timedelta from os.path import exists from pytz import timezone, UnknownTimeZoneError @@ -470,4 +471,72 @@ return to_utc_datetime(get_datetime(recurrenceid), tzid) +# Time corrections. + +def correct_datetime(dt, resolution): + + "Correct 'dt' using the given 'resolution' details." + + carry, hour, minute, second = correct_value((dt.hour, dt.minute, dt.second), resolution) + return datetime(dt.year, dt.month, dt.day, hour, minute, second, dt.microsecond, dt.tzinfo) + \ + (carry and timedelta(1) or timedelta(0)) + +def correct_value(value, resolution): + + """ + Correct the given (hour, minute, second) tuple 'value' according to the + 'resolution' details. + """ + + limits = 23, 59, 59 + + corrected = [] + reset = False + + # Find invalid values and reset all following values. + + for v, values, limit in zip(value, resolution, limits): + if reset: + if values: + v = values[0] + else: + v = 0 + + elif values and v not in values: + reset = True + + corrected.append(v) + + value = corrected + corrected = [] + carry = 0 + + # Find invalid values and update them to the next valid value, updating more + # significant values if the next valid value is the first in the appropriate + # series. + + for v, values, limit in zip(value, resolution, limits)[::-1]: + if carry: + v += 1 + if v > limit: + if values: + v = values[0] + else: + v = 0 + corrected.append(v) + continue + else: + carry = 0 + + i = bisect_left(values, v) + if i < len(values): + v = values[i] + else: + v = values[0] + carry = 1 + + corrected.append(v) + + return [carry] + corrected[::-1] + # vim: tabstop=4 expandtab shiftwidth=4