diff --git a/diesel/src/pg/types/date_and_time/time.rs b/diesel/src/pg/types/date_and_time/time.rs index ac0770281ce5..24ced3186059 100644 --- a/diesel/src/pg/types/date_and_time/time.rs +++ b/diesel/src/pg/types/date_and_time/time.rs @@ -17,6 +17,11 @@ use crate::sql_types::{Date, Time, Timestamp, Timestamptz}; // Postgres timestamps start from January 1st 2000. const PG_EPOCH: PrimitiveDateTime = datetime!(2000-1-1 0:00:00); +fn to_primitive_datetime(dt: OffsetDateTime) -> PrimitiveDateTime { + let dt = dt.to_offset(UtcOffset::UTC); + PrimitiveDateTime::new(dt.date(), dt.time()) +} + #[cfg(all(feature = "time", feature = "postgres_backend"))] impl FromSql for PrimitiveDateTime { fn from_sql(bytes: PgValue<'_>) -> deserialize::Result { @@ -44,6 +49,23 @@ impl ToSql for PrimitiveDateTime { } } +// Delegate offset datetimes in terms of UTC primitive datetimes; this stores everything in the DB as UTC +#[cfg(all(feature = "time", feature = "postgres_backend"))] +impl ToSql for OffsetDateTime { + fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result { + let prim = to_primitive_datetime(*self); + >::to_sql(&prim, &mut out.reborrow()) + } +} + +#[cfg(all(feature = "time", feature = "postgres_backend"))] +impl FromSql for OffsetDateTime { + fn from_sql(bytes: PgValue<'_>) -> deserialize::Result { + let prim = >::from_sql(bytes)?; + Ok(prim.assume_utc()) + } +} + #[cfg(all(feature = "time", feature = "postgres_backend"))] impl FromSql for PrimitiveDateTime { fn from_sql(bytes: PgValue<'_>) -> deserialize::Result { diff --git a/diesel/src/sql_types/mod.rs b/diesel/src/sql_types/mod.rs index 06d8e4c31693..dc9d4ac7b61a 100644 --- a/diesel/src/sql_types/mod.rs +++ b/diesel/src/sql_types/mod.rs @@ -331,14 +331,14 @@ pub struct Time; /// - [`std::time::SystemTime`][SystemTime] (PG only) /// - [`chrono::NaiveDateTime`][NaiveDateTime] with `feature = "chrono"` /// - [`time::PrimitiveDateTime`] with `feature = "time"` -/// - [`time::OffsetDateTime`] with `feature = "time"` (MySQL only) +/// - [`time::OffsetDateTime`] with `feature = "time"` /// /// ### [`FromSql`](crate::deserialize::FromSql) impls /// /// - [`std::time::SystemTime`][SystemTime] (PG only) /// - [`chrono::NaiveDateTime`][NaiveDateTime] with `feature = "chrono"` /// - [`time::PrimitiveDateTime`] with `feature = "time"` -/// - [`time::OffsetDateTime`] with `feature = "time"` (MySQL only) +/// - [`time::OffsetDateTime`] with `feature = "time"` /// /// [SystemTime]: std::time::SystemTime #[cfg_attr(