fix: Use rfc3339 to decode date from text (#3411)

This commit is contained in:
Pierre Wehbe 2024-09-02 12:34:51 -07:00 committed by GitHub
parent ad2936a9c4
commit fd80f998ac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -86,22 +86,41 @@ impl<Tz: TimeZone> Encode<'_, Postgres> for DateTime<Tz> {
impl<'r> Decode<'r, Postgres> for DateTime<Local> { impl<'r> Decode<'r, Postgres> for DateTime<Local> {
fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> { fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> {
let naive = <NaiveDateTime as Decode<Postgres>>::decode(value)?; let fixed = <DateTime<FixedOffset> as Decode<Postgres>>::decode(value)?;
Ok(Local.from_utc_datetime(&naive)) Ok(Local.from_utc_datetime(&fixed.naive_utc()))
} }
} }
impl<'r> Decode<'r, Postgres> for DateTime<Utc> { impl<'r> Decode<'r, Postgres> for DateTime<Utc> {
fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> { fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> {
let naive = <NaiveDateTime as Decode<Postgres>>::decode(value)?; let fixed = <DateTime<FixedOffset> as Decode<Postgres>>::decode(value)?;
Ok(Utc.from_utc_datetime(&naive)) Ok(Utc.from_utc_datetime(&fixed.naive_utc()))
} }
} }
impl<'r> Decode<'r, Postgres> for DateTime<FixedOffset> { impl<'r> Decode<'r, Postgres> for DateTime<FixedOffset> {
fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> { fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> {
let naive = <NaiveDateTime as Decode<Postgres>>::decode(value)?; Ok(match value.format() {
Ok(Utc.fix().from_utc_datetime(&naive)) PgValueFormat::Binary => {
let naive = <NaiveDateTime as Decode<Postgres>>::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"
},
)?
}
})
} }
} }