@@ -86,6 +86,45 @@ impl Duration {
86
86
/// fractional portion of a second (e.g. it is less than one billion).
87
87
#[ stable( feature = "duration" , since = "1.3.0" ) ]
88
88
pub fn subsec_nanos ( & self ) -> u32 { self . nanos }
89
+
90
+ /// Multiplies this `Duration`.
91
+ ///
92
+ /// This method takes a `u64` in contrast to `Duration`'s `Mul`
93
+ /// implementation which takes an `i32`. For technical reasons, this cannot
94
+ /// be provided as an additional `Mul` implementation, though that may
95
+ /// change in the future in which case this method will be deprecated.
96
+ #[ unstable( feature = "duration_u64" , reason = "newly added" , issue = "0" ) ]
97
+ pub fn mul_u64 ( & self , rhs : u64 ) -> Duration {
98
+ // for nanos, treat rhs as (NANOS_PER_SEC * a + b), where b < NANOS_PER_SEC
99
+ let a = rhs / NANOS_PER_SEC as u64 ;
100
+ let b = rhs % NANOS_PER_SEC as u64 ;
101
+ let total_nanos = self . nanos as u64 * b; // can't overflow
102
+ let nanos = ( total_nanos % NANOS_PER_SEC as u64 ) as u32 ;
103
+
104
+ let secs = self . secs
105
+ . checked_mul ( rhs)
106
+ . and_then ( |s| s. checked_add ( total_nanos / NANOS_PER_SEC as u64 ) )
107
+ . and_then ( |s| s. checked_add ( self . nanos as u64 * a) )
108
+ . expect ( "overflow when multiplying duration" ) ;
109
+ debug_assert ! ( nanos < NANOS_PER_SEC ) ;
110
+ Duration { secs : secs, nanos : nanos }
111
+ }
112
+
113
+ /// Divides this `Duration`.
114
+ ///
115
+ /// This method takes a `u64` in contrast to `Duration`'s `Div`
116
+ /// implementation which takes an `i32`. For technical reasons, this cannot
117
+ /// be provided as an additional `Div` implementation, though that may
118
+ /// change in the future in which case this method will be deprecated.
119
+ #[ unstable( feature = "duration_u64" , reason = "newly added" , issue = "0" ) ]
120
+ pub fn div_u64 ( & self , rhs : u64 ) -> Duration {
121
+ let secs = self . secs / rhs;
122
+ let carry = self . secs - secs * rhs;
123
+ let extra_nanos = carry * ( NANOS_PER_SEC as u64 ) / rhs;
124
+ let nanos = ( self . nanos as u64 / rhs + extra_nanos) as u32 ;
125
+ debug_assert ! ( nanos < NANOS_PER_SEC ) ;
126
+ Duration { secs : secs, nanos : nanos }
127
+ }
89
128
}
90
129
91
130
#[ stable( feature = "duration" , since = "1.3.0" ) ]
@@ -250,6 +289,14 @@ mod tests {
250
289
assert_eq ! ( Duration :: new( 0 , 500_000_001 ) * 4 , Duration :: new( 2 , 4 ) ) ;
251
290
assert_eq ! ( Duration :: new( 0 , 500_000_001 ) * 4000 ,
252
291
Duration :: new( 2000 , 4000 ) ) ;
292
+
293
+ assert_eq ! ( Duration :: new( 0 , 1 ) . mul_u64( 2 ) , Duration :: new( 0 , 2 ) ) ;
294
+ assert_eq ! ( Duration :: new( 1 , 1 ) . mul_u64( 3 ) , Duration :: new( 3 , 3 ) ) ;
295
+ assert_eq ! ( Duration :: new( 0 , 500_000_001 ) . mul_u64( 4 ) , Duration :: new( 2 , 4 ) ) ;
296
+ assert_eq ! ( Duration :: new( 0 , 500_000_001 ) . mul_u64( 4000 ) ,
297
+ Duration :: new( 2000 , 4000 ) ) ;
298
+ assert_eq ! ( Duration :: new( 0 , 500_000_000 ) . mul_u64( 1 << 63 ) ,
299
+ Duration :: new( 1 << 62 , 0 ) ) ;
253
300
}
254
301
255
302
#[ test]
@@ -258,5 +305,12 @@ mod tests {
258
305
assert_eq ! ( Duration :: new( 1 , 1 ) / 3 , Duration :: new( 0 , 333_333_333 ) ) ;
259
306
assert_eq ! ( Duration :: new( 99 , 999_999_000 ) / 100 ,
260
307
Duration :: new( 0 , 999_999_990 ) ) ;
308
+
309
+ assert_eq ! ( Duration :: new( 0 , 1 ) . div_u64( 2 ) , Duration :: new( 0 , 0 ) ) ;
310
+ assert_eq ! ( Duration :: new( 1 , 1 ) . div_u64( 3 ) , Duration :: new( 0 , 333_333_333 ) ) ;
311
+ assert_eq ! ( Duration :: new( 99 , 999_999_000 ) . div_u64( 100 ) ,
312
+ Duration :: new( 0 , 999_999_990 ) ) ;
313
+ assert_eq ! ( Duration :: new( 1 << 62 , 0 ) . div_u64( 1 << 63 ) ,
314
+ Duration :: new( 0 , 500_000_000 ) ) ;
261
315
}
262
316
}
0 commit comments