From 00437e5b30418a5e3d7ecf0974648e6b5130c2d8 Mon Sep 17 00:00:00 2001 From: Paul Dicker Date: Sat, 10 Jun 2023 16:53:37 +0200 Subject: [PATCH] Make parsing `%:z` conform to documentation --- src/format/mod.rs | 1 - src/format/parse.rs | 38 +++++++++++++++++++++++--------------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/format/mod.rs b/src/format/mod.rs index ed65d9228f..ba0caefd02 100644 --- a/src/format/mod.rs +++ b/src/format/mod.rs @@ -215,7 +215,6 @@ pub enum Fixed { TimezoneName, /// Offset from the local time to UTC (`+09:00` or `-04:00` or `+00:00`). /// - /// In the parser, the colon can be omitted and/or surrounded with any amount of whitespace. /// 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 bc67521047..4e66a46527 100644 --- a/src/format/parse.rs +++ b/src/format/parse.rs @@ -525,14 +525,22 @@ where try_consume!(Ok((s.trim_start_matches(|c: char| !c.is_whitespace()), ()))); } - &TimezoneOffsetColon - | &TimezoneOffset - | &TimezoneOffsetColonZ - | &TimezoneOffsetZ => { + &TimezoneOffset | &TimezoneOffsetZ => { let offset_format = OffsetFormat { precision: OffsetPrecision::Minutes, colons: Colons::Maybe, - allow_zulu: spec == &TimezoneOffsetColonZ || spec == &TimezoneOffsetZ, + allow_zulu: spec == &TimezoneOffsetZ, + padding: Pad::Zero, + }; + let offset = try_consume!(scan::utc_offset(s.trim_start(), offset_format)); + parsed.set_offset(i64::from(offset)).map_err(|e| (s, e))?; + } + + &TimezoneOffsetColon | &TimezoneOffsetColonZ => { + let offset_format = OffsetFormat { + precision: OffsetPrecision::Minutes, + colons: Colons::Colon, + allow_zulu: spec == &TimezoneOffsetColonZ, padding: Pad::Zero, }; let offset = try_consume!(scan::utc_offset(s.trim_start(), offset_format)); @@ -999,14 +1007,14 @@ mod tests { check!("12345678", [fixed(Fixed::TimezoneOffsetColon)]; INVALID); check!("+1", [fixed(Fixed::TimezoneOffsetColon)]; TOO_SHORT); check!("+12", [fixed(Fixed::TimezoneOffsetColon)]; TOO_SHORT); - check!("+123", [fixed(Fixed::TimezoneOffsetColon)]; TOO_SHORT); - check!("+1234", [fixed(Fixed::TimezoneOffsetColon)]; offset: 45_240); - check!("-1234", [fixed(Fixed::TimezoneOffsetColon)]; offset: -45_240); - check!("−1234", [fixed(Fixed::TimezoneOffsetColon)]; offset: -45_240); // MINUS SIGN (U+2212) - check!("+12345", [fixed(Fixed::TimezoneOffsetColon)]; TOO_LONG); - check!("+123456", [fixed(Fixed::TimezoneOffsetColon)]; TOO_LONG); - check!("+1234567", [fixed(Fixed::TimezoneOffsetColon)]; TOO_LONG); - check!("+12345678", [fixed(Fixed::TimezoneOffsetColon)]; TOO_LONG); + check!("+123", [fixed(Fixed::TimezoneOffsetColon)]; INVALID); + check!("+1234", [fixed(Fixed::TimezoneOffsetColon)]; INVALID); + check!("-1234", [fixed(Fixed::TimezoneOffsetColon)]; INVALID); + check!("−1234", [fixed(Fixed::TimezoneOffsetColon)]; INVALID); // MINUS SIGN (U+2212) + check!("+12345", [fixed(Fixed::TimezoneOffsetColon)]; INVALID); + check!("+123456", [fixed(Fixed::TimezoneOffsetColon)]; INVALID); + check!("+1234567", [fixed(Fixed::TimezoneOffsetColon)]; INVALID); + check!("+12345678", [fixed(Fixed::TimezoneOffsetColon)]; INVALID); check!("1:", [fixed(Fixed::TimezoneOffsetColon)]; INVALID); check!("12:", [fixed(Fixed::TimezoneOffsetColon)]; INVALID); check!("12:3", [fixed(Fixed::TimezoneOffsetColon)]; INVALID); @@ -1027,7 +1035,7 @@ mod tests { check!("+12:34:56:7", [fixed(Fixed::TimezoneOffsetColon)]; TOO_LONG); check!("+12:34:56:78", [fixed(Fixed::TimezoneOffsetColon)]; TOO_LONG); check!("+12:3456", [fixed(Fixed::TimezoneOffsetColon)]; TOO_LONG); - check!("+1234:56", [fixed(Fixed::TimezoneOffsetColon)]; TOO_LONG); + check!("+1234:56", [fixed(Fixed::TimezoneOffsetColon)]; INVALID); check!("−12:34", [fixed(Fixed::TimezoneOffsetColon)]; offset: -45_240); // MINUS SIGN (U+2212) check!("−12 : 34", [fixed(Fixed::TimezoneOffsetColon)]; INVALID); // MINUS SIGN (U+2212) check!("+12 :34", [fixed(Fixed::TimezoneOffsetColon)]; INVALID); @@ -1056,7 +1064,7 @@ mod tests { check!("", [fixed(Fixed::TimezoneOffsetColon)]; TOO_SHORT); check!("+", [fixed(Fixed::TimezoneOffsetColon)]; TOO_SHORT); check!(":", [fixed(Fixed::TimezoneOffsetColon)]; INVALID); - check!("+12345", [fixed(Fixed::TimezoneOffsetColon), num(Day)]; offset: 45_240, day: 5); + check!("+12345", [fixed(Fixed::TimezoneOffsetColon), num(Day)]; INVALID); check!("+12:345", [fixed(Fixed::TimezoneOffsetColon), num(Day)]; offset: 45_240, day: 5); check!("+12:34:", [fixed(Fixed::TimezoneOffsetColon), Literal(":")]; offset: 45_240); check!("Z", [fixed(Fixed::TimezoneOffsetColon)]; INVALID);