|
1 |
| -use crate::{IsoWeek, Weekday}; |
| 1 | +use crate::{IsoWeek, Month, Weekday}; |
2 | 2 |
|
3 | 3 | /// The common set of methods for date component.
|
4 | 4 | ///
|
@@ -265,6 +265,18 @@ pub trait Datelike: Sized {
|
265 | 265 | ndays += ((year * 1461) >> 2) - div_100 + (div_100 >> 2);
|
266 | 266 | ndays + self.ordinal() as i32
|
267 | 267 | }
|
| 268 | + |
| 269 | + /// Get the length in days of the month |
| 270 | + fn num_days_in_month(&self) -> u8 { |
| 271 | + use num_traits::FromPrimitive; |
| 272 | + // The value returned from `self.month()` is guaranteed to be in the |
| 273 | + // range [1,12], which will never result in a `None` value here. |
| 274 | + let month = Month::from_u32(self.month()).unwrap(); |
| 275 | + // `Month::num_days` will only return `None` if the provided year is out |
| 276 | + // of range. Since we are passing it directly from a verified date, we |
| 277 | + // know it is in range, and the result will never be `None`. |
| 278 | + month.num_days(self.year()).unwrap() |
| 279 | + } |
268 | 280 | }
|
269 | 281 |
|
270 | 282 | /// The common set of methods for time component.
|
@@ -390,4 +402,14 @@ mod tests {
|
390 | 402 | );
|
391 | 403 | }
|
392 | 404 | }
|
| 405 | + |
| 406 | + #[test] |
| 407 | + fn test_num_days_in_month() { |
| 408 | + let feb_leap_year = NaiveDate::from_ymd_opt(2004, 2, 1).unwrap(); |
| 409 | + assert_eq!(feb_leap_year.num_days_in_month(), 29); |
| 410 | + let feb = feb_leap_year.with_year(2005).unwrap(); |
| 411 | + assert_eq!(feb.num_days_in_month(), 28); |
| 412 | + let march = feb.with_month(3).unwrap(); |
| 413 | + assert_eq!(march.num_days_in_month(), 31); |
| 414 | + } |
393 | 415 | }
|
0 commit comments