Skip to content

Commit 328e3a5

Browse files
committed
fix: hour must be greater than 0 when meridiem is specified
1 parent 1bfbaa7 commit 328e3a5

File tree

1 file changed

+31
-18
lines changed

1 file changed

+31
-18
lines changed

src/items/time.rs

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ impl Display for Offset {
143143
}
144144

145145
#[derive(Clone)]
146-
enum Suffix {
146+
enum Meridiem {
147147
Am,
148148
Pm,
149149
}
@@ -178,30 +178,37 @@ pub fn iso(input: &mut &str) -> ModalResult<Time> {
178178
///
179179
/// The hours are restricted to 12 or lower in this format
180180
fn am_pm_time(input: &mut &str) -> ModalResult<Time> {
181-
seq!(
181+
let (h, m, s, meridiem) = seq!(
182182
hour12,
183183
opt(preceded(colon, minute)),
184184
opt(preceded(colon, second)),
185185
alt((
186-
s("am").value(Suffix::Am),
187-
s("a.m.").value(Suffix::Am),
188-
s("pm").value(Suffix::Pm),
189-
s("p.m.").value(Suffix::Pm)
186+
s("am").value(Meridiem::Am),
187+
s("a.m.").value(Meridiem::Am),
188+
s("pm").value(Meridiem::Pm),
189+
s("p.m.").value(Meridiem::Pm)
190190
)),
191191
)
192-
.map(|(h, m, s, suffix)| {
193-
let mut h = h % 12;
194-
if let Suffix::Pm = suffix {
195-
h += 12;
196-
}
197-
Time {
198-
hour: h,
199-
minute: m.unwrap_or(0),
200-
second: s.unwrap_or(0.0),
201-
offset: None,
202-
}
192+
.parse_next(input)?;
193+
194+
if h == 0 {
195+
let mut ctx_err = ContextError::new();
196+
ctx_err.push(StrContext::Expected(StrContextValue::Description(
197+
"hour must be greater than 0 when meridiem is specified",
198+
)));
199+
return Err(ErrMode::Cut(ctx_err));
200+
}
201+
202+
let mut h = h % 12;
203+
if let Meridiem::Pm = meridiem {
204+
h += 12;
205+
}
206+
Ok(Time {
207+
hour: h,
208+
minute: m.unwrap_or(0),
209+
second: s.unwrap_or(0.0),
210+
offset: None,
203211
})
204-
.parse_next(input)
205212
}
206213

207214
/// Parse a colon preceded by whitespace
@@ -626,6 +633,12 @@ mod tests {
626633
}
627634
}
628635

636+
#[test]
637+
fn invalid() {
638+
assert!(parse(&mut "00:00am").is_err());
639+
assert!(parse(&mut "00:00:00am").is_err());
640+
}
641+
629642
#[test]
630643
fn hours_only() {
631644
let reference = Time {

0 commit comments

Comments
 (0)