1 //! Tests for the [`DateTime`] type.
2 
3 use der::{asn1::UtcTime, DateTime, Decode, Encode};
4 use proptest::prelude::*;
5 
6 proptest! {
7     #[test]
8     fn roundtrip_datetime(
9         year in 1970u16..=9999,
10         month in 1u8..=12,
11         day in 1u8..=31,
12         hour in 0u8..=23,
13         min in 0u8..=59,
14         sec in 0u8..=59,
15     ) {
16         let datetime1 = make_datetime(year, month, day, hour, min, sec);
17         let datetime2 = DateTime::from_unix_duration(datetime1.unix_duration()).unwrap();
18         prop_assert_eq!(datetime1, datetime2);
19     }
20 
21     #[test]
22     fn roundtrip_utctime(
23         year in 1970u16..=2049,
24         month in 1u8..=12,
25         day in 1u8..=31,
26         hour in 0u8..=23,
27         min in 0u8..=59,
28         sec in 0u8..=59,
29     ) {
30         let datetime = make_datetime(year, month, day, hour, min, sec);
31         let utc_time1 = UtcTime::try_from(datetime).unwrap();
32 
33         let mut buf = [0u8; 128];
34         let mut encoder = der::SliceWriter::new(&mut buf);
35         utc_time1.encode(&mut encoder).unwrap();
36         let der_bytes = encoder.finish().unwrap();
37 
38         let utc_time2 = UtcTime::from_der(der_bytes).unwrap();
39         prop_assert_eq!(utc_time1, utc_time2);
40     }
41 }
42 
make_datetime(year: u16, month: u8, day: u8, hour: u8, min: u8, sec: u8) -> DateTime43 fn make_datetime(year: u16, month: u8, day: u8, hour: u8, min: u8, sec: u8) -> DateTime {
44     let max_day = if month == 2 {
45         let is_leap_year = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
46 
47         if is_leap_year {
48             29
49         } else {
50             28
51         }
52     } else {
53         30
54     };
55 
56     let day = if day > max_day { max_day } else { day };
57 
58     DateTime::new(year, month, day, hour, min, sec).unwrap_or_else(|e| {
59         panic!(
60             "invalid DateTime: {:02}-{:02}-{:02}T{:02}:{:02}:{:02}: {}",
61             year, month, day, hour, min, sec, e
62         );
63     })
64 }
65