@@ -371,19 +371,63 @@ pub struct TimeParams {
371371 pub daylight : Daylight ,
372372}
373373
374- /// Error returned by [`Time`] methods if the input is outside the valid range.
375- #[ derive( Copy , Clone , Debug , Default , Eq , PartialEq ) ]
376- pub struct TimeError ;
374+ /// Error returned by [`Time`] methods. A bool value of `true` means
375+ /// the specified field is outside of its valid range.
376+ #[ allow( missing_docs) ]
377+ #[ derive( Debug , Default , PartialEq , Eq ) ]
378+ pub struct TimeError {
379+ pub year : bool ,
380+ pub month : bool ,
381+ pub day : bool ,
382+ pub hour : bool ,
383+ pub minute : bool ,
384+ pub second : bool ,
385+ pub nanosecond : bool ,
386+ pub timezone : bool ,
387+ pub daylight : bool ,
388+ }
377389
378390impl Display for TimeError {
379391 fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
380- write ! ( f, "{self:?}" )
392+ if * self == TimeError :: default ( ) {
393+ write ! ( f, "No erroneous fields found in EFI Time." ) ?;
394+ } else {
395+ write ! ( f, "Erroneous fields found in EFI Time:" ) ?;
396+ if self . year {
397+ write ! ( f, "\n year not within `1900..=9999`" ) ?;
398+ }
399+ if self . month {
400+ write ! ( f, "\n month not within `1..=12" ) ?;
401+ }
402+ if self . day {
403+ write ! ( f, "\n day not within `1..=31`" ) ?;
404+ }
405+ if self . hour {
406+ write ! ( f, "\n hour not within `0..=23`" ) ?;
407+ }
408+ if self . minute {
409+ write ! ( f, "\n minute not within `0..=59`" ) ?;
410+ }
411+ if self . second {
412+ write ! ( f, "\n second not within `0..=59`" ) ?;
413+ }
414+ if self . nanosecond {
415+ write ! ( f, "\n nanosecond not within `0..=999_999_999`" ) ?;
416+ }
417+ if self . timezone {
418+ write ! (
419+ f,
420+ "\n time_zone not `Time::UNSPECIFIED_TIMEZONE` nor within `-1440..=1440`"
421+ ) ?;
422+ }
423+ if self . daylight {
424+ write ! ( f, "\n unknown bits set for daylight" ) ?;
425+ }
426+ }
427+ Ok ( ( ) )
381428 }
382429}
383430
384- #[ cfg( feature = "unstable" ) ]
385- impl core:: error:: Error for TimeError { }
386-
387431impl Time {
388432 /// Unspecified Timezone/local time.
389433 const UNSPECIFIED_TIMEZONE : i16 = uefi_raw:: time:: Time :: UNSPECIFIED_TIMEZONE ;
@@ -404,11 +448,8 @@ impl Time {
404448 daylight : params. daylight ,
405449 pad2 : 0 ,
406450 } ) ;
407- if time. is_valid ( ) {
408- Ok ( time)
409- } else {
410- Err ( TimeError )
411- }
451+
452+ time. is_valid ( ) . map ( |_| time)
412453 }
413454
414455 /// Create an invalid `Time` with all fields set to zero. This can
@@ -422,10 +463,38 @@ impl Time {
422463 Self ( uefi_raw:: time:: Time :: invalid ( ) )
423464 }
424465
425- /// True if all fields are within valid ranges, false otherwise.
426- #[ must_use]
427- pub fn is_valid ( & self ) -> bool {
428- self . 0 . is_valid ( )
466+ /// `Ok()` if all fields are within valid ranges, `Err(TimeError)` otherwise.
467+ pub fn is_valid ( & self ) -> core:: result:: Result < ( ) , TimeError > {
468+ let mut err = TimeError :: default ( ) ;
469+ if !( 1900 ..=9999 ) . contains ( & self . year ( ) ) {
470+ err. year = true ;
471+ }
472+ if !( 1 ..=12 ) . contains ( & self . month ( ) ) {
473+ err. month = true ;
474+ }
475+ if !( 1 ..=31 ) . contains ( & self . day ( ) ) {
476+ err. day = true ;
477+ }
478+ if self . hour ( ) > 23 {
479+ err. hour = true ;
480+ }
481+ if self . minute ( ) > 59 {
482+ err. minute = true ;
483+ }
484+ if self . second ( ) > 59 {
485+ err. second = true ;
486+ }
487+ if self . nanosecond ( ) > 999_999_999 {
488+ err. nanosecond = true ;
489+ }
490+ if self . time_zone ( ) . is_some ( ) && !( ( -1440 ..=1440 ) . contains ( & self . time_zone ( ) . unwrap ( ) ) ) {
491+ err. timezone = true ;
492+ }
493+ if err == TimeError :: default ( ) {
494+ Ok ( ( ) )
495+ } else {
496+ Err ( err)
497+ }
429498 }
430499
431500 /// Query the year.
0 commit comments