@classmethod<EOL><INDENT>def from_ISO_8601(cls, date_string, time_string, tz_string):<DEDENT>
<EOL>if tz_string:<EOL><INDENT>tz_offset = (int(tz_string[<NUM_LIT:1>:<NUM_LIT:3>]) * <NUM_LIT>) + int(tz_string[<NUM_LIT:3>:])<EOL>if tz_string[<NUM_LIT:0>] == '<STR_LIT:->':<EOL><INDENT>tz_offset = -tz_offset<EOL><DEDENT><DEDENT>else:<EOL><INDENT>tz_offset = None<EOL><DEDENT>if time_string == '<STR_LIT>':<EOL><INDENT>time_string = '<STR_LIT>'<EOL>tz_offset = None<EOL><DEDENT>datetime_string = date_string + time_string[:<NUM_LIT>]<EOL>precision = min((len(datetime_string) - <NUM_LIT:2>) // <NUM_LIT:2>, <NUM_LIT:7>)<EOL>if precision <= <NUM_LIT:0>:<EOL><INDENT>return None<EOL><DEDENT>fmt = '<STR_LIT>'.join(('<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>')[:precision])<EOL>return cls(<EOL>(datetime.strptime(datetime_string, fmt), precision, tz_offset))<EOL>
Sufficiently general ISO 8601 parser.

        Inputs must be in "basic" format, i.e. no '-' or ':' separators.
        See https://en.wikipedia.org/wiki/ISO_8601