rbdc_pg/types/
timestamp.rs

1use crate::arguments::PgArgumentBuffer;
2use crate::types::decode::Decode;
3use crate::types::encode::{Encode, IsNull};
4use crate::value::{PgValue, PgValueFormat};
5use rbdc::timestamp::Timestamp;
6use rbdc::Error;
7use std::str::FromStr;
8
9impl Encode for Timestamp {
10    fn encode(self, buf: &mut PgArgumentBuffer) -> Result<IsNull, Error> {
11        let epoch = fastdate::DateTime::from(fastdate::Date {
12            day: 1,
13            mon: 1,
14            year: 2000,
15        });
16        let dt = fastdate::DateTime::from_timestamp_millis(self.0);
17        let micros;
18        if dt >= epoch {
19            micros = (dt - epoch).as_micros() as i64;
20        } else {
21            micros = (epoch - dt).as_micros() as i64 * -1;
22        }
23        micros.encode(buf)
24    }
25}
26
27impl Decode for Timestamp {
28    fn decode(value: PgValue) -> Result<Self, Error> {
29        Ok(match value.format() {
30            PgValueFormat::Binary => {
31                // TIMESTAMP is encoded as the microseconds since the epoch
32                let epoch = fastdate::DateTime::from(fastdate::Date {
33                    day: 1,
34                    mon: 1,
35                    year: 2000,
36                });
37                let us: i64 = Decode::decode(value)?;
38                let v = {
39                    if us < 0 {
40                        epoch - std::time::Duration::from_micros(-us as u64)
41                    } else {
42                        epoch + std::time::Duration::from_micros(us as u64)
43                    }
44                };
45                Timestamp(v.unix_timestamp_millis())
46            }
47            PgValueFormat::Text => {
48                //2023-11-08 16:38:06.157
49                let s = value.as_str()?;
50                Timestamp(
51                    fastdate::DateTime::from_str(&format!("{}Z", s))
52                        .map_err(|e| Error::from(e.to_string()))?
53                        .unix_timestamp_millis(),
54                )
55            }
56        })
57    }
58}