pub fn days_from_ymd(year: u16, month: u8, day: u8) -> Result<i32, Error> {
    const DAYS_IN_MONTH: [u8; 12] = [31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    if month < 1 || month > 12 || day < 1 {
        return Err(Error::BadDERTime);
    }
    if if month == 2 {
        let not_leap = year % 4 != 0 || (year % 100 == 0 && year % 400 != 0);
        day > 29u8 - u8::from(not_leap)
    } else {
        day > DAYS_IN_MONTH[month as usize - 1]
    } {
        return Err(Error::BadDERTime);
    }

    // Taken from https://howardhinnant.github.io/date_algorithms.html
    // Public domain
    let year: i32 = i32::from(year) - i32::from(month <= 2);
    let era: i32 = if year >= 0 { year } else { year - 399 } / 400;
    let yoe: i32 = year - era * 400;
    let months_since_feb = if month > 2 { month - 3 } else { month + 9 };
    // This is magic, but the unit-tests prove that it is correct.
    let doy: i32 = (153 * months_since_feb as i32 + 2) / 5 + i32::from(day) - 1;
    let doe: i32 = yoe * 365 + yoe / 4 - yoe / 100 + doy;
    Ok(era * 146097 + doe - 719468)
}
/// We use our own version, instead of chrono, because:
///
/// * We can (and do) perform exhaustive testing of every possible input. The
///   only possible inputs are (0, 0, 0) to (9999, 99, 99) inclusive, and we can
///   (and do) test every single one of them in a reasonable amount of time.
/// * It avoids an unnecessary dependency, and thus prevents bloat.
We use our own version, instead of chrono, because:
We can (and do) perform exhaustive testing of every possible input. The
only possible inputs are (0, 0, 0) to (9999, 99, 99) inclusive, and we can
(and do) test every single one of them in a reasonable amount of time.
It avoids an unnecessary dependency, and thus prevents bloat.
We use our own version instead of chrono because : We can ( and do ) perform exhaustive testing of every possible input . The only possible inputs are ( 0 0 0 ) to ( 9999 99 99 ) inclusive and we can ( and do ) test every single one of them in a reasonable amount of time . It avoids an unnecessary dependency and thus prevents bloat .
pub fn days_from_ymd(year: u16, month: u8, day: u8) -> Result<i32, Error> {
    const DAYS_IN_MONTH: [u8; 12] = [31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    if month < 1 || month > 12 || day < 1 {
        return Err(Error::BadDERTime);
    }
    if if month == 2 {
        let not_leap = year % 4 != 0 || (year % 100 == 0 && year % 400 != 0);
        day > 29u8 - u8::from(not_leap)
    } else {
        day > DAYS_IN_MONTH[month as usize - 1]
    } {
        return Err(Error::BadDERTime);
    }
    // Taken from https://howardhinnant.github.io/date_algorithms.html
    // Public domain
    let year: i32 = i32::from(year) - i32::from(month <= 2);
    let era: i32 = if year >= 0 { year } else { year - 399 } / 400;
    let yoe: i32 = year - era * 400;
    let months_since_feb = if month > 2 { month - 3 } else { month + 9 };
    // This is magic, but the unit-tests prove that it is correct.
    let doy: i32 = (153 * months_since_feb as i32 + 2) / 5 + i32::from(day) - 1;
    let doe: i32 = yoe * 365 + yoe / 4 - yoe / 100 + doy;
    Ok(era * 146097 + doe - 719468)
}
pub fn days_from_ymd ( year : u16 , month : u8 , day : u8 ) -> Result < i32 , Error > { const DAYS_IN_MONTH : [ u8 ; 12 ] = [ 31 , 0 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 ] ; if month < 1 || month > 12 || day < 1 { return Err ( Error :: BadDERTime ) ; } if if month == 2 { let not_leap = year % 4 != 0 || ( year % 100 == 0 && year % 400 != 0 ) ; day > 29u8 - u8 :: from ( not_leap ) } else { day > DAYS_IN_MONTH [ month as usize - 1 ] } { return Err ( Error :: BadDERTime ) ; } // Taken from https://howardhinnant.github.io/date_algorithms.html // Public domain let year : i32 = i32 :: from ( year ) - i32 :: from ( month <= 2 ) ; let era : i32 = if year >= 0 { year } else { year - 399 } / 400 ; let yoe : i32 = year - era * 400 ; let months_since_feb = if month > 2 { month - 3 } else { month + 9 } ; // This is magic, but the unit-tests prove that it is correct. let doy : i32 = ( 153 * months_since_feb as i32 + 2 ) / 5 + i32 :: from ( day ) - 1 ; let doe : i32 = yoe * 365 + yoe / 4 - yoe / 100 + doy ; Ok ( era * 146097 + doe - 719468 ) }
We use our own version, instead of chrono, because:
 We can (and do) perform exhaustive testing of every possible input.
We use our own version instead of chrono because : We can ( and do ) perform exhaustive testing of every possible input .
year
u16
month
u8
day
u8
year
u16
month
u8
day
u8