@@ -77,6 +77,7 @@ mod format {
7777 pub const YYYYMMDDHHMM_UTC_OFFSET : & str = "%Y%m%d%H%MUTC%z" ;
7878 pub const YYYYMMDDHHMM_ZULU_OFFSET : & str = "%Y%m%d%H%MZ%z" ;
7979 pub const YYYYMMDDHHMM_HYPHENATED_OFFSET : & str = "%Y-%m-%d %H:%M %z" ;
80+ pub const YYYYMMDDHHMMSS_HYPHENATED_OFFSET : & str = "%Y-%m-%d %H:%M:%S %#z" ;
8081 pub const YYYYMMDDHHMMS_T_SEP : & str = "%Y-%m-%dT%H:%M:%S" ;
8182 pub const UTC_OFFSET : & str = "UTC%#z" ;
8283 pub const ZULU_OFFSET : & str = "Z%#z" ;
@@ -154,9 +155,16 @@ pub fn parse_datetime_at_date<S: AsRef<str> + Clone>(
154155 // similar
155156
156157 // Formats with offsets don't require NaiveDateTime workaround
158+ //
159+ // HACK: if the string ends with a single digit preceded by a + or -
160+ // sign, then insert a 0 between the sign and the digit to make it
161+ // possible for `chrono` to parse it.
162+ let pattern = Regex :: new ( r"([\+-])(\d)$" ) . unwrap ( ) ;
163+ let s = pattern. replace ( s. as_ref ( ) , "${1}0${2}" ) ;
157164 for fmt in [
158165 format:: YYYYMMDDHHMM_OFFSET ,
159166 format:: YYYYMMDDHHMM_HYPHENATED_OFFSET ,
167+ format:: YYYYMMDDHHMMSS_HYPHENATED_OFFSET ,
160168 format:: YYYYMMDDHHMM_UTC_OFFSET ,
161169 format:: YYYYMMDDHHMM_ZULU_OFFSET ,
162170 ] {
@@ -230,16 +238,7 @@ pub fn parse_datetime_at_date<S: AsRef<str> + Clone>(
230238 // offsets, so instead we replicate parse_date behaviour by getting
231239 // the current date with local, and create a date time string at midnight,
232240 // before trying offset suffixes
233- //
234- // HACK: if the string ends with a single digit preceded by a + or -
235- // sign, then insert a 0 between the sign and the digit to make it
236- // possible for `chrono` to parse it.
237- let pattern = Regex :: new ( r"([\+-])(\d)$" ) . unwrap ( ) ;
238- let ts = format ! (
239- "{}0000{}" ,
240- date. format( "%Y%m%d" ) ,
241- pattern. replace( s. as_ref( ) , "${1}0${2}" )
242- ) ;
241+ let ts = format ! ( "{}0000{}" , date. format( "%Y%m%d" ) , s) ;
243242 for fmt in [
244243 format:: UTC_OFFSET ,
245244 format:: ZULU_OFFSET ,
@@ -370,7 +369,7 @@ mod tests {
370369
371370 #[ cfg( test) ]
372371 mod offsets {
373- use chrono:: Local ;
372+ use chrono:: { Local , NaiveDate } ;
374373
375374 use crate :: parse_datetime;
376375 use crate :: ParseDateTimeError ;
@@ -413,6 +412,17 @@ mod tests {
413412 Err ( ParseDateTimeError :: InvalidInput )
414413 ) ;
415414 }
415+
416+ #[ test]
417+ fn test_datetime_with_offset ( ) {
418+ let actual = parse_datetime ( "1997-01-19 08:17:48 +0" ) . unwrap ( ) ;
419+ let expected = NaiveDate :: from_ymd_opt ( 1997 , 1 , 19 )
420+ . unwrap ( )
421+ . and_hms_opt ( 8 , 17 , 48 )
422+ . unwrap ( )
423+ . and_utc ( ) ;
424+ assert_eq ! ( actual, expected) ;
425+ }
416426 }
417427
418428 #[ cfg( test) ]
0 commit comments