Skip to content

Commit 15dd90b

Browse files
committed
auto merge of #18359 : 1-more/rust/feature, r=alexcrichton
2 parents 18a3db6 + 9bf82fa commit 15dd90b

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

src/libstd/time/duration.rs

+18-13
Original file line numberDiff line numberDiff line change
@@ -317,26 +317,29 @@ impl Div<i32,Duration> for Duration {
317317

318318
impl 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

Comments
 (0)