@@ -2,7 +2,7 @@ extern crate chrono;
22
33use std:: io:: prelude:: * ;
44use 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
77use Result ;
88use 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
1414const TIME_SEC_CONVERSION : i64 = 946684800 ;
1515
16- const POSTGRES_EPOCH_JDATE : i32 = 2451545 ;
17-
1816fn 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
7472impl 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
10081impl 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
12892impl 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
144101impl 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