@@ -3,6 +3,7 @@ use core::fmt;
33#[ cfg( any( feature = "rkyv" , feature = "rkyv-16" , feature = "rkyv-32" , feature = "rkyv-64" ) ) ]
44use rkyv:: { Archive , Deserialize , Serialize } ;
55
6+ use crate :: naive:: NaiveDate ;
67use crate :: OutOfRange ;
78
89/// The month of the year.
@@ -161,6 +162,29 @@ impl Month {
161162 Month :: December => "December" ,
162163 }
163164 }
165+
166+ /// Get the length in days of the month
167+ ///
168+ /// Yields `None` if `year` is out of range for `NaiveDate`.
169+ pub fn num_days ( & self , year : i32 ) -> Option < u8 > {
170+ Some ( match * self {
171+ Month :: January => 31 ,
172+ Month :: February => match NaiveDate :: from_ymd_opt ( year, 2 , 1 ) ?. leap_year ( ) {
173+ true => 29 ,
174+ false => 28 ,
175+ } ,
176+ Month :: March => 31 ,
177+ Month :: April => 30 ,
178+ Month :: May => 31 ,
179+ Month :: June => 30 ,
180+ Month :: July => 31 ,
181+ Month :: August => 31 ,
182+ Month :: September => 30 ,
183+ Month :: October => 31 ,
184+ Month :: November => 30 ,
185+ Month :: December => 31 ,
186+ } )
187+ }
164188}
165189
166190impl TryFrom < u8 > for Month {
@@ -438,4 +462,11 @@ mod tests {
438462 let bytes = rkyv:: to_bytes :: < _ , 1 > ( & month) . unwrap ( ) ;
439463 assert_eq ! ( rkyv:: from_bytes:: <Month >( & bytes) . unwrap( ) , month) ;
440464 }
465+
466+ #[ test]
467+ fn num_days ( ) {
468+ assert_eq ! ( Month :: January . num_days( 2020 ) , Some ( 31 ) ) ;
469+ assert_eq ! ( Month :: February . num_days( 2020 ) , Some ( 29 ) ) ;
470+ assert_eq ! ( Month :: February . num_days( 2019 ) , Some ( 28 ) ) ;
471+ }
441472}
0 commit comments