Skip to content

Commit 8cd2a6e

Browse files
committed
fix(odbc): handle datetime parsing without timezone info
1 parent 2de1174 commit 8cd2a6e

File tree

1 file changed

+36
-2
lines changed

1 file changed

+36
-2
lines changed

sqlx-core/src/odbc/types/chrono.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,14 +211,48 @@ impl<'r> Decode<'r, Odbc> for NaiveDateTime {
211211
impl<'r> Decode<'r, Odbc> for DateTime<Utc> {
212212
fn decode(value: OdbcValueRef<'r>) -> Result<Self, BoxDynError> {
213213
let s = <String as Decode<'r, Odbc>>::decode(value)?;
214-
Ok(s.parse()?)
214+
let s_trimmed = s.trim();
215+
216+
// First try to parse as a UTC timestamp with timezone
217+
if let Ok(dt) = s_trimmed.parse::<DateTime<Utc>>() {
218+
return Ok(dt);
219+
}
220+
221+
// If that fails, try to parse as a naive datetime and convert to UTC
222+
if let Ok(naive_dt) = NaiveDateTime::parse_from_str(s_trimmed, "%Y-%m-%d %H:%M:%S") {
223+
return Ok(DateTime::<Utc>::from_naive_utc_and_offset(naive_dt, Utc));
224+
}
225+
226+
// Finally, try chrono's default naive datetime parser
227+
if let Ok(naive_dt) = s_trimmed.parse::<NaiveDateTime>() {
228+
return Ok(DateTime::<Utc>::from_naive_utc_and_offset(naive_dt, Utc));
229+
}
230+
231+
Err(format!("Cannot parse '{}' as DateTime<Utc>", s_trimmed).into())
215232
}
216233
}
217234

218235
impl<'r> Decode<'r, Odbc> for DateTime<FixedOffset> {
219236
fn decode(value: OdbcValueRef<'r>) -> Result<Self, BoxDynError> {
220237
let s = <String as Decode<'r, Odbc>>::decode(value)?;
221-
Ok(s.parse()?)
238+
let s_trimmed = s.trim();
239+
240+
// First try to parse as a timestamp with timezone/offset
241+
if let Ok(dt) = s_trimmed.parse::<DateTime<FixedOffset>>() {
242+
return Ok(dt);
243+
}
244+
245+
// If that fails, try to parse as a naive datetime and assume UTC (zero offset)
246+
if let Ok(naive_dt) = NaiveDateTime::parse_from_str(s_trimmed, "%Y-%m-%d %H:%M:%S") {
247+
return Ok(DateTime::<Utc>::from_naive_utc_and_offset(naive_dt, Utc).fixed_offset());
248+
}
249+
250+
// Finally, try chrono's default naive datetime parser
251+
if let Ok(naive_dt) = s_trimmed.parse::<NaiveDateTime>() {
252+
return Ok(DateTime::<Utc>::from_naive_utc_and_offset(naive_dt, Utc).fixed_offset());
253+
}
254+
255+
Err(format!("Cannot parse '{}' as DateTime<FixedOffset>", s_trimmed).into())
222256
}
223257
}
224258

0 commit comments

Comments
 (0)