@@ -371,19 +371,61 @@ 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( Clone , Copy , 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+ }
389+
390+ #[ cfg( feature = "unstable" ) ]
391+ impl core:: error:: Error for TimeError { }
377392
378393impl Display for TimeError {
379394 fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
380- write ! ( f, "{self:?}" )
395+ if self . year {
396+ writeln ! ( f, "year not within `1900..=9999`" ) ?;
397+ }
398+ if self . month {
399+ writeln ! ( f, "month not within `1..=12" ) ?;
400+ }
401+ if self . day {
402+ writeln ! ( f, "day not within `1..=31`" ) ?;
403+ }
404+ if self . hour {
405+ writeln ! ( f, "hour not within `0..=23`" ) ?;
406+ }
407+ if self . minute {
408+ writeln ! ( f, "minute not within `0..=59`" ) ?;
409+ }
410+ if self . second {
411+ writeln ! ( f, "second not within `0..=59`" ) ?;
412+ }
413+ if self . nanosecond {
414+ writeln ! ( f, "nanosecond not within `0..=999_999_999`" ) ?;
415+ }
416+ if self . timezone {
417+ writeln ! (
418+ f,
419+ "time_zone not `Time::UNSPECIFIED_TIMEZONE` nor within `-1440..=1440`"
420+ ) ?;
421+ }
422+ if self . daylight {
423+ writeln ! ( f, "unknown bits set for daylight" ) ?;
424+ }
425+ Ok ( ( ) )
381426 }
382427}
383428
384- #[ cfg( feature = "unstable" ) ]
385- impl core:: error:: Error for TimeError { }
386-
387429impl Time {
388430 /// Unspecified Timezone/local time.
389431 const UNSPECIFIED_TIMEZONE : i16 = uefi_raw:: time:: Time :: UNSPECIFIED_TIMEZONE ;
@@ -404,11 +446,8 @@ impl Time {
404446 daylight : params. daylight ,
405447 pad2 : 0 ,
406448 } ) ;
407- if time. is_valid ( ) {
408- Ok ( time)
409- } else {
410- Err ( TimeError )
411- }
449+
450+ time. is_valid ( ) . map ( |_| time)
412451 }
413452
414453 /// Create an invalid `Time` with all fields set to zero. This can
@@ -422,10 +461,39 @@ impl Time {
422461 Self ( uefi_raw:: time:: Time :: invalid ( ) )
423462 }
424463
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 ( )
464+ /// `Ok()` if all fields are within valid ranges, `Err(TimeError)` otherwise.
465+ pub fn is_valid ( & self ) -> core:: result:: Result < ( ) , TimeError > {
466+ let mut err = TimeError :: default ( ) ;
467+ if !( 1900 ..=9999 ) . contains ( & self . year ( ) ) {
468+ err. year = true ;
469+ }
470+ if !( 1 ..=12 ) . contains ( & self . month ( ) ) {
471+ err. month = true ;
472+ }
473+ if !( 1 ..=31 ) . contains ( & self . day ( ) ) {
474+ err. day = true ;
475+ }
476+ if self . hour ( ) > 23 {
477+ err. hour = true ;
478+ }
479+ if self . minute ( ) > 59 {
480+ err. minute = true ;
481+ }
482+ if self . second ( ) > 59 {
483+ err. second = true ;
484+ }
485+ if self . nanosecond ( ) > 999_999_999 {
486+ err. nanosecond = true ;
487+ }
488+ if self . time_zone ( ) . is_some ( ) && !( ( -1440 ..=1440 ) . contains ( & self . time_zone ( ) . unwrap ( ) ) ) {
489+ err. timezone = true ;
490+ }
491+ // All fields are false, i.e., within their valid range.
492+ if err == TimeError :: default ( ) {
493+ Ok ( ( ) )
494+ } else {
495+ Err ( err)
496+ }
429497 }
430498
431499 /// Query the year.
0 commit comments