From 3e9473c4ea9c33281b92f86cd96802efafc97922 Mon Sep 17 00:00:00 2001 From: Pierre Wehbe Date: Tue, 6 Aug 2024 23:05:30 -0700 Subject: [PATCH] fix: Use rfc3339 to decode date from text --- sqlx-postgres/src/types/chrono/datetime.rs | 31 +++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/sqlx-postgres/src/types/chrono/datetime.rs b/sqlx-postgres/src/types/chrono/datetime.rs index 2dceb9e93a..77f900d42a 100644 --- a/sqlx-postgres/src/types/chrono/datetime.rs +++ b/sqlx-postgres/src/types/chrono/datetime.rs @@ -86,22 +86,41 @@ impl Encode<'_, Postgres> for DateTime { impl<'r> Decode<'r, Postgres> for DateTime { fn decode(value: PgValueRef<'r>) -> Result { - let naive = >::decode(value)?; - Ok(Local.from_utc_datetime(&naive)) + let fixed = as Decode>::decode(value)?; + Ok(Local.from_utc_datetime(&fixed.naive_utc())) } } impl<'r> Decode<'r, Postgres> for DateTime { fn decode(value: PgValueRef<'r>) -> Result { - let naive = >::decode(value)?; - Ok(Utc.from_utc_datetime(&naive)) + let fixed = as Decode>::decode(value)?; + Ok(Utc.from_utc_datetime(&fixed.naive_utc())) } } impl<'r> Decode<'r, Postgres> for DateTime { fn decode(value: PgValueRef<'r>) -> Result { - let naive = >::decode(value)?; - Ok(Utc.fix().from_utc_datetime(&naive)) + Ok(match value.format() { + PgValueFormat::Binary => { + let naive = >::decode(value)?; + Utc.fix().from_utc_datetime(&naive) + } + + PgValueFormat::Text => { + let s = value.as_str()?; + DateTime::parse_from_str( + s, + if s.contains('+') || s.contains('-') { + // Contains a time-zone specifier + // This is given for timestamptz for some reason + // Postgres already guarantees this to always be UTC + "%Y-%m-%d %H:%M:%S%.f%#z" + } else { + "%Y-%m-%d %H:%M:%S%.f" + }, + )? + } + }) } }