Skip to content

Commit 1f251c4

Browse files
committed
Simplify NaiveDate and NaiveTime logic
1 parent c25f3fa commit 1f251c4

File tree

1 file changed

+8
-55
lines changed

1 file changed

+8
-55
lines changed

src/types/chrono.rs

Lines changed: 8 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ extern crate chrono;
22

33
use std::io::prelude::*;
44
use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian};
5-
use self::chrono::{Timelike, Datelike, NaiveDate, NaiveTime, NaiveDateTime, DateTime, UTC};
5+
use self::chrono::{Duration, NaiveDate, NaiveTime, NaiveDateTime, DateTime, UTC};
66

77
use Result;
88
use types::{FromSql, ToSql, IsNull, Type};
@@ -13,8 +13,6 @@ const NSEC_PER_USEC: i64 = 1_000;
1313
// Number of seconds from 1970-01-01 to 2000-01-01
1414
const TIME_SEC_CONVERSION: i64 = 946684800;
1515

16-
const POSTGRES_EPOCH_JDATE: i32 = 2451545;
17-
1816
fn base() -> NaiveDateTime {
1917
NaiveDate::from_ymd(2000, 1, 1).and_hms(0, 0, 0)
2018
}
@@ -72,52 +70,18 @@ impl ToSql for DateTime<UTC> {
7270
}
7371

7472
impl FromSql for NaiveDate {
75-
// adapted from j2date in src/interfaces/ecpg/pgtypeslib/dt_common.c
7673
fn from_sql<R: Read>(_: &Type, raw: &mut R) -> Result<NaiveDate> {
7774
let jd = try!(raw.read_i32::<BigEndian>());
78-
79-
let mut julian: u32 = (jd + POSTGRES_EPOCH_JDATE) as u32;
80-
julian += 32044;
81-
let mut quad: u32 = julian / 146097;
82-
let extra: u32 = (julian - quad * 146097) * 4 + 3;
83-
julian += 60 + quad * 3 + extra / 146097;
84-
quad = julian / 1461;
85-
julian -= quad * 1461;
86-
let mut y: i32 = (julian * 4 / 1461) as i32;
87-
julian = if y != 0 { (julian + 305) % 365 } else { (julian + 306) % 366 } + 123;
88-
y += (quad * 4) as i32;
89-
let year = y - 4800;
90-
quad = julian * 2141 / 65536;
91-
let day = julian - 7834 * quad / 256;
92-
let month = (quad + 10) % 12 + 1;
93-
94-
Ok(NaiveDate::from_ymd(year, month as u32, day as u32))
75+
Ok(base().date() + Duration::days(jd as i64))
9576
}
9677

9778
accepts!(Type::Date);
9879
}
9980

10081
impl ToSql for NaiveDate {
101-
// adapted from date2j in src/interfaces/ecpg/pgtypeslib/dt_common.c
10282
fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W) -> Result<IsNull> {
103-
let mut y = self.year();
104-
let mut m = self.month() as i32;
105-
let d = self.day() as i32;
106-
107-
if m > 2 {
108-
m += 1;
109-
y += 4800;
110-
} else {
111-
m += 13;
112-
y += 4799;
113-
}
114-
115-
let century = y / 100;
116-
let mut julian = y * 365 - 32167;
117-
julian += y / 4 - century + century / 4;
118-
julian += 7834 * m / 256 + d;
119-
120-
try!(w.write_i32::<BigEndian>(julian - POSTGRES_EPOCH_JDATE));
83+
let jd = *self - base().date();
84+
try!(w.write_i32::<BigEndian>(jd.num_days() as i32));
12185
Ok(IsNull::No)
12286
}
12387

@@ -127,28 +91,17 @@ impl ToSql for NaiveDate {
12791

12892
impl FromSql for NaiveTime {
12993
fn from_sql<R: Read>(_: &Type, raw: &mut R) -> Result<NaiveTime> {
130-
let mut usec = try!(raw.read_i64::<BigEndian>());
131-
let mut sec = usec / USEC_PER_SEC;
132-
usec -= sec * USEC_PER_SEC;
133-
let mut min = sec / 60;
134-
sec -= min * 60;
135-
let hr = min / 60;
136-
min -= hr * 60;
137-
138-
Ok(NaiveTime::from_hms_micro(hr as u32, min as u32, sec as u32, usec as u32))
94+
let usec = try!(raw.read_i64::<BigEndian>());
95+
Ok(NaiveTime::from_hms(0, 0, 0) + Duration::microseconds(usec))
13996
}
14097

14198
accepts!(Type::Time);
14299
}
143100

144101
impl ToSql for NaiveTime {
145102
fn to_sql<W: Write+?Sized>(&self, _: &Type, mut w: &mut W) -> Result<IsNull> {
146-
let hr = self.hour() as i64;
147-
let min = hr * 60 + self.minute() as i64;
148-
let sec = min * 60 + self.second() as i64;
149-
let usec = sec * USEC_PER_SEC + self.nanosecond() as i64 / NSEC_PER_USEC;
150-
151-
try!(w.write_i64::<BigEndian>(usec));
103+
let delta = *self - NaiveTime::from_hms(0, 0, 0);
104+
try!(w.write_i64::<BigEndian>(delta.num_microseconds().unwrap()));
152105
Ok(IsNull::No)
153106
}
154107

0 commit comments

Comments
 (0)