@@ -317,26 +317,29 @@ impl Div<i32,Duration> for Duration {
317317
318318impl fmt:: Show for Duration {
319319 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
320- let days = self . num_days ( ) ;
321- let secs = self . secs - days * SECS_PER_DAY ;
320+ // technically speaking, negative duration is not valid ISO 8601,
321+ // but we need to print it anyway.
322+ let ( abs, sign) = if self . secs < 0 { ( -self , "-" ) } else { ( * self , "" ) } ;
323+
324+ let days = abs. secs / SECS_PER_DAY ;
325+ let secs = abs. secs - days * SECS_PER_DAY ;
322326 let hasdate = days != 0 ;
323- let hastime = ( secs != 0 || self . nanos != 0 ) || !hasdate;
327+ let hastime = ( secs != 0 || abs. nanos != 0 ) || !hasdate;
328+
329+ try!( write ! ( f, "{}P" , sign) ) ;
324330
325- try!( write ! ( f, "P" ) ) ;
326331 if hasdate {
327- // technically speaking the negative part is not the valid ISO 8601,
328- // but we need to print it anyway.
329332 try!( write ! ( f, "{}D" , days) ) ;
330333 }
331334 if hastime {
332- if self . nanos == 0 {
335+ if abs . nanos == 0 {
333336 try!( write ! ( f, "T{}S" , secs) ) ;
334- } else if self . nanos % NANOS_PER_MILLI == 0 {
335- try!( write ! ( f, "T{}.{:03}S" , secs, self . nanos / NANOS_PER_MILLI ) ) ;
336- } else if self . nanos % NANOS_PER_MICRO == 0 {
337- try!( write ! ( f, "T{}.{:06}S" , secs, self . nanos / NANOS_PER_MICRO ) ) ;
337+ } else if abs . nanos % NANOS_PER_MILLI == 0 {
338+ try!( write ! ( f, "T{}.{:03}S" , secs, abs . nanos / NANOS_PER_MILLI ) ) ;
339+ } else if abs . nanos % NANOS_PER_MICRO == 0 {
340+ try!( write ! ( f, "T{}.{:06}S" , secs, abs . nanos / NANOS_PER_MICRO ) ) ;
338341 } else {
339- try!( write ! ( f, "T{}.{:09}S" , secs, self . nanos) ) ;
342+ try!( write ! ( f, "T{}.{:09}S" , secs, abs . nanos) ) ;
340343 }
341344 }
342345 Ok ( ( ) )
@@ -540,13 +543,15 @@ mod tests {
540543 let d: Duration = Zero :: zero ( ) ;
541544 assert_eq ! ( d. to_string( ) , "PT0S" . to_string( ) ) ;
542545 assert_eq ! ( Duration :: days( 42 ) . to_string( ) , "P42D" . to_string( ) ) ;
543- assert_eq ! ( Duration :: days( -42 ) . to_string( ) , "P-42D " . to_string( ) ) ;
546+ assert_eq ! ( Duration :: days( -42 ) . to_string( ) , "-P42D " . to_string( ) ) ;
544547 assert_eq ! ( Duration :: seconds( 42 ) . to_string( ) , "PT42S" . to_string( ) ) ;
545548 assert_eq ! ( Duration :: milliseconds( 42 ) . to_string( ) , "PT0.042S" . to_string( ) ) ;
546549 assert_eq ! ( Duration :: microseconds( 42 ) . to_string( ) , "PT0.000042S" . to_string( ) ) ;
547550 assert_eq ! ( Duration :: nanoseconds( 42 ) . to_string( ) , "PT0.000000042S" . to_string( ) ) ;
548551 assert_eq ! ( ( Duration :: days( 7 ) + Duration :: milliseconds( 6543 ) ) . to_string( ) ,
549552 "P7DT6.543S" . to_string( ) ) ;
553+ assert_eq ! ( Duration :: seconds( -86401 ) . to_string( ) , "-P1DT1S" . to_string( ) ) ;
554+ assert_eq ! ( Duration :: nanoseconds( -1 ) . to_string( ) , "-PT0.000000001S" . to_string( ) ) ;
550555
551556 // the format specifier should have no effect on `Duration`
552557 assert_eq ! ( format!( "{:30}" , Duration :: days( 1 ) + Duration :: milliseconds( 2345 ) ) ,
0 commit comments