21
21
//! assert_eq!(Duration::new(5, 0), Duration::from_secs(5));
22
22
//! ```
23
23
24
- use fmt;
24
+ use { fmt, u64 } ;
25
25
use iter:: Sum ;
26
26
use ops:: { Add , Sub , Mul , Div , AddAssign , SubAssign , MulAssign , DivAssign } ;
27
27
@@ -30,6 +30,7 @@ const NANOS_PER_MILLI: u32 = 1_000_000;
30
30
const NANOS_PER_MICRO : u32 = 1_000 ;
31
31
const MILLIS_PER_SEC : u64 = 1_000 ;
32
32
const 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 ;
33
34
34
35
/// A `Duration` type to represent a span of time, typically used for system
35
36
/// timeouts.
@@ -458,6 +459,115 @@ impl Duration {
458
459
None
459
460
}
460
461
}
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
+ }
461
571
}
462
572
463
573
#[ stable( feature = "duration" , since = "1.3.0" ) ]
@@ -501,6 +611,15 @@ impl Mul<u32> for Duration {
501
611
}
502
612
}
503
613
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
+
504
623
#[ stable( feature = "time_augmented_assignment" , since = "1.9.0" ) ]
505
624
impl MulAssign < u32 > for Duration {
506
625
fn mul_assign ( & mut self , rhs : u32 ) {
0 commit comments