chrono icon indicating copy to clipboard operation
chrono copied to clipboard

`%:::z` format incorrectly expects minutes when parsing

Open max-kamps opened this issue 2 years ago • 1 comments
trafficstars

If I understand the docs correctly, %:::z corresponds to the timezone offset, without minutes. When formatting, this works correctly. However, when parsing it does expect minutes, and rejects inputs that don't include them.

Tested on 0.4.26 and main, both affected

Playground-compatible sample:

use chrono::{FixedOffset, NaiveDate, TimeZone, Timelike, Utc, DateTime};

fn main() {
    let dt = FixedOffset::west_opt(5 * 3600)
        .unwrap()
        .from_local_datetime(
            &NaiveDate::from_ymd_opt(2001, 7, 8)
                .unwrap()
                .and_hms_nano_opt(0, 34, 59, 1_026_490_708)
                .unwrap(),
        )
        .unwrap();

    const FORMAT: &str = "%Y-%m-%d %H:%M:%S%:::z";
    
    // Formatting works as expected. This produces "-05" for the timezone
    println!("{}", dt.format(FORMAT));
    // Output: 2001-07-08 00:34:60-05
    
    // However, parsing doesn't! This will result in a ParseError(TooShort) / "premature end of input error"
    println!("{:?}", DateTime::parse_from_str("2001-07-08 00:34:60-05", FORMAT));
    // Output: Err(ParseError(TooShort))

    // Adding minutes to the timezone fixes it. But %:::z should not expect minutes
    println!("{:?}", DateTime::parse_from_str("2001-07-08 00:34:60-0500", FORMAT));
    // Output: Ok(2001-07-08T00:34:60-05:00)
}

max-kamps avatar Aug 27 '23 00:08 max-kamps

Should get fixed with https://github.com/chronotope/chrono/pull/1083.

pitdicker avatar Aug 27 '23 06:08 pitdicker