From 3068f31946b7ae82785cbbf0ae32db138643fff4 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 | 42 +++++++++++++++++++++++------------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/format/mod.rs b/src/format/mod.rs index a741453396..d542301d52 100644 --- a/src/format/mod.rs +++ b/src/format/mod.rs @@ -208,7 +208,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 d81b9f75ae..1a673688d6 100644 --- a/src/format/parse.rs +++ b/src/format/parse.rs @@ -521,14 +521,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)); @@ -1163,14 +1171,14 @@ mod tests { check("12345678", &[fixed(TimezoneOffsetColon)], Err(INVALID)); check("+1", &[fixed(TimezoneOffsetColon)], Err(TOO_SHORT)); check("+12", &[fixed(TimezoneOffsetColon)], Err(TOO_SHORT)); - check("+123", &[fixed(TimezoneOffsetColon)], Err(TOO_SHORT)); - check("+1234", &[fixed(TimezoneOffsetColon)], parsed!(offset: 45_240)); - check("-1234", &[fixed(TimezoneOffsetColon)], parsed!(offset: -45_240)); - check("−1234", &[fixed(TimezoneOffsetColon)], parsed!(offset: -45_240)); // MINUS SIGN (U+2212) - check("+12345", &[fixed(TimezoneOffsetColon)], Err(TOO_LONG)); - check("+123456", &[fixed(TimezoneOffsetColon)], Err(TOO_LONG)); - check("+1234567", &[fixed(TimezoneOffsetColon)], Err(TOO_LONG)); - check("+12345678", &[fixed(TimezoneOffsetColon)], Err(TOO_LONG)); + check("+123", &[fixed(TimezoneOffsetColon)], Err(INVALID)); + check("+1234", &[fixed(TimezoneOffsetColon)], Err(INVALID)); + check("-1234", &[fixed(TimezoneOffsetColon)], Err(INVALID)); + check("−1234", &[fixed(TimezoneOffsetColon)], Err(INVALID)); // MINUS SIGN (U+2212) + check("+12345", &[fixed(TimezoneOffsetColon)], Err(INVALID)); + check("+123456", &[fixed(TimezoneOffsetColon)], Err(INVALID)); + check("+1234567", &[fixed(TimezoneOffsetColon)], Err(INVALID)); + check("+12345678", &[fixed(TimezoneOffsetColon)], Err(INVALID)); check("1:", &[fixed(TimezoneOffsetColon)], Err(INVALID)); check("12:", &[fixed(TimezoneOffsetColon)], Err(INVALID)); check("12:3", &[fixed(TimezoneOffsetColon)], Err(INVALID)); @@ -1191,7 +1199,7 @@ mod tests { check("+12:34:56:7", &[fixed(TimezoneOffsetColon)], Err(TOO_LONG)); check("+12:34:56:78", &[fixed(TimezoneOffsetColon)], Err(TOO_LONG)); check("+12:3456", &[fixed(TimezoneOffsetColon)], Err(TOO_LONG)); - check("+1234:56", &[fixed(TimezoneOffsetColon)], Err(TOO_LONG)); + check("+1234:56", &[fixed(TimezoneOffsetColon)], Err(INVALID)); check("−12:34", &[fixed(TimezoneOffsetColon)], parsed!(offset: -45_240)); // MINUS SIGN (U+2212) check("−12 : 34", &[fixed(TimezoneOffsetColon)], Err(INVALID)); // MINUS SIGN (U+2212) check("+12 :34", &[fixed(TimezoneOffsetColon)], Err(INVALID)); @@ -1220,11 +1228,7 @@ mod tests { check("", &[fixed(TimezoneOffsetColon)], Err(TOO_SHORT)); check("+", &[fixed(TimezoneOffsetColon)], Err(TOO_SHORT)); check(":", &[fixed(TimezoneOffsetColon)], Err(INVALID)); - check( - "+12345", - &[fixed(TimezoneOffsetColon), num(Numeric::Day)], - parsed!(offset: 45_240, day: 5), - ); + check("+12345", &[fixed(TimezoneOffsetColon), num(Numeric::Day)], Err(INVALID)); check( "+12:345", &[fixed(TimezoneOffsetColon), num(Numeric::Day)],