diff --git a/src/datetime/tests.rs b/src/datetime/tests.rs index c17e6320fd..cab6059b0b 100644 --- a/src/datetime/tests.rs +++ b/src/datetime/tests.rs @@ -1042,17 +1042,18 @@ fn test_datetime_parse_from_str() { // %:z // assert_eq!(parse("Aug 09 2013 23:54:35 -09:00", "%b %d %Y %H:%M:%S %:z"), Ok(dt)); - assert_eq!(parse("Aug 09 2013 23:54:35 -0900", "%b %d %Y %H:%M:%S %:z"), Ok(dt)); + assert!(parse("Aug 09 2013 23:54:35 -0900", "%b %d %Y %H:%M:%S %:z").is_err()); assert!(parse("Aug 09 2013 23:54:35 -09 00", "%b %d %Y %H:%M:%S %:z").is_err()); assert!(parse("Aug 09 2013 23:54:35 -09 : 00", "%b %d %Y %H:%M:%S %:z").is_err()); - assert!(parse("Aug 09 2013 23:54:35 -09 : 00:", "%b %d %Y %H:%M:%S %:z:").is_err()); + assert!(parse("Aug 09 2013 23:54:35 -09:0", "%b %d %Y %H:%M:%S %:z:").is_err()); + assert!(parse("Aug 09 2013 23:54:35 -09:", "%b %d %Y %H:%M:%S %:z:").is_err()); // wrong timezone data assert!(parse("Aug 09 2013 23:54:35 -09", "%b %d %Y %H:%M:%S %:z").is_err()); + assert!(parse("Aug 09 2013 23:54:35 -090000", "%b %d %Y %H:%M:%S %:z").is_err()); + assert!(parse("Aug 09 2013 23:54:35 -09:00:00", "%b %d %Y %H:%M:%S %:z").is_err()); + // timezone data has too many colons assert!(parse("Aug 09 2013 23:54:35 -09::00", "%b %d %Y %H:%M:%S %:z").is_err()); - // timezone data hs too many colons assert!(parse("Aug 09 2013 23:54:35 -09:00:", "%b %d %Y %H:%M:%S %:z").is_err()); - // timezone data hs too many colons - assert!(parse("Aug 09 2013 23:54:35 -09:00::", "%b %d %Y %H:%M:%S %:z").is_err()); assert_eq!(parse("Aug 09 2013 23:54:35 -09:00::", "%b %d %Y %H:%M:%S %:z::"), Ok(dt)); // diff --git a/src/format/mod.rs b/src/format/mod.rs index 912a9344cd..a98109d897 100644 --- a/src/format/mod.rs +++ b/src/format/mod.rs @@ -210,7 +210,6 @@ pub enum Fixed { TimezoneName, /// Offset from the local time to UTC (`+09:00` or `-0400` or `+00:00`). /// - /// In the parser, the colon may be omitted, /// The offset is limited from `-24:00` to `+24:00`, /// which is the same as [`FixedOffset`](../offset/struct.FixedOffset.html)'s range. TimezoneOffsetColon, diff --git a/src/format/parse.rs b/src/format/parse.rs index 58aa102d6f..a7e39bdf50 100644 --- a/src/format/parse.rs +++ b/src/format/parse.rs @@ -489,15 +489,24 @@ where try_consume!(scan::timezone_name_skip(s)); } - &TimezoneOffsetColon - | &TimezoneOffset - | &TimezoneOffsetColonZ - | &TimezoneOffsetZ => { + &TimezoneOffset | &TimezoneOffsetZ => { s = scan::trim1(s); let offset_format = UtcOffsetFormat { precision: OffsetPrecision::Minutes, colons: Colon::Maybe, - allow_zulu: spec == &TimezoneOffsetColonZ || spec == &TimezoneOffsetZ, + allow_zulu: spec == &TimezoneOffsetZ, + padding: Pad::Zero, + }; + let offset = try_consume!(scan::utc_offset(s, offset_format)); + parsed.set_offset(i64::from(offset)).map_err(|e| (s, e))?; + } + + &TimezoneOffsetColon | &TimezoneOffsetColonZ => { + s = scan::trim1(s); + let offset_format = UtcOffsetFormat { + precision: OffsetPrecision::Minutes, + colons: Colon::Colon, + allow_zulu: spec == &TimezoneOffsetColonZ, padding: Pad::Zero, }; let offset = try_consume!(scan::utc_offset(s, offset_format)); @@ -1101,13 +1110,11 @@ fn test_parse() { check!("12345678", [fix!(TimezoneOffsetColon)]; INVALID); check!("+1", [fix!(TimezoneOffsetColon)]; TOO_SHORT); check!("+12", [fix!(TimezoneOffsetColon)]; TOO_SHORT); - check!("+123", [fix!(TimezoneOffsetColon)]; TOO_SHORT); - check!("+1234", [fix!(TimezoneOffsetColon)]; offset: 45_240); - check!("-1234", [fix!(TimezoneOffsetColon)]; offset: -45_240); - check!("+12345", [fix!(TimezoneOffsetColon)]; TOO_LONG); - check!("+123456", [fix!(TimezoneOffsetColon)]; TOO_LONG); - check!("+1234567", [fix!(TimezoneOffsetColon)]; TOO_LONG); - check!("+12345678", [fix!(TimezoneOffsetColon)]; TOO_LONG); + check!("+123", [fix!(TimezoneOffsetColon)]; INVALID); + check!("+1234", [fix!(TimezoneOffsetColon)]; INVALID); + check!("-1234", [fix!(TimezoneOffsetColon)]; INVALID); + check!("+12345", [fix!(TimezoneOffsetColon)]; INVALID); + check!("+123456", [fix!(TimezoneOffsetColon)]; INVALID); check!("1:", [fix!(TimezoneOffsetColon)]; INVALID); check!("12:", [fix!(TimezoneOffsetColon)]; INVALID); check!("12:3", [fix!(TimezoneOffsetColon)]; INVALID); @@ -1124,10 +1131,8 @@ fn test_parse() { check!("+12:34:5", [fix!(TimezoneOffsetColon)]; TOO_LONG); check!("+12:34:56", [fix!(TimezoneOffsetColon)]; TOO_LONG); check!("+12:34:56:", [fix!(TimezoneOffsetColon)]; TOO_LONG); - check!("+12:34:56:7", [fix!(TimezoneOffsetColon)]; TOO_LONG); - check!("+12:34:56:78", [fix!(TimezoneOffsetColon)]; TOO_LONG); check!("+12:3456", [fix!(TimezoneOffsetColon)]; TOO_LONG); - check!("+1234:56", [fix!(TimezoneOffsetColon)]; TOO_LONG); + check!("+1234:56", [fix!(TimezoneOffsetColon)]; INVALID); check!("+12 34", [fix!(TimezoneOffsetColon)]; INVALID); check!("+12: 34", [fix!(TimezoneOffsetColon)]; INVALID); check!("+12 :34", [fix!(TimezoneOffsetColon)]; INVALID); @@ -1151,7 +1156,7 @@ fn test_parse() { check!("", [fix!(TimezoneOffsetColon)]; TOO_SHORT); check!("+", [fix!(TimezoneOffsetColon)]; TOO_SHORT); check!(":", [fix!(TimezoneOffsetColon)]; INVALID); - check!("+12345", [fix!(TimezoneOffsetColon), num!(Day)]; offset: 45_240, day: 5); + check!("+12345", [fix!(TimezoneOffsetColon), num!(Day)]; INVALID); check!("+12:345", [fix!(TimezoneOffsetColon), num!(Day)]; offset: 45_240, day: 5); check!("+12:34:", [fix!(TimezoneOffsetColon), lit!(":")]; offset: 45_240); check!("Z", [fix!(TimezoneOffsetColon)]; INVALID);