1use core::cmp::Ordering;
4use core::fmt;
5use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
6
7#[cfg(feature = "std")]
8use chrono::{Datelike, Timelike, Utc};
9
10#[repr(C)]
12#[derive(
13 Debug, Clone, Copy, FromBytes, IntoBytes, KnownLayout, Immutable, Eq, PartialEq, Default,
14)]
15pub struct EfiTime {
16 pub year: u16,
17 pub month: u8,
18 pub day: u8,
19 pub hour: u8,
20 pub minute: u8,
21 pub second: u8,
22 _pad1: u8,
23 pub nanosecond: u32,
24 pub timezone: i16,
25 pub daylight: u8,
26 _pad2: u8,
27}
28
29impl EfiTime {
30 pub fn new(year: u16, month: u8, day: u8, hour: u8, minute: u8, second: u8) -> Self {
31 Self {
32 year,
33 month,
34 day,
35 hour,
36 minute,
37 second,
38 ..Default::default()
39 }
40 }
41
42 #[cfg(feature = "std")]
43 pub fn now() -> Self {
44 let t = Utc::now();
45 Self {
46 year: t.year() as u16,
47 month: t.month() as u8,
48 day: t.day() as u8,
49 hour: t.hour() as u8,
50 minute: t.minute() as u8,
51 second: t.second() as u8,
52 nanosecond: t.nanosecond(),
53 ..Default::default()
54 }
55 }
56
57 pub fn initial() -> Self {
58 Self {
61 year: 2010,
62 month: 1,
63 day: 1,
64 ..Default::default()
65 }
66 }
67}
68
69#[cfg(feature = "x509")]
70impl From<&der::DateTime> for EfiTime {
71 fn from(dt: &der::DateTime) -> Self {
72 Self {
73 year: dt.year(),
74 month: dt.month(),
75 day: dt.day(),
76 hour: dt.hour(),
77 minute: dt.minutes(),
78 second: dt.seconds(),
79 ..Default::default()
80 }
81 }
82}
83
84impl PartialOrd for EfiTime {
85 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
86 Some(self.cmp(other))
87 }
88}
89
90impl Ord for EfiTime {
91 fn cmp(&self, other: &Self) -> Ordering {
92 if self.year != other.year {
93 return self.year.cmp(&other.year);
94 }
95 if self.month != other.month {
96 return self.month.cmp(&other.month);
97 }
98 if self.day != other.day {
99 return self.day.cmp(&other.day);
100 }
101 if self.hour != other.hour {
102 return self.hour.cmp(&other.hour);
103 }
104 if self.minute != other.minute {
105 return self.minute.cmp(&other.minute);
106 }
107 if self.second != other.second {
108 return self.second.cmp(&other.second);
109 }
110 if self.nanosecond != other.nanosecond {
111 return self.nanosecond.cmp(&other.nanosecond);
112 }
113 Ordering::Equal
114 }
115}
116
117impl fmt::Display for EfiTime {
118 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119 write!(f, "{:04}-{:02}-{:02}", self.year, self.month, self.day)
120 }
121}