Convert an ISO 8601 string into a datetime object. The following formats are supported: - 2020-03-03T09:21:43.636153304Z - 2020-03-03T15:52:30.136257504-0600 - 2020-03-03T15:52:30.136257504 :param string: The string to parse. :return: Returns an aware datetime object o
(string: str)
| 37 | |
| 38 | |
| 39 | def str_to_datetime(string: str) -> datetime.datetime: |
| 40 | """ |
| 41 | Convert an ISO 8601 string into a datetime object. |
| 42 | The following formats are supported: |
| 43 | |
| 44 | - 2020-03-03T09:21:43.636153304Z |
| 45 | - 2020-03-03T15:52:30.136257504-0600 |
| 46 | - 2020-03-03T15:52:30.136257504 |
| 47 | |
| 48 | :param string: The string to parse. |
| 49 | :return: Returns an aware datetime object of the given date |
| 50 | and time string. |
| 51 | :raises: :exc:`~exceptions.ValueError` for an unknown |
| 52 | datetime string. |
| 53 | """ |
| 54 | fmts = [ |
| 55 | '%Y-%m-%dT%H:%M:%S.%f', |
| 56 | '%Y-%m-%dT%H:%M:%S.%f%z', |
| 57 | ] |
| 58 | |
| 59 | # In *all* cases, the 9 digit second precision is too much for |
| 60 | # Python's strptime. Shorten it to 6 digits. |
| 61 | p = re.compile(r'(\.[\d]{6})[\d]*') |
| 62 | string = p.sub(r'\1', string) |
| 63 | |
| 64 | # Replace trailing Z with -0000, since (on Python 3.6.8) it |
| 65 | # won't parse. |
| 66 | if string and string[-1] == 'Z': |
| 67 | string = string[:-1] + '-0000' |
| 68 | |
| 69 | for fmt in fmts: |
| 70 | try: |
| 71 | dt = datetime.datetime.strptime(string, fmt) |
| 72 | # Make sure the datetime object is aware (timezone is set). |
| 73 | # If not, then assume the time is in UTC. |
| 74 | if dt.tzinfo is None: |
| 75 | dt = dt.replace(tzinfo=datetime.timezone.utc) |
| 76 | return dt |
| 77 | except ValueError: |
| 78 | pass |
| 79 | |
| 80 | raise ValueError( |
| 81 | "Time data {} does not match one of the formats {}".format( |
| 82 | string, str(fmts) |
| 83 | ) |
| 84 | ) |
| 85 | |
| 86 | |
| 87 | def parse_timedelta(delta: str) -> Optional[datetime.timedelta]: |