def fromISO8601TimeAndDate(klass, iso8601string, tzinfo=None):
def calculateTimezone():<EOL><INDENT>if groups['<STR_LIT>'] == '<STR_LIT>':<EOL><INDENT>return FixedOffset(<NUM_LIT:0>, <NUM_LIT:0>)<EOL><DEDENT>else:<EOL><INDENT>tzhour = groups.pop('<STR_LIT>')<EOL>tzmin = groups.pop('<STR_LIT>')<EOL>if tzhour is not None:<EOL><INDENT>return FixedOffset(int(tzhour), int(tzmin or <NUM_LIT:0>))<EOL><DEDENT><DEDENT>return tzinfo or FixedOffset(<NUM_LIT:0>, <NUM_LIT:0>)<EOL><DEDENT>def coerceGroups():<EOL><INDENT>groups['<STR_LIT>'] = groups['<STR_LIT>'] or groups['<STR_LIT>']<EOL>groups['<STR_LIT>'] = groups['<STR_LIT>'] or groups['<STR_LIT>']<EOL>defaultTo0 = ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']<EOL>defaultTo1 = ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']<EOL>if groups['<STR_LIT>'] is None:<EOL><INDENT>groups['<STR_LIT>'] = '<STR_LIT:0>'<EOL><DEDENT>for key in defaultTo0:<EOL><INDENT>if groups[key] is None:<EOL><INDENT>groups[key] = <NUM_LIT:0><EOL><DEDENT><DEDENT>for key in defaultTo1:<EOL><INDENT>if groups[key] is None:<EOL><INDENT>groups[key] = <NUM_LIT:1><EOL><DEDENT><DEDENT>groups['<STR_LIT>'] = float('<STR_LIT:.>'+groups['<STR_LIT>'])<EOL>for key in defaultTo0 + defaultTo1 + ['<STR_LIT>']:<EOL><INDENT>groups[key] = int(groups[key])<EOL><DEDENT>for group, min, max in [<EOL>('<STR_LIT>', <NUM_LIT:1>, <NUM_LIT>),<EOL>('<STR_LIT>', <NUM_LIT:1>, <NUM_LIT:7>),<EOL>('<STR_LIT>', <NUM_LIT:1>, <NUM_LIT:12>),<EOL>('<STR_LIT>', <NUM_LIT:1>, <NUM_LIT>),<EOL>('<STR_LIT>', <NUM_LIT:0>, <NUM_LIT>),<EOL>('<STR_LIT>', <NUM_LIT:0>, <NUM_LIT>),<EOL>('<STR_LIT>', <NUM_LIT:0>, <NUM_LIT>),<EOL>('<STR_LIT>', <NUM_LIT:1>, <NUM_LIT>)]:<EOL><INDENT>if not min <= groups[group] <= max:<EOL><INDENT>raise ValueError('<STR_LIT>' % (group, min, max))<EOL><DEDENT><DEDENT><DEDENT>def determineResolution():<EOL><INDENT>if match.group('<STR_LIT>') is not None:<EOL><INDENT>return max(datetime.timedelta.resolution,<EOL>datetime.timedelta(<EOL>microseconds=<NUM_LIT:1> * <NUM_LIT:10> ** -len(<EOL>match.group('<STR_LIT>')) * <NUM_LIT>))<EOL><DEDENT>for testGroup, resolution in [<EOL>('<STR_LIT>', datetime.timedelta(seconds=<NUM_LIT:1>)),<EOL>('<STR_LIT>', datetime.timedelta(minutes=<NUM_LIT:1>)),<EOL>('<STR_LIT>', datetime.timedelta(hours=<NUM_LIT:1>)),<EOL>('<STR_LIT>', datetime.timedelta(days=<NUM_LIT:1>)),<EOL>('<STR_LIT>', datetime.timedelta(days=<NUM_LIT:1>)),<EOL>('<STR_LIT>', datetime.timedelta(days=<NUM_LIT:1>)),<EOL>('<STR_LIT>', datetime.timedelta(weeks=<NUM_LIT:1>)),<EOL>('<STR_LIT>', datetime.timedelta(weeks=<NUM_LIT:1>))]:<EOL><INDENT>if match.group(testGroup) is not None:<EOL><INDENT>return resolution<EOL><DEDENT><DEDENT>if match.group('<STR_LIT>') is not Noneor match.group('<STR_LIT>') is not None:<EOL><INDENT>if self._time.month == <NUM_LIT:12>:<EOL><INDENT>return datetime.timedelta(days=<NUM_LIT>)<EOL><DEDENT>nextMonth = self._time.replace(month=self._time.month+<NUM_LIT:1>)<EOL>return nextMonth - self._time<EOL><DEDENT>else:<EOL><INDENT>nextYear = self._time.replace(year=self._time.year+<NUM_LIT:1>)<EOL>return nextYear - self._time<EOL><DEDENT><DEDENT>def calculateDtime(tzinfo):<EOL><INDENT>"""<STR_LIT>"""<EOL>if match.group('<STR_LIT>') is not Noneor match.group('<STR_LIT>') is not None:<EOL><INDENT>if not <NUM_LIT:0> < groups['<STR_LIT>'] <= <NUM_LIT>:<EOL><INDENT>raise ValueError(<EOL>'<STR_LIT>' % (groups['<STR_LIT>'],))<EOL><DEDENT>dtime = datetime.datetime(<EOL>groups['<STR_LIT>'],<EOL><NUM_LIT:1>,<EOL><NUM_LIT:4>,<EOL>groups['<STR_LIT>'],<EOL>groups['<STR_LIT>'],<EOL>groups['<STR_LIT>'],<EOL>int(round(groups['<STR_LIT>'] * <NUM_LIT>)),<EOL>tzinfo=tzinfo<EOL>)<EOL>dtime -= datetime.timedelta(days = dtime.weekday())<EOL>dtime += datetime.timedelta(<EOL>days = (groups['<STR_LIT>']-<NUM_LIT:1>) * <NUM_LIT:7> + groups['<STR_LIT>'] - <NUM_LIT:1>)<EOL>if dtime.isocalendar() != (<EOL>groups['<STR_LIT>'], groups['<STR_LIT>'], groups['<STR_LIT>']):<EOL><INDENT>raise ValueError('<STR_LIT>' %<EOL>(groups['<STR_LIT>'], groups['<STR_LIT>']))<EOL><DEDENT>return dtime<EOL><DEDENT>if match.group('<STR_LIT>') is not None:<EOL><INDENT>dtime = datetime.datetime(<EOL>groups['<STR_LIT>'],<EOL><NUM_LIT:1>,<EOL><NUM_LIT:1>,<EOL>groups['<STR_LIT>'],<EOL>groups['<STR_LIT>'],<EOL>groups['<STR_LIT>'],<EOL>int(round(groups['<STR_LIT>'] * <NUM_LIT>)),<EOL>tzinfo=tzinfo<EOL>)<EOL>dtime += datetime.timedelta(days=groups['<STR_LIT>']-<NUM_LIT:1>)<EOL>if dtime.year != groups['<STR_LIT>']:<EOL><INDENT>raise ValueError(<EOL>'<STR_LIT>' %<EOL>(groups['<STR_LIT>'], groups['<STR_LIT>']))<EOL><DEDENT>return dtime<EOL><DEDENT>else:<EOL><INDENT>return datetime.datetime(<EOL>groups['<STR_LIT>'],<EOL>groups['<STR_LIT>'],<EOL>groups['<STR_LIT>'],<EOL>groups['<STR_LIT>'],<EOL>groups['<STR_LIT>'],<EOL>groups['<STR_LIT>'],<EOL>int(round(groups['<STR_LIT>'] * <NUM_LIT>)),<EOL>tzinfo=tzinfo<EOL>)<EOL><DEDENT><DEDENT>match = klass.iso8601pattern.match(iso8601string)<EOL>if match is None:<EOL><INDENT>raise ValueError(<EOL>'<STR_LIT>' %<EOL>(iso8601string,))<EOL><DEDENT>groups = match.groupdict()<EOL>coerceGroups()<EOL>if match.group('<STR_LIT>') is not None:<EOL><INDENT>timezone = calculateTimezone()<EOL><DEDENT>else:<EOL><INDENT>timezone = None<EOL><DEDENT>self = klass.fromDatetime(calculateDtime(timezone))<EOL>self.resolution = determineResolution()<EOL>return self<EOL>
Return a new Time instance from a string formated as in ISO 8601.

        If the given string contains no timezone, it is assumed to be in the
        timezone specified by the parameter `tzinfo`, or UTC if tzinfo is None.
        An input string with an explicit timezone will always override tzinfo.

        If the given iso8601string does not contain all parts of the time, they
        will default to 0 in the timezone given by `tzinfo`.

        WARNING: this function is incomplete. ISO is dumb and their standards
        are not free. Only a subset of all valid ISO 8601 dates are parsed,
        because I can't find a formal description of the format. However,
        common ones should work.