@@ -128,7 +128,7 @@ impl TryFrom<Date> for jiff::civil::Date {
128128}
129129
130130pub ( super ) fn parse ( input : & mut & str ) -> ModalResult < Date > {
131- alt ( ( iso1, iso2, us, literal1, literal2) ) . parse_next ( input)
131+ alt ( ( iso1, iso2, us, literal1, literal2, literal3 ) ) . parse_next ( input)
132132}
133133
134134/// Parse `[year]-[month]-[day]`
@@ -252,6 +252,18 @@ fn literal2(input: &mut &str) -> ModalResult<Date> {
252252 }
253253}
254254
255+ /// Parse `November-14-2022` and `Nov-14-2022`. Unlike `literal2`, the year is mandatory
256+ /// to match the behavior of GNU `date`.
257+ fn literal3 ( input : & mut & str ) -> ModalResult < Date > {
258+ let ( month, _, day, _, year) =
259+ ( s ( literal_month) , s ( '-' ) , s ( dec_uint) , s ( '-' ) , year_str) . parse_next ( input) ?;
260+
261+ // Map err to Backtrack instead of Cut to avoid early termination of parsing
262+ ( year, month, day)
263+ . try_into ( )
264+ . map_err ( |e| ErrMode :: Backtrack ( ctx_err ( e) ) )
265+ }
266+
255267/// Parse the name of a month (case-insensitive)
256268fn literal_month ( input : & mut & str ) -> ModalResult < u8 > {
257269 s ( alpha1)
@@ -549,6 +561,27 @@ mod tests {
549561 assert_eq ! ( s, ", 2022a" ) ;
550562 }
551563
564+ #[ test]
565+ fn literal3 ( ) {
566+ let reference = Date {
567+ year : Some ( 2022 ) ,
568+ month : 11 ,
569+ day : 14 ,
570+ } ;
571+
572+ for mut s in [
573+ "november-14-2022" ,
574+ "november----14----2022" ,
575+ "november - 14 - 2022" ,
576+ "nov-14-2022" ,
577+ "nov---14---2022" ,
578+ "nov - 14 - 2022" ,
579+ ] {
580+ let old_s = s. to_owned ( ) ;
581+ assert_eq ! ( parse( & mut s) . unwrap( ) , reference, "Format string: {old_s}" ) ;
582+ }
583+ }
584+
552585 #[ test]
553586 fn with_year ( ) {
554587 let reference = Date {
0 commit comments