chrono
chrono copied to clipboard
Parsing "%H%M%S" has either a bug or incorrect description
The documentation states that %S represents "Second number (00–60), zero-padded to 2 digits."
Given this, I would expect the following behavior when parsing timestamps with NaiveTime::parse_from_str:
✅ Valid: "010233" with "%H%M%S" parses successfully as 01:02:33.
❌ Too Long: "0102334" with "%H%M%S" fails with an error (correct).
❌ Too Short: "01023" with "%H%M%S" should fail — but instead, it parses as 01:02:03.
This seems inconsistent. Even more confusingly: If we remove the first zero (e.g., "10233"), it parses as 10:23:03 — a completely different time.
Expected Behavior For the format "%H%M%S", any input length other than 6 digits should result in an error.
Suggested Fix Either:
Strict parsing: Enforce exact digit matching (6 digits for %H%M%S).
Document the behavior: Explicitly clarify that trailing digits may be ignored or that partial parsing is allowed.
Currently, the behavior is unintuitive and could lead to subtle bugs.
Fair enough. Want to contribute a PR?
Fair enough. Want to contribute a PR?
Not yet, unfortunately.
Hey,
I found that in some cases, it accepts 60 as a valid second as well. Here is an example:
fn main() {
let dt = chrono::NaiveDateTime::parse_from_str("2023-12-25 15:30:60", "%Y-%m-%d %H:%M:%S");
println!("{:?}", dt);
}
While it should print Err(ParseError(OutOfRange)), it prints Ok(2023-12-25T15:30:60) instead. I'm using version 0.4.41.
chrono has some support for leap seconds, which is why this accepted. I guess we could restrict it so that it only supports 60 at midnight (which I think is when all leap seconds have been scheduled?). PR welcome.