@@ -2,7 +2,7 @@ extern crate chrono;
2
2
3
3
use std:: io:: prelude:: * ;
4
4
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 } ;
6
6
7
7
use Result ;
8
8
use types:: { FromSql , ToSql , IsNull , Type } ;
@@ -13,8 +13,6 @@ const NSEC_PER_USEC: i64 = 1_000;
13
13
// Number of seconds from 1970-01-01 to 2000-01-01
14
14
const TIME_SEC_CONVERSION : i64 = 946684800 ;
15
15
16
- const POSTGRES_EPOCH_JDATE : i32 = 2451545 ;
17
-
18
16
fn base ( ) -> NaiveDateTime {
19
17
NaiveDate :: from_ymd ( 2000 , 1 , 1 ) . and_hms ( 0 , 0 , 0 )
20
18
}
@@ -72,52 +70,18 @@ impl ToSql for DateTime<UTC> {
72
70
}
73
71
74
72
impl FromSql for NaiveDate {
75
- // adapted from j2date in src/interfaces/ecpg/pgtypeslib/dt_common.c
76
73
fn from_sql < R : Read > ( _: & Type , raw : & mut R ) -> Result < NaiveDate > {
77
74
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 ) )
95
76
}
96
77
97
78
accepts ! ( Type :: Date ) ;
98
79
}
99
80
100
81
impl ToSql for NaiveDate {
101
- // adapted from date2j in src/interfaces/ecpg/pgtypeslib/dt_common.c
102
82
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 ) ) ;
121
85
Ok ( IsNull :: No )
122
86
}
123
87
@@ -127,28 +91,17 @@ impl ToSql for NaiveDate {
127
91
128
92
impl FromSql for NaiveTime {
129
93
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) )
139
96
}
140
97
141
98
accepts ! ( Type :: Time ) ;
142
99
}
143
100
144
101
impl ToSql for NaiveTime {
145
102
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 ( ) ) ) ;
152
105
Ok ( IsNull :: No )
153
106
}
154
107
0 commit comments