8145166: Duration.toString violates specification
Summary: Correct Duration.toString method
Reviewed-by: rriggs, scolebourne
--- a/jdk/src/java.base/share/classes/java/time/Duration.java Mon Jan 04 19:48:44 2016 -0800
+++ b/jdk/src/java.base/share/classes/java/time/Duration.java Tue Jan 05 10:09:48 2016 -0500
@@ -1385,7 +1385,7 @@
* <p>
* The format of the returned string will be {@code PTnHnMnS}, where n is
* the relevant hours, minutes or seconds part of the duration.
- * Any fractional seconds are placed after a decimal point i the seconds section.
+ * Any fractional seconds are placed after a decimal point in the seconds section.
* If a section has a zero value, it is omitted.
* The hours, minutes and seconds will all have the same sign.
* <p>
@@ -1406,9 +1406,13 @@
if (this == ZERO) {
return "PT0S";
}
- long hours = seconds / SECONDS_PER_HOUR;
- int minutes = (int) ((seconds % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE);
- int secs = (int) (seconds % SECONDS_PER_MINUTE);
+ long effectiveTotalSecs = seconds;
+ if (seconds < 0 && nanos > 0) {
+ effectiveTotalSecs++;
+ }
+ long hours = effectiveTotalSecs / SECONDS_PER_HOUR;
+ int minutes = (int) ((effectiveTotalSecs % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE);
+ int secs = (int) (effectiveTotalSecs % SECONDS_PER_MINUTE);
StringBuilder buf = new StringBuilder(24);
buf.append("PT");
if (hours != 0) {
@@ -1420,18 +1424,18 @@
if (secs == 0 && nanos == 0 && buf.length() > 2) {
return buf.toString();
}
- if (secs < 0 && nanos > 0) {
- if (secs == -1) {
+ if (seconds < 0 && nanos > 0) {
+ if (secs == 0) {
buf.append("-0");
} else {
- buf.append(secs + 1);
+ buf.append(secs);
}
} else {
buf.append(secs);
}
if (nanos > 0) {
int pos = buf.length();
- if (secs < 0) {
+ if (seconds < 0) {
buf.append(2 * NANOS_PER_SECOND - nanos);
} else {
buf.append(nanos + NANOS_PER_SECOND);
--- a/jdk/test/java/time/tck/java/time/TCKDuration.java Mon Jan 04 19:48:44 2016 -0800
+++ b/jdk/test/java/time/tck/java/time/TCKDuration.java Tue Jan 05 10:09:48 2016 -0500
@@ -2893,6 +2893,9 @@
{-1, 0, "PT-1S"},
{-1, 1000, "PT-0.999999S"},
{-1, 900000000, "PT-0.1S"},
+ {-60, 100_000_000, "PT-59.9S"},
+ {-59, -900_000_000, "PT-59.9S"},
+ {-60, -100_000_000, "PT-1M-0.1S"},
{Long.MAX_VALUE, 0, "PT" + (Long.MAX_VALUE / 3600) + "H" +
((Long.MAX_VALUE % 3600) / 60) + "M" + (Long.MAX_VALUE % 60) + "S"},
{Long.MIN_VALUE, 0, "PT" + (Long.MIN_VALUE / 3600) + "H" +