@@ -72,10 +72,12 @@ def parse_date(value):
72
72
Raise ValueError if the input is well formatted but not a valid date.
73
73
Return None if the input isn't well formatted.
74
74
"""
75
- match = date_re .match (value )
76
- if match :
77
- kw = {k : int (v ) for k , v in match .groupdict ().items ()}
78
- return datetime .date (** kw )
75
+ try :
76
+ return datetime .date .fromisoformat (value )
77
+ except ValueError :
78
+ if match := date_re .match (value ):
79
+ kw = {k : int (v ) for k , v in match .groupdict ().items ()}
80
+ return datetime .date (** kw )
79
81
80
82
81
83
def parse_time (value ):
@@ -87,12 +89,18 @@ def parse_time(value):
87
89
Return None if the input isn't well formatted, in particular if it
88
90
contains an offset.
89
91
"""
90
- match = time_re .match (value )
91
- if match :
92
- kw = match .groupdict ()
93
- kw ['microsecond' ] = kw ['microsecond' ] and kw ['microsecond' ].ljust (6 , '0' )
94
- kw = {k : int (v ) for k , v in kw .items () if v is not None }
95
- return datetime .time (** kw )
92
+ try :
93
+ # The fromisoformat() method takes time zone info into account and
94
+ # returns a time with a tzinfo component, if possible. However, there
95
+ # are no circumstances where aware datetime.time objects make sense, so
96
+ # remove the time zone offset.
97
+ return datetime .time .fromisoformat (value ).replace (tzinfo = None )
98
+ except ValueError :
99
+ if match := time_re .match (value ):
100
+ kw = match .groupdict ()
101
+ kw ['microsecond' ] = kw ['microsecond' ] and kw ['microsecond' ].ljust (6 , '0' )
102
+ kw = {k : int (v ) for k , v in kw .items () if v is not None }
103
+ return datetime .time (** kw )
96
104
97
105
98
106
def parse_datetime (value ):
@@ -104,22 +112,23 @@ def parse_datetime(value):
104
112
Raise ValueError if the input is well formatted but not a valid datetime.
105
113
Return None if the input isn't well formatted.
106
114
"""
107
- match = datetime_re .match (value )
108
- if match :
109
- kw = match .groupdict ()
110
- kw ['microsecond' ] = kw ['microsecond' ] and kw ['microsecond' ].ljust (6 , '0' )
111
- tzinfo = kw .pop ('tzinfo' )
112
- if tzinfo == 'Z' :
113
- tzinfo = utc
114
- elif tzinfo is not None :
115
- offset_mins = int (tzinfo [- 2 :]) if len (tzinfo ) > 3 else 0
116
- offset = 60 * int (tzinfo [1 :3 ]) + offset_mins
117
- if tzinfo [0 ] == '-' :
118
- offset = - offset
119
- tzinfo = get_fixed_timezone (offset )
120
- kw = {k : int (v ) for k , v in kw .items () if v is not None }
121
- kw ['tzinfo' ] = tzinfo
122
- return datetime .datetime (** kw )
115
+ try :
116
+ return datetime .datetime .fromisoformat (value )
117
+ except ValueError :
118
+ if match := datetime_re .match (value ):
119
+ kw = match .groupdict ()
120
+ kw ['microsecond' ] = kw ['microsecond' ] and kw ['microsecond' ].ljust (6 , '0' )
121
+ tzinfo = kw .pop ('tzinfo' )
122
+ if tzinfo == 'Z' :
123
+ tzinfo = utc
124
+ elif tzinfo is not None :
125
+ offset_mins = int (tzinfo [- 2 :]) if len (tzinfo ) > 3 else 0
126
+ offset = 60 * int (tzinfo [1 :3 ]) + offset_mins
127
+ if tzinfo [0 ] == '-' :
128
+ offset = - offset
129
+ tzinfo = get_fixed_timezone (offset )
130
+ kw = {k : int (v ) for k , v in kw .items () if v is not None }
131
+ return datetime .datetime (** kw , tzinfo = tzinfo )
123
132
124
133
125
134
def parse_duration (value ):
0 commit comments