time-rs / time

The most used Rust library for date and time handling.
https://time-rs.github.io
Apache License 2.0
1.13k stars 281 forks source link

Optional leading zeros and parsing #666

Closed softdevca closed 9 months ago

softdevca commented 9 months ago

The default Display implementation for Time and OffsetDateTime cannot reliably be parsed by a format description because the hour is not always two digits.

 let format = format_description!("[hour]:[minute]:[second]");
 let time = Time::from_hms(1, 2, 3).expect("time");
 let parsed = Time::parse(&time.to_string(), &format).expect("parsed"); // Fails

The root issues seems to be that in parsing/component.rs the following function requires the hour field be two digits, where the display implementation of Time does not pad to two digit hours:

/// Parse the "hour" component of a `Time`.
pub(crate) fn parse_hour(input: &[u8], modifiers: modifier::Hour) -> Option<ParsedItem<'_, u8>> {
    exactly_n_digits_padded::<2, _>(modifiers.padding)(input)
}

I suggest that single digit hours be permitted. A more general solution would be to enable format descriptions to indicate which fields may be single digits.

softdevca commented 9 months ago

For a little more background: A test was failing occasionally because code that was parsing the result of OffsetDateTime::now_utc().to_string() would start to fail around midnight UTC.

jhpratt commented 9 months ago

Single digit hours can be parsed. You need to explicitly ask for that, as the default is to have them padded with zeroes. This is indicated in the documentation. More generally, you should use a format description for clarity rather than relying on the Display implementation if you are expecting a specific format. The output of Display is permitted to change without warning.

softdevca commented 9 months ago

Submitted PR to the book to clarify padding.