@@ -140,6 +140,8 @@ pub struct Parsed {
140140 #[ doc( hidden) ]
141141 pub isoyear_mod_100 : Option < i32 > ,
142142 #[ doc( hidden) ]
143+ pub quarter : Option < u32 > ,
144+ #[ doc( hidden) ]
143145 pub month : Option < u32 > ,
144146 #[ doc( hidden) ]
145147 pub week_from_sun : Option < u32 > ,
@@ -304,6 +306,23 @@ impl Parsed {
304306 set_if_consistent ( & mut self . isoyear_mod_100 , value as i32 )
305307 }
306308
309+ /// Set the [`quarter`](Parsed::quarter) field to the given value.
310+ ///
311+ /// Quarter 1 starts in January.
312+ ///
313+ /// # Errors
314+ ///
315+ /// Returns `OUT_OF_RANGE` if `value` is not in the range 1-4.
316+ ///
317+ /// Returns `IMPOSSIBLE` if this field was already set to a different value.
318+ #[ inline]
319+ pub fn set_quarter ( & mut self , value : i64 ) -> ParseResult < ( ) > {
320+ if !( 1 ..=4 ) . contains ( & value) {
321+ return Err ( OUT_OF_RANGE ) ;
322+ }
323+ set_if_consistent ( & mut self . quarter , value as u32 )
324+ }
325+
307326 /// Set the [`month`](Parsed::month) field to the given value.
308327 ///
309328 /// # Errors
@@ -698,7 +717,15 @@ impl Parsed {
698717 ( _, _, _) => return Err ( NOT_ENOUGH ) ,
699718 } ;
700719
701- if verified { Ok ( parsed_date) } else { Err ( IMPOSSIBLE ) }
720+ if !verified {
721+ return Err ( IMPOSSIBLE ) ;
722+ } else if let Some ( parsed) = self . quarter {
723+ if parsed != parsed_date. quarter ( ) {
724+ return Err ( IMPOSSIBLE ) ;
725+ }
726+ }
727+
728+ Ok ( parsed_date)
702729 }
703730
704731 /// Returns a parsed naive time out of given fields.
@@ -1013,6 +1040,14 @@ impl Parsed {
10131040 self . isoyear_mod_100
10141041 }
10151042
1043+ /// Get the `quarter` field if set.
1044+ ///
1045+ /// See also [`set_quarter()`](Parsed::set_quarter).
1046+ #[ inline]
1047+ pub fn quarter ( & self ) -> Option < u32 > {
1048+ self . quarter
1049+ }
1050+
10161051 /// Get the `month` field if set.
10171052 ///
10181053 /// See also [`set_month()`](Parsed::set_month).
@@ -1267,6 +1302,11 @@ mod tests {
12671302 assert ! ( Parsed :: new( ) . set_isoyear_mod_100( 99 ) . is_ok( ) ) ;
12681303 assert_eq ! ( Parsed :: new( ) . set_isoyear_mod_100( 100 ) , Err ( OUT_OF_RANGE ) ) ;
12691304
1305+ assert_eq ! ( Parsed :: new( ) . set_quarter( 0 ) , Err ( OUT_OF_RANGE ) ) ;
1306+ assert ! ( Parsed :: new( ) . set_quarter( 1 ) . is_ok( ) ) ;
1307+ assert ! ( Parsed :: new( ) . set_quarter( 4 ) . is_ok( ) ) ;
1308+ assert_eq ! ( Parsed :: new( ) . set_quarter( 5 ) , Err ( OUT_OF_RANGE ) ) ;
1309+
12701310 assert_eq ! ( Parsed :: new( ) . set_month( 0 ) , Err ( OUT_OF_RANGE ) ) ;
12711311 assert ! ( Parsed :: new( ) . set_month( 1 ) . is_ok( ) ) ;
12721312 assert ! ( Parsed :: new( ) . set_month( 12 ) . is_ok( ) ) ;
@@ -1425,6 +1465,17 @@ mod tests {
14251465 assert_eq ! ( parse!( year: -1 , year_div_100: 0 , month: 1 , day: 1 ) , Err ( IMPOSSIBLE ) ) ;
14261466 assert_eq ! ( parse!( year: -1 , year_mod_100: 99 , month: 1 , day: 1 ) , Err ( IMPOSSIBLE ) ) ;
14271467
1468+ // quarters
1469+ assert_eq ! ( parse!( year: 2000 , quarter: 1 ) , Err ( NOT_ENOUGH ) ) ;
1470+ assert_eq ! ( parse!( year: 2000 , quarter: 1 , month: 1 , day: 1 ) , ymd( 2000 , 1 , 1 ) ) ;
1471+ assert_eq ! ( parse!( year: 2000 , quarter: 2 , month: 4 , day: 1 ) , ymd( 2000 , 4 , 1 ) ) ;
1472+ assert_eq ! ( parse!( year: 2000 , quarter: 3 , month: 7 , day: 1 ) , ymd( 2000 , 7 , 1 ) ) ;
1473+ assert_eq ! ( parse!( year: 2000 , quarter: 4 , month: 10 , day: 1 ) , ymd( 2000 , 10 , 1 ) ) ;
1474+
1475+ // quarter: conflicting inputs
1476+ assert_eq ! ( parse!( year: 2000 , quarter: 2 , month: 3 , day: 31 ) , Err ( IMPOSSIBLE ) ) ;
1477+ assert_eq ! ( parse!( year: 2000 , quarter: 4 , month: 3 , day: 31 ) , Err ( IMPOSSIBLE ) ) ;
1478+
14281479 // weekdates
14291480 assert_eq ! ( parse!( year: 2000 , week_from_mon: 0 ) , Err ( NOT_ENOUGH ) ) ;
14301481 assert_eq ! ( parse!( year: 2000 , week_from_sun: 0 ) , Err ( NOT_ENOUGH ) ) ;
0 commit comments