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" + }, + )? + } + }) } }