diesel/pg/types/date_and_time/
mod.rs

1use std::io::Write;
2use std::ops::Add;
3
4use deserialize::{self, FromSql};
5use pg::Pg;
6use serialize::{self, IsNull, Output, ToSql};
7use sql_types::{self, Date, Interval, Time, Timestamp, Timestamptz};
8
9#[cfg(feature = "chrono")]
10mod chrono;
11#[cfg(feature = "deprecated-time")]
12mod deprecated_time;
13#[cfg(feature = "quickcheck")]
14mod quickcheck_impls;
15mod std_time;
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, FromSqlRow, AsExpression)]
18#[sql_type = "Timestamp"]
19#[sql_type = "Timestamptz"]
20/// Timestamps are represented in Postgres as a 64 bit signed integer representing the number of
21/// microseconds since January 1st 2000. This struct is a dumb wrapper type, meant only to indicate
22/// the integer's meaning.
23pub struct PgTimestamp(pub i64);
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, FromSqlRow, AsExpression)]
26#[sql_type = "Date"]
27/// Dates are represented in Postgres as a 32 bit signed integer representing the number of julian
28/// days since January 1st 2000. This struct is a dumb wrapper type, meant only to indicate the
29/// integer's meaning.
30pub struct PgDate(pub i32);
31
32/// Time is represented in Postgres as a 64 bit signed integer representing the number of
33/// microseconds since midnight. This struct is a dumb wrapper type, meant only to indicate the
34/// integer's meaning.
35#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, FromSqlRow, AsExpression)]
36#[sql_type = "Time"]
37pub struct PgTime(pub i64);
38
39/// Intervals in Postgres are separated into 3 parts. A 64 bit integer representing time in
40/// microseconds, a 32 bit integer representing number of days, and a 32 bit integer
41/// representing number of months. This struct is a dumb wrapper type, meant only to indicate the
42/// meaning of these parts.
43#[derive(Debug, Clone, Copy, PartialEq, Eq, FromSqlRow, AsExpression)]
44#[sql_type = "Interval"]
45pub struct PgInterval {
46    /// The number of whole microseconds
47    pub microseconds: i64,
48    /// The number of whole days
49    pub days: i32,
50    /// The number of whole months
51    pub months: i32,
52}
53
54impl PgInterval {
55    /// Constructs a new `PgInterval`
56    ///
57    /// No conversion occurs on the arguments. It is valid to provide a number
58    /// of microseconds greater than the longest possible day, or a number of
59    /// days greater than the longest possible month, as it is impossible to say
60    /// how many months are in "40 days" without knowing a precise date.
61    pub fn new(microseconds: i64, days: i32, months: i32) -> Self {
62        PgInterval {
63            microseconds: microseconds,
64            days: days,
65            months: months,
66        }
67    }
68
69    /// Equivalent to `new(microseconds, 0, 0)`
70    pub fn from_microseconds(microseconds: i64) -> Self {
71        Self::new(microseconds, 0, 0)
72    }
73
74    /// Equivalent to `new(0, days, 0)`
75    pub fn from_days(days: i32) -> Self {
76        Self::new(0, days, 0)
77    }
78
79    /// Equivalent to `new(0, 0, months)`
80    pub fn from_months(months: i32) -> Self {
81        Self::new(0, 0, months)
82    }
83}
84
85impl ToSql<sql_types::Timestamp, Pg> for PgTimestamp {
86    fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
87        ToSql::<sql_types::BigInt, Pg>::to_sql(&self.0, out)
88    }
89}
90
91impl FromSql<sql_types::Timestamp, Pg> for PgTimestamp {
92    fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
93        FromSql::<sql_types::BigInt, Pg>::from_sql(bytes).map(PgTimestamp)
94    }
95}
96
97impl ToSql<sql_types::Timestamptz, Pg> for PgTimestamp {
98    fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
99        ToSql::<sql_types::Timestamp, Pg>::to_sql(self, out)
100    }
101}
102
103impl FromSql<sql_types::Timestamptz, Pg> for PgTimestamp {
104    fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
105        FromSql::<sql_types::Timestamp, Pg>::from_sql(bytes)
106    }
107}
108
109impl ToSql<sql_types::Date, Pg> for PgDate {
110    fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
111        ToSql::<sql_types::Integer, Pg>::to_sql(&self.0, out)
112    }
113}
114
115impl FromSql<sql_types::Date, Pg> for PgDate {
116    fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
117        FromSql::<sql_types::Integer, Pg>::from_sql(bytes).map(PgDate)
118    }
119}
120
121impl ToSql<sql_types::Time, Pg> for PgTime {
122    fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
123        ToSql::<sql_types::BigInt, Pg>::to_sql(&self.0, out)
124    }
125}
126
127impl FromSql<sql_types::Time, Pg> for PgTime {
128    fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
129        FromSql::<sql_types::BigInt, Pg>::from_sql(bytes).map(PgTime)
130    }
131}
132
133impl ToSql<sql_types::Interval, Pg> for PgInterval {
134    fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
135        ToSql::<sql_types::BigInt, Pg>::to_sql(&self.microseconds, out)?;
136        ToSql::<sql_types::Integer, Pg>::to_sql(&self.days, out)?;
137        ToSql::<sql_types::Integer, Pg>::to_sql(&self.months, out)?;
138        Ok(IsNull::No)
139    }
140}
141
142impl FromSql<sql_types::Interval, Pg> for PgInterval {
143    fn from_sql(bytes: Option<&[u8]>) -> deserialize::Result<Self> {
144        let bytes = not_none!(bytes);
145        Ok(PgInterval {
146            microseconds: FromSql::<sql_types::BigInt, Pg>::from_sql(Some(&bytes[..8]))?,
147            days: FromSql::<sql_types::Integer, Pg>::from_sql(Some(&bytes[8..12]))?,
148            months: FromSql::<sql_types::Integer, Pg>::from_sql(Some(&bytes[12..16]))?,
149        })
150    }
151}
152
153impl Add<PgInterval> for PgInterval {
154    type Output = PgInterval;
155
156    fn add(self, other: PgInterval) -> Self::Output {
157        PgInterval {
158            microseconds: self.microseconds + other.microseconds,
159            days: self.days + other.days,
160            months: self.months + other.months,
161        }
162    }
163}