Skip to content

Commit d53143c

Browse files
committed
Add FromSql/ToSql<Timestamp> to Pg backend for OffsetDateTime
1 parent a5c82df commit d53143c

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

diesel/src/pg/types/date_and_time/time.rs

+38-1
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,16 @@ use super::{PgDate, PgTime, PgTimestamp};
1212
use crate::deserialize::{self, FromSql};
1313
use crate::pg::{Pg, PgValue};
1414
use crate::serialize::{self, Output, ToSql};
15-
use crate::sql_types::{Date, Time, Timestamp, Timestamptz};
15+
use crate::sql_types::{Date, Datetime, Time, Timestamp, Timestamptz};
1616

1717
// Postgres timestamps start from January 1st 2000.
1818
const PG_EPOCH: PrimitiveDateTime = datetime!(2000-1-1 0:00:00);
1919

20+
fn to_primitive_datetime(dt: OffsetDateTime) -> PrimitiveDateTime {
21+
let dt = dt.to_offset(UtcOffset::UTC);
22+
PrimitiveDateTime::new(dt.date(), dt.time())
23+
}
24+
2025
#[cfg(all(feature = "time", feature = "postgres_backend"))]
2126
impl FromSql<Timestamp, Pg> for PrimitiveDateTime {
2227
fn from_sql(bytes: PgValue<'_>) -> deserialize::Result<Self> {
@@ -44,6 +49,38 @@ impl ToSql<Timestamp, Pg> for PrimitiveDateTime {
4449
}
4550
}
4651

52+
// Delegate offset datetimes in terms of UTC primitive datetimes; this stores everything in the DB as UTC
53+
#[cfg(all(feature = "time", feature = "postgres_backend"))]
54+
impl ToSql<Datetime, Pg> for OffsetDateTime {
55+
fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
56+
let prim = to_primitive_datetime(*self);
57+
<PrimitiveDateTime as ToSql<Datetime, Pg>>::to_sql(&prim, &mut out.reborrow())
58+
}
59+
}
60+
61+
#[cfg(all(feature = "time", feature = "postgres_backend"))]
62+
impl FromSql<Datetime, Pg> for OffsetDateTime {
63+
fn from_sql(bytes: PgValue<'_>) -> deserialize::Result<Self> {
64+
let prim = <PrimitiveDateTime as FromSql<Datetime, Pg>>::from_sql(bytes)?;
65+
Ok(prim.assume_utc())
66+
}
67+
}
68+
69+
// delegate timestamp column to datetime column for offset datetimes
70+
#[cfg(all(feature = "time", feature = "postgres_backend"))]
71+
impl ToSql<Timestamp, Pg> for OffsetDateTime {
72+
fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result {
73+
<OffsetDateTime as ToSql<Datetime, Pg>>::to_sql(self, out)
74+
}
75+
}
76+
77+
#[cfg(all(feature = "time", feature = "postgres_backend"))]
78+
impl FromSql<Timestamp, Pg> for OffsetDateTime {
79+
fn from_sql(bytes: PgValue<'_>) -> deserialize::Result<Self> {
80+
<OffsetDateTime as FromSql<Datetime, Pg>>::from_sql(bytes)
81+
}
82+
}
83+
4784
#[cfg(all(feature = "time", feature = "postgres_backend"))]
4885
impl FromSql<Timestamptz, Pg> for PrimitiveDateTime {
4986
fn from_sql(bytes: PgValue<'_>) -> deserialize::Result<Self> {

diesel/src/sql_types/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -331,14 +331,14 @@ pub struct Time;
331331
/// - [`std::time::SystemTime`][SystemTime] (PG only)
332332
/// - [`chrono::NaiveDateTime`][NaiveDateTime] with `feature = "chrono"`
333333
/// - [`time::PrimitiveDateTime`] with `feature = "time"`
334-
/// - [`time::OffsetDateTime`] with `feature = "time"` (MySQL only)
334+
/// - [`time::OffsetDateTime`] with `feature = "time"`
335335
///
336336
/// ### [`FromSql`](crate::deserialize::FromSql) impls
337337
///
338338
/// - [`std::time::SystemTime`][SystemTime] (PG only)
339339
/// - [`chrono::NaiveDateTime`][NaiveDateTime] with `feature = "chrono"`
340340
/// - [`time::PrimitiveDateTime`] with `feature = "time"`
341-
/// - [`time::OffsetDateTime`] with `feature = "time"` (MySQL only)
341+
/// - [`time::OffsetDateTime`] with `feature = "time"`
342342
///
343343
/// [SystemTime]: std::time::SystemTime
344344
#[cfg_attr(

0 commit comments

Comments
 (0)