You've already forked parse_datetime
mirror of
https://github.com/uutils/parse_datetime.git
synced 2026-06-10 16:13:15 -07:00
fix: hour must be greater than 0 when meridiem is specified
This commit is contained in:
committed by
Daniel Hofstetter
parent
24fa78a927
commit
0b5d3ffdf3
+31
-18
@@ -143,7 +143,7 @@ impl Display for Offset {
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
enum Suffix {
|
||||
enum Meridiem {
|
||||
Am,
|
||||
Pm,
|
||||
}
|
||||
@@ -178,30 +178,37 @@ pub fn iso(input: &mut &str) -> ModalResult<Time> {
|
||||
///
|
||||
/// The hours are restricted to 12 or lower in this format
|
||||
fn am_pm_time(input: &mut &str) -> ModalResult<Time> {
|
||||
seq!(
|
||||
let (h, m, s, meridiem) = seq!(
|
||||
hour12,
|
||||
opt(preceded(colon, minute)),
|
||||
opt(preceded(colon, second)),
|
||||
alt((
|
||||
s("am").value(Suffix::Am),
|
||||
s("a.m.").value(Suffix::Am),
|
||||
s("pm").value(Suffix::Pm),
|
||||
s("p.m.").value(Suffix::Pm)
|
||||
s("am").value(Meridiem::Am),
|
||||
s("a.m.").value(Meridiem::Am),
|
||||
s("pm").value(Meridiem::Pm),
|
||||
s("p.m.").value(Meridiem::Pm)
|
||||
)),
|
||||
)
|
||||
.map(|(h, m, s, suffix)| {
|
||||
let mut h = h % 12;
|
||||
if let Suffix::Pm = suffix {
|
||||
h += 12;
|
||||
}
|
||||
Time {
|
||||
hour: h,
|
||||
minute: m.unwrap_or(0),
|
||||
second: s.unwrap_or(0.0),
|
||||
offset: None,
|
||||
}
|
||||
.parse_next(input)?;
|
||||
|
||||
if h == 0 {
|
||||
let mut ctx_err = ContextError::new();
|
||||
ctx_err.push(StrContext::Expected(StrContextValue::Description(
|
||||
"hour must be greater than 0 when meridiem is specified",
|
||||
)));
|
||||
return Err(ErrMode::Cut(ctx_err));
|
||||
}
|
||||
|
||||
let mut h = h % 12;
|
||||
if let Meridiem::Pm = meridiem {
|
||||
h += 12;
|
||||
}
|
||||
Ok(Time {
|
||||
hour: h,
|
||||
minute: m.unwrap_or(0),
|
||||
second: s.unwrap_or(0.0),
|
||||
offset: None,
|
||||
})
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
/// Parse a colon preceded by whitespace
|
||||
@@ -633,6 +640,12 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid() {
|
||||
assert!(parse(&mut "00:00am").is_err());
|
||||
assert!(parse(&mut "00:00:00am").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hours_only() {
|
||||
let reference = Time {
|
||||
|
||||
@@ -107,10 +107,8 @@ fn test_time_correction_with_overflow(#[case] input: &str, #[case] expected: &st
|
||||
#[case("23:59:60")]
|
||||
#[case("13:00:00am")]
|
||||
#[case("13:00:00pm")]
|
||||
/* TODO: https://github.com/uutils/parse_datetime/issues/166
|
||||
#[case("00:00:00am")]
|
||||
#[case("00:00:00pm")]
|
||||
*/
|
||||
#[case("23:59:59 a.m")]
|
||||
#[case("23:59:59 pm.")]
|
||||
#[case("23:59:59+24:01")]
|
||||
|
||||
Reference in New Issue
Block a user