@@ -196,19 +196,19 @@ impl Time {
196196 pub fn new ( year : u16 , month : u8 , day : u8 , hour : u8 , minute : u8 , second : u8 ) -> Option < Time > {
197197 if year < 10000 && month >= 1 && month <= 12 && day >= 1 && day <= 31 && hour < 24 && minute < 60 && second < 60 {
198198 Some ( Time {
199- year : year ,
200- month : month ,
201- day : day ,
202- hour : hour ,
203- minute : minute ,
204- second : second ,
199+ year,
200+ month,
201+ day,
202+ hour,
203+ minute,
204+ second,
205205 } )
206206 } else {
207207 None
208208 }
209209 }
210210
211- fn to_x509_time ( & self ) -> [ u8 ; 15 ] {
211+ pub fn to_x509_time ( & self ) -> [ u8 ; 15 ] {
212212 let mut writer = TimeWriter { buf : [ 0 ; 15 ] , idx : 0 } ;
213213 write ! (
214214 writer,
@@ -219,4 +219,76 @@ impl Time {
219219 assert ! ( writer. idx == 14 ) ;
220220 writer. buf
221221 }
222+
223+ pub fn year ( & self ) -> u16 {
224+ self . year
225+ }
226+ pub fn month ( & self ) -> u8 {
227+ self . month
228+ }
229+ pub fn day ( & self ) -> u8 {
230+ self . day
231+ }
232+ pub fn hour ( & self ) -> u8 {
233+ self . hour
234+ }
235+ pub fn minute ( & self ) -> u8 {
236+ self . minute
237+ }
238+ pub fn second ( & self ) -> u8 {
239+ self . second
240+ }
241+ }
242+
243+ #[ cfg( feature = "chrono" ) ]
244+ #[ derive( Clone , Copy , PartialEq , Eq , Debug , Default ) ]
245+ pub struct InvalidTimeError ;
246+
247+ #[ cfg( feature = "chrono" ) ]
248+ mod chrono_time {
249+ use chrono:: { Datelike , NaiveDate , NaiveDateTime , Timelike } ;
250+ use core:: convert:: { TryFrom , TryInto } ;
251+
252+ use super :: { InvalidTimeError , Time } ;
253+
254+ impl TryFrom < Time > for NaiveDateTime {
255+ type Error = InvalidTimeError ;
256+
257+ fn try_from ( value : Time ) -> Result < Self , Self :: Error > {
258+ let res = NaiveDate :: from_ymd_opt ( value. year . into ( ) , value. month . into ( ) , value. day . into ( ) )
259+ . and_then ( |date| date. and_hms_opt ( value. hour . into ( ) , value. minute . into ( ) , value. second . into ( ) ) )
260+ . ok_or ( InvalidTimeError ) ?;
261+ Ok ( res)
262+ }
263+ }
264+
265+ impl TryFrom < NaiveDateTime > for Time {
266+ type Error = InvalidTimeError ;
267+
268+ fn try_from ( value : NaiveDateTime ) -> Result < Self , Self :: Error > {
269+ let res = Time :: new (
270+ value. year ( ) . try_into ( ) . map_err ( |_| InvalidTimeError ) ?,
271+ value. month ( ) . try_into ( ) . map_err ( |_| InvalidTimeError ) ?,
272+ value. day ( ) . try_into ( ) . map_err ( |_| InvalidTimeError ) ?,
273+ value. hour ( ) . try_into ( ) . map_err ( |_| InvalidTimeError ) ?,
274+ value. minute ( ) . try_into ( ) . map_err ( |_| InvalidTimeError ) ?,
275+ value. second ( ) . try_into ( ) . map_err ( |_| InvalidTimeError ) ?,
276+ ) ;
277+ res. ok_or ( InvalidTimeError )
278+ }
279+ }
280+
281+ #[ test]
282+ fn time_naive_date_time_conversion ( ) {
283+ let time = Time :: new ( 2077 , 12 , 13 , 10 , 20 , 30 ) . unwrap ( ) ;
284+ let naive_date_time: NaiveDateTime = time. try_into ( ) . unwrap ( ) ;
285+
286+ let expected = NaiveDate :: from_ymd_opt ( 2077 , 12 , 13 )
287+ . unwrap ( )
288+ . and_hms_opt ( 10 , 20 , 30 )
289+ . unwrap ( ) ;
290+ assert_eq ! ( naive_date_time, expected) ;
291+
292+ assert_eq ! ( time, Time :: try_from( naive_date_time) . unwrap( ) ) ;
293+ }
222294}
0 commit comments