@@ -86,22 +86,41 @@ impl<Tz: TimeZone> Encode<'_, Postgres> for DateTime<Tz> {
86
86
87
87
impl < ' r > Decode < ' r , Postgres > for DateTime < Local > {
88
88
fn decode ( value : PgValueRef < ' r > ) -> Result < Self , BoxDynError > {
89
- let naive = <NaiveDateTime as Decode < Postgres > >:: decode ( value) ?;
90
- Ok ( Local . from_utc_datetime ( & naive ) )
89
+ let fixed = <DateTime < FixedOffset > as Decode < Postgres > >:: decode ( value) ?;
90
+ Ok ( Local . from_utc_datetime ( & fixed . naive_utc ( ) ) )
91
91
}
92
92
}
93
93
94
94
impl < ' r > Decode < ' r , Postgres > for DateTime < Utc > {
95
95
fn decode ( value : PgValueRef < ' r > ) -> Result < Self , BoxDynError > {
96
- let naive = <NaiveDateTime as Decode < Postgres > >:: decode ( value) ?;
97
- Ok ( Utc . from_utc_datetime ( & naive ) )
96
+ let fixed = <DateTime < FixedOffset > as Decode < Postgres > >:: decode ( value) ?;
97
+ Ok ( Utc . from_utc_datetime ( & fixed . naive_utc ( ) ) )
98
98
}
99
99
}
100
100
101
101
impl < ' r > Decode < ' r , Postgres > for DateTime < FixedOffset > {
102
102
fn decode ( value : PgValueRef < ' r > ) -> Result < Self , BoxDynError > {
103
- let naive = <NaiveDateTime as Decode < Postgres > >:: decode ( value) ?;
104
- Ok ( Utc . fix ( ) . from_utc_datetime ( & naive) )
103
+ Ok ( match value. format ( ) {
104
+ PgValueFormat :: Binary => {
105
+ let naive = <NaiveDateTime as Decode < Postgres > >:: decode ( value) ?;
106
+ Utc . fix ( ) . from_utc_datetime ( & naive)
107
+ }
108
+
109
+ PgValueFormat :: Text => {
110
+ let s = value. as_str ( ) ?;
111
+ DateTime :: parse_from_str (
112
+ s,
113
+ if s. contains ( '+' ) || s. contains ( '-' ) {
114
+ // Contains a time-zone specifier
115
+ // This is given for timestamptz for some reason
116
+ // Postgres already guarantees this to always be UTC
117
+ "%Y-%m-%d %H:%M:%S%.f%#z"
118
+ } else {
119
+ "%Y-%m-%d %H:%M:%S%.f"
120
+ } ,
121
+ ) ?
122
+ }
123
+ } )
105
124
}
106
125
}
107
126
0 commit comments