Usage of FormatItem::First to attempt parsing with multiple descriptions #476
-
It was suggested to me that there may be a better way to match time formats than in a loop like: let formats = &[
format_description!("[hour]:[minute]:[second]"),
format_description!("[hour]:[minute]:[second].[subsecond]"),
format_description!("[hour]:[minute]"),
];
for format in formats {
if let Ok(dt) = Time::parse(value, &format) {
return Ok(dt);
}
} The better way being let formats = FormatItem::First(&[
FormatItem::Compound(format_description!("[hour]:[minute]:[second]")),
FormatItem::Compound(format_description!("[hour]:[minute]:[second].[subsecond]")),
FormatItem::Compound(format_description!("[hour]:[minute]")),
]);
Time::parse("21:46:32", &formats).expect("Parse failed");
Time::parse("20:45:31.133", &formats).expect("Parse failed");
Time::parse("19:44", &formats).expect("Parse failed"); Then I get an error from the second parse:
But if I changed the ordering to the following they all pass: let formats = FormatItem::First(&[
FormatItem::Compound(format_description!("[hour]:[minute]:[second].[subsecond]")),
FormatItem::Compound(format_description!("[hour]:[minute]:[second]")),
FormatItem::Compound(format_description!("[hour]:[minute]")),
]); I had the same issue with PrimitiveDateTime for the descriptions I gave it. Conversely, OffsetDateTime format description ordering had no effect at all at least for the descriptions I gave it: let formats = FormatItem::First(&[
FormatItem::Compound(format_description!("[year]-[month]-[day] [hour]:[minute][offset_hour sign:mandatory]:[offset_minute]")),
FormatItem::Compound(format_description!("[year]-[month]-[day]T[hour]:[minute][offset_hour sign:mandatory]:[offset_minute]")),
FormatItem::Compound(format_description!("[year]-[month]-[day] [hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]")),
FormatItem::Compound(format_description!("[year]-[month]-[day] [hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]:[offset_minute]")),
]);
OffsetDateTime::parse("2015-11-19 01:01:39+01:00", &formats).expect("Parse failed");
OffsetDateTime::parse("2014-10-18 00:00:38.697+00:00", &formats).expect("Parse failed");
OffsetDateTime::parse("2013-09-17 23:59-01:00", &formats).expect("Parse failed");
OffsetDateTime::parse("2017-04-11T14:35+02:00", &formats).expect("Parse failed"); Am I using |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
It is |
Beta Was this translation helpful? Give feedback.
It is
Time::parse("20:45:31.133", &formats).expect("Parse failed");
that fails. There is a simple explanation for this behavior. The first format description ("[hour]:[minute]:[second]"
) does match the string, albeit with characters left over (hence the "trailing characters" error). This is due to the way parsing is done: one step parses the item, returning the remaining input, and another step sees the remaining input and returns an error.FormatItem::First
only handles the catches errors at the first step. I will look into what it would take to change this — I'm not positive it's doable for the general case.