rbdc_pg/types/
timestamp.rs1use 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 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 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}