@@ -40,11 +40,22 @@ impl Instant {
40
40
}
41
41
42
42
impl SystemTime {
43
+ pub ( crate ) const ZERO : SystemTime = SystemTime ( Duration :: ZERO ) ;
44
+
45
+ pub ( crate ) const fn new ( t : r_efi:: efi:: Time ) -> Self {
46
+ Self ( system_time_internal:: uefi_time_to_duration ( t) )
47
+ }
48
+
43
49
pub fn now ( ) -> SystemTime {
44
50
system_time_internal:: now ( )
45
51
. unwrap_or_else ( || panic ! ( "time not implemented on this platform" ) )
46
52
}
47
53
54
+ #[ expect( dead_code) ]
55
+ pub ( crate ) const fn to_uefi_time ( & self , daylight : u8 , timezone : i16 ) -> r_efi:: efi:: Time {
56
+ system_time_internal:: uefi_time_from_duration ( self . 0 , daylight, timezone)
57
+ }
58
+
48
59
pub fn sub_time ( & self , other : & SystemTime ) -> Result < Duration , Duration > {
49
60
self . 0 . checked_sub ( other. 0 ) . ok_or_else ( || other. 0 - self . 0 )
50
61
}
@@ -79,7 +90,7 @@ pub(crate) mod system_time_internal {
79
90
80
91
let t = unsafe { t. assume_init ( ) } ;
81
92
82
- Some ( SystemTime ( uefi_time_to_duration ( t ) ) )
93
+ Some ( SystemTime :: new ( t ) )
83
94
}
84
95
85
96
// This algorithm is based on the one described in the post
@@ -112,6 +123,48 @@ pub(crate) mod system_time_internal {
112
123
113
124
Duration :: new ( utc_epoch, t. nanosecond )
114
125
}
126
+
127
+ /// This algorithm is taken from: http://howardhinnant.github.io/date_algorithms.html
128
+ pub ( crate ) const fn uefi_time_from_duration (
129
+ dur : crate :: time:: Duration ,
130
+ daylight : u8 ,
131
+ timezone : i16 ,
132
+ ) -> r_efi:: system:: Time {
133
+ const SECS_IN_MINUTE : u64 = 60 ;
134
+ const SECS_IN_HOUR : u64 = SECS_IN_MINUTE * 60 ;
135
+ const SECS_IN_DAY : u64 = SECS_IN_HOUR * 24 ;
136
+
137
+ let secs = dur. as_secs ( ) ;
138
+ let days = secs / SECS_IN_DAY ;
139
+ let remaining_secs = secs % SECS_IN_DAY ;
140
+ let z = days + 719468 ;
141
+ let era = z / 146097 ;
142
+ let doe = z - ( era * 146097 ) ;
143
+ let yoe = ( doe - doe / 1460 + doe / 36524 - doe / 146096 ) / 365 ;
144
+ let mut y = yoe + era * 400 ;
145
+ let doy = doe - ( 365 * yoe + yoe / 4 - yoe / 100 ) ;
146
+ let mp = ( 5 * doy + 2 ) / 153 ;
147
+ let d = doy - ( 153 * mp + 2 ) / 5 + 1 ;
148
+ let m = if mp < 10 { mp + 3 } else { mp - 9 } ;
149
+
150
+ if m <= 2 {
151
+ y += 1 ;
152
+ }
153
+
154
+ r_efi:: system:: Time {
155
+ year : y as u16 ,
156
+ month : m as u8 ,
157
+ day : d as u8 ,
158
+ hour : ( remaining_secs / SECS_IN_HOUR ) as u8 ,
159
+ minute : ( ( remaining_secs % SECS_IN_HOUR ) / SECS_IN_MINUTE ) as u8 ,
160
+ second : ( ( remaining_secs % SECS_IN_HOUR ) % SECS_IN_MINUTE ) as u8 ,
161
+ pad1 : 0 ,
162
+ nanosecond : dur. subsec_nanos ( ) ,
163
+ timezone,
164
+ daylight,
165
+ pad2 : 0 ,
166
+ }
167
+ }
115
168
}
116
169
117
170
pub ( crate ) mod instant_internal {
0 commit comments