@@ -138,7 +138,7 @@ where
138
138
139
139
// Parse an item
140
140
pub fn parse_one ( input : & mut & str ) -> PResult < Item > {
141
- // eprintln!("--- > parse_one {input}");
141
+ eprintln ! ( "--- > parse_one {input}" ) ;
142
142
let result = alt ( (
143
143
combined:: parse. map ( Item :: DateTime ) ,
144
144
date:: parse. map ( Item :: Date ) ,
@@ -151,7 +151,7 @@ pub fn parse_one(input: &mut &str) -> PResult<Item> {
151
151
) )
152
152
. parse_next ( input) ?;
153
153
154
- // eprintln!("--- < parse_one {input} {result:?}");
154
+ eprintln ! ( "--- < parse_one {input} {result:?}" ) ;
155
155
Ok ( result)
156
156
}
157
157
@@ -169,7 +169,6 @@ fn with_timezone_restore(
169
169
) -> Option < DateTime < FixedOffset > > {
170
170
let offset: FixedOffset = chrono:: FixedOffset :: from ( offset) ;
171
171
let copy = at;
172
- //eprintln!("with_timezone {at} {offset}");
173
172
let x = at
174
173
. with_timezone ( & offset)
175
174
. with_day ( copy. day ( ) ) ?
@@ -181,14 +180,11 @@ fn with_timezone_restore(
181
180
Some ( x)
182
181
}
183
182
184
- pub ( crate ) fn at_date (
185
- date : Vec < Item > ,
186
- mut d : DateTime < FixedOffset > ,
187
- ) -> Result < DateTime < FixedOffset > , ParseDateTimeError > {
188
- d = d. with_hour ( 0 ) . unwrap_or ( d) ;
189
- d = d. with_minute ( 0 ) . unwrap_or ( d) ;
190
- d = d. with_second ( 0 ) . unwrap_or ( d) ;
191
- d = d. with_nanosecond ( 0 ) . unwrap_or ( d) ;
183
+ fn at_date_inner ( date : Vec < Item > , mut d : DateTime < FixedOffset > ) -> Option < DateTime < FixedOffset > > {
184
+ d = d. with_hour ( 0 ) . unwrap ( ) ;
185
+ d = d. with_minute ( 0 ) . unwrap ( ) ;
186
+ d = d. with_second ( 0 ) . unwrap ( ) ;
187
+ d = d. with_nanosecond ( 0 ) . unwrap ( ) ;
192
188
193
189
for item in date {
194
190
match item {
@@ -199,13 +195,12 @@ pub(crate) fn at_date(
199
195
. with_timezone ( & d. timezone ( ) )
200
196
}
201
197
Item :: Date ( date:: Date { day, month, year } ) => {
202
- d = d. with_day ( day) . unwrap_or ( d) ;
203
- d = d. with_month ( month) . unwrap_or ( d) ;
204
- d = year
205
- // converts i32 to u32 safely
206
- . and_then ( |year : u32 | <u32 as TryInto < i32 > >:: try_into ( year) . ok ( ) )
207
- . and_then ( |year| d. with_year ( year) )
208
- . unwrap_or ( d) ;
198
+ d = d. with_day ( day) ?;
199
+ d = d. with_month ( month) ?;
200
+ if let Some ( year) = year {
201
+ let y = year as i32 ;
202
+ d = d. with_year ( y) ?
203
+ }
209
204
}
210
205
Item :: DateTime ( combined:: DateTime {
211
206
date : date:: Date { day, month, year } ,
@@ -222,16 +217,14 @@ pub(crate) fn at_date(
222
217
let offset: FixedOffset = chrono:: FixedOffset :: from ( offset) ;
223
218
d = d. with_timezone ( & offset) ;
224
219
}
225
- d = d. with_day ( day) . unwrap_or ( d) ;
226
- d = d. with_month ( month) . unwrap_or ( d) ;
227
- d = year
228
- // converts i32 to u32 safely
229
- . and_then ( |year : u32 | <u32 as TryInto < i32 > >:: try_into ( year) . ok ( ) )
230
- . and_then ( |year| d. with_year ( year) )
231
- . unwrap_or ( d) ;
232
- d = d. with_hour ( hour) . unwrap_or ( d) ;
233
- d = d. with_minute ( minute) . unwrap_or ( d) ;
234
- d = d. with_second ( second as u32 ) . unwrap_or ( d) ;
220
+ d = d. with_day ( day) ?;
221
+ d = d. with_month ( month) ?;
222
+ d = d. with_hour ( hour) ?;
223
+ d = d. with_minute ( minute) ?;
224
+ d = d. with_second ( second as u32 ) ?;
225
+ if let Some ( year) = year {
226
+ d = d. with_year ( year as i32 ) ?
227
+ }
235
228
}
236
229
Item :: Year ( year) => d = d. with_year ( year as i32 ) . unwrap_or ( d) ,
237
230
Item :: Time ( time:: Time {
@@ -242,11 +235,11 @@ pub(crate) fn at_date(
242
235
} ) => {
243
236
if let Some ( offset) = offset {
244
237
// timezone overflowed
245
- d = with_timezone_restore ( offset, d) . ok_or ( ParseDateTimeError :: InvalidInput ) ?;
238
+ d = with_timezone_restore ( offset, d) ?;
246
239
}
247
- d = d. with_hour ( hour) . unwrap_or ( d ) ;
248
- d = d. with_minute ( minute) . unwrap_or ( d ) ;
249
- d = d. with_second ( second as u32 ) . unwrap_or ( d ) ;
240
+ d = d. with_hour ( hour) ? ;
241
+ d = d. with_minute ( minute) ? ;
242
+ d = d. with_second ( second as u32 ) ? ;
250
243
}
251
244
Item :: Weekday ( weekday:: Weekday {
252
245
offset : _, // TODO: use the offset
@@ -269,9 +262,14 @@ pub(crate) fn at_date(
269
262
270
263
d = beginning_of_day
271
264
}
272
- Item :: Relative ( relative:: Relative :: Years ( x) ) => d = d. with_year ( x) . unwrap_or ( d) ,
265
+ Item :: Relative ( relative:: Relative :: Years ( x) ) => {
266
+ d = d. with_year ( d. year ( ) + x) ?;
267
+ }
273
268
Item :: Relative ( relative:: Relative :: Months ( x) ) => {
274
- d = d. with_month ( x as u32 ) . unwrap_or ( d)
269
+ d += d
270
+ . date_naive ( )
271
+ . checked_add_months ( chrono:: Months :: new ( x as u32 ) ) ?
272
+ . signed_duration_since ( d. date_naive ( ) ) ;
275
273
}
276
274
Item :: Relative ( relative:: Relative :: Days ( x) ) => d += chrono:: Duration :: days ( x. into ( ) ) ,
277
275
Item :: Relative ( relative:: Relative :: Hours ( x) ) => d += chrono:: Duration :: hours ( x. into ( ) ) ,
@@ -283,12 +281,19 @@ pub(crate) fn at_date(
283
281
d += chrono:: Duration :: seconds ( x as i64 ) ;
284
282
}
285
283
Item :: TimeZone ( offset) => {
286
- d = with_timezone_restore ( offset, d) . ok_or ( ParseDateTimeError :: InvalidInput ) ?;
284
+ d = with_timezone_restore ( offset, d) ?;
287
285
}
288
286
}
289
287
}
290
288
291
- Ok ( d)
289
+ Some ( d)
290
+ }
291
+
292
+ pub ( crate ) fn at_date (
293
+ date : Vec < Item > ,
294
+ d : DateTime < FixedOffset > ,
295
+ ) -> Result < DateTime < FixedOffset > , ParseDateTimeError > {
296
+ at_date_inner ( date, d) . ok_or ( ParseDateTimeError :: InvalidInput )
292
297
}
293
298
294
299
pub ( crate ) fn at_local ( date : Vec < Item > ) -> Result < DateTime < FixedOffset > , ParseDateTimeError > {
0 commit comments