#NEWLINE# def iso8601interval( value , argument = 'argument' ) : #NEWLINE# #INDENT# '\n    Parses ISO 8601-formatted datetime intervals into tuples of datetimes.\n\n    Accepts both a single date(time) or a full interval using either start/end\n    or start/duration notation, with the following behavior:\n\n    - Intervals are defined as inclusive start, exclusive end\n    - Single datetimes are translated into the interval spanning the\n      largest resolution not specified in the input value, up to the day.\n    - The smallest accepted resolution is 1 second.\n    - All timezones are accepted as values; returned datetimes are\n      localized to UTC. Naive inputs and date inputs will are assumed UTC.\n\n    Examples::\n\n        "2013-01-01" -> datetime(2013, 1, 1), datetime(2013, 1, 2)\n        "2013-01-01T12" -> datetime(2013, 1, 1, 12), datetime(2013, 1, 1, 13)\n        "2013-01-01/2013-02-28" -> datetime(2013, 1, 1), datetime(2013, 2, 28)\n        "2013-01-01/P3D" -> datetime(2013, 1, 1), datetime(2013, 1, 4)\n        "2013-01-01T12:00/PT30M" -> datetime(2013, 1, 1, 12), datetime(2013, 1, 1, 12, 30)\n        "2013-01-01T06:00/2013-01-01T12:00" -> datetime(2013, 1, 1, 6), datetime(2013, 1, 1, 12)\n\n    :param str value: The ISO8601 date time as a string\n    :return: Two UTC datetimes, the start and the end of the specified interval\n    :rtype: A tuple (datetime, datetime)\n    :raises ValueError: if the interval is invalid.\n    ' #NEWLINE# try : #NEWLINE# #INDENT# ( start , end ) = _parse_interval ( value ) #NEWLINE# if ( end is None ) : #NEWLINE# #INDENT# end = _expand_datetime ( start , value ) #NEWLINE# #UNINDENT# ( start , end ) = _normalize_interval ( start , end , value ) #NEWLINE# #UNINDENT# except ValueError : #NEWLINE# #INDENT# msg = 'Invalid {arg}: {value}. {arg} must be a valid ISO8601 date/time interval.' #NEWLINE# raise ValueError ( msg . format ( arg = argument , value = value ) ) #NEWLINE# #UNINDENT# return ( start , end )