2121//! assert_eq!(Duration::new(5, 0), Duration::from_secs(5));
2222//! ```
2323
24- use fmt;
24+ use { fmt, u64 } ;
2525use iter:: Sum ;
2626use ops:: { Add , Sub , Mul , Div , AddAssign , SubAssign , MulAssign , DivAssign } ;
2727
@@ -30,6 +30,7 @@ const NANOS_PER_MILLI: u32 = 1_000_000;
3030const NANOS_PER_MICRO : u32 = 1_000 ;
3131const MILLIS_PER_SEC : u64 = 1_000 ;
3232const MICROS_PER_SEC : u64 = 1_000_000 ;
33+ const MAX_NANOS_F64 : f64 = ( ( u64:: MAX as u128 + 1 ) * ( NANOS_PER_SEC as u128 ) ) as f64 ;
3334
3435/// A `Duration` type to represent a span of time, typically used for system
3536/// timeouts.
@@ -458,6 +459,115 @@ impl Duration {
458459 None
459460 }
460461 }
462+
463+ /// Returns the number of seconds contained by this `Duration` as `f64`.
464+ ///
465+ /// The returned value does include the fractional (nanosecond) part of the duration.
466+ ///
467+ /// # Examples
468+ /// ```
469+ /// #![feature(duration_float)]
470+ /// use std::time::Duration;
471+ ///
472+ /// let dur = Duration::new(2, 700_000_000);
473+ /// assert_eq!(dur.as_float_secs(), 2.7);
474+ /// ```
475+ #[ unstable( feature = "duration_float" , issue = "54361" ) ]
476+ #[ inline]
477+ pub fn as_float_secs ( & self ) -> f64 {
478+ ( self . secs as f64 ) + ( self . nanos as f64 ) / ( NANOS_PER_SEC as f64 )
479+ }
480+
481+ /// Creates a new `Duration` from the specified number of seconds.
482+ ///
483+ /// # Panics
484+ /// This constructor will panic if `secs` is not finite, negative or overflows `Duration`.
485+ ///
486+ /// # Examples
487+ /// ```
488+ /// #![feature(duration_float)]
489+ /// use std::time::Duration;
490+ ///
491+ /// let dur = Duration::from_float_secs(2.7);
492+ /// assert_eq!(dur, Duration::new(2, 700_000_000));
493+ /// ```
494+ #[ unstable( feature = "duration_float" , issue = "54361" ) ]
495+ #[ inline]
496+ pub fn from_float_secs ( secs : f64 ) -> Duration {
497+ let nanos = secs * ( NANOS_PER_SEC as f64 ) ;
498+ if !nanos. is_finite ( ) {
499+ panic ! ( "got non-finite value when converting float to duration" ) ;
500+ }
501+ if nanos >= MAX_NANOS_F64 {
502+ panic ! ( "overflow when converting float to duration" ) ;
503+ }
504+ if nanos < 0.0 {
505+ panic ! ( "underflow when converting float to duration" ) ;
506+ }
507+ let nanos = nanos as u128 ;
508+ Duration {
509+ secs : ( nanos / ( NANOS_PER_SEC as u128 ) ) as u64 ,
510+ nanos : ( nanos % ( NANOS_PER_SEC as u128 ) ) as u32 ,
511+ }
512+ }
513+
514+ /// Multiply `Duration` by `f64`.
515+ ///
516+ /// # Panics
517+ /// This method will panic if result is not finite, negative or overflows `Duration`.
518+ ///
519+ /// # Examples
520+ /// ```
521+ /// #![feature(duration_float)]
522+ /// use std::time::Duration;
523+ ///
524+ /// let dur = Duration::new(2, 700_000_000);
525+ /// assert_eq!(dur.mul_f64(3.14), Duration::new(8, 478_000_000));
526+ /// assert_eq!(dur.mul_f64(3.14e5), Duration::new(847_800, 0));
527+ /// ```
528+ #[ unstable( feature = "duration_float" , issue = "54361" ) ]
529+ #[ inline]
530+ pub fn mul_f64 ( self , rhs : f64 ) -> Duration {
531+ Duration :: from_float_secs ( rhs * self . as_float_secs ( ) )
532+ }
533+
534+ /// Divide `Duration` by `f64`.
535+ ///
536+ /// # Panics
537+ /// This method will panic if result is not finite, negative or overflows `Duration`.
538+ ///
539+ /// # Examples
540+ /// ```
541+ /// #![feature(duration_float)]
542+ /// use std::time::Duration;
543+ ///
544+ /// let dur = Duration::new(2, 700_000_000);
545+ /// assert_eq!(dur.div_f64(3.14), Duration::new(0, 859_872_611));
546+ /// // note that truncation is used, not rounding
547+ /// assert_eq!(dur.div_f64(3.14e5), Duration::new(0, 8_598));
548+ /// ```
549+ #[ unstable( feature = "duration_float" , issue = "54361" ) ]
550+ #[ inline]
551+ pub fn div_f64 ( self , rhs : f64 ) -> Duration {
552+ Duration :: from_float_secs ( self . as_float_secs ( ) / rhs)
553+ }
554+
555+ /// Divide `Duration` by `Duration` and return `f64`.
556+ ///
557+ /// # Examples
558+ /// ```
559+ /// #![feature(duration_float)]
560+ /// use std::time::Duration;
561+ ///
562+ /// let dur1 = Duration::new(2, 700_000_000);
563+ /// let dur2 = Duration::new(5, 400_000_000);
564+ /// assert_eq!(dur1.div_duration(dur2), 0.5);
565+ /// ```
566+ #[ unstable( feature = "duration_float" , issue = "54361" ) ]
567+ #[ inline]
568+ pub fn div_duration ( self , rhs : Duration ) -> f64 {
569+ self . as_float_secs ( ) / rhs. as_float_secs ( )
570+ }
461571}
462572
463573#[ stable( feature = "duration" , since = "1.3.0" ) ]
@@ -501,6 +611,15 @@ impl Mul<u32> for Duration {
501611 }
502612}
503613
614+ #[ stable( feature = "symmetric_u32_duration_mul" , since = "1.31.0" ) ]
615+ impl Mul < Duration > for u32 {
616+ type Output = Duration ;
617+
618+ fn mul ( self , rhs : Duration ) -> Duration {
619+ rhs * self
620+ }
621+ }
622+
504623#[ stable( feature = "time_augmented_assignment" , since = "1.9.0" ) ]
505624impl MulAssign < u32 > for Duration {
506625 fn mul_assign ( & mut self , rhs : u32 ) {
0 commit comments