Parse a string and return a datetime.datetime. This function supports time zone offsets. When the input contains one, the output uses a timezone with a fixed offset from UTC. Raise ValueError if the input is well formatted but not a valid datetime. Return None if the input isn't we
(value)
| 103 | |
| 104 | |
| 105 | def parse_datetime(value): |
| 106 | """Parse a string and return a datetime.datetime. |
| 107 | |
| 108 | This function supports time zone offsets. When the input contains one, |
| 109 | the output uses a timezone with a fixed offset from UTC. |
| 110 | |
| 111 | Raise ValueError if the input is well formatted but not a valid datetime. |
| 112 | Return None if the input isn't well formatted. |
| 113 | """ |
| 114 | try: |
| 115 | return datetime.datetime.fromisoformat(value) |
| 116 | except ValueError: |
| 117 | if match := datetime_re.match(value): |
| 118 | kw = match.groupdict() |
| 119 | kw["microsecond"] = kw["microsecond"] and kw["microsecond"].ljust(6, "0") |
| 120 | tzinfo = kw.pop("tzinfo") |
| 121 | if tzinfo == "Z": |
| 122 | tzinfo = datetime.UTC |
| 123 | elif tzinfo is not None: |
| 124 | offset_mins = int(tzinfo[-2:]) if len(tzinfo) > 3 else 0 |
| 125 | offset = 60 * int(tzinfo[1:3]) + offset_mins |
| 126 | if tzinfo[0] == "-": |
| 127 | offset = -offset |
| 128 | tzinfo = get_fixed_timezone(offset) |
| 129 | kw = {k: int(v) for k, v in kw.items() if v is not None} |
| 130 | return datetime.datetime(**kw, tzinfo=tzinfo) |
| 131 | |
| 132 | |
| 133 | def parse_duration(value): |