changeset 13412:c65bb5305208

8145166: Duration.toString violates specification Summary: Correct Duration.toString method Reviewed-by: rriggs, scolebourne
author ntv
date Tue, 05 Jan 2016 10:09:48 -0500
parents e246069c6a83
children c8dd830a0393
files src/java.base/share/classes/java/time/Duration.java test/java/time/tck/java/time/TCKDuration.java
diffstat 2 files changed, 15 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/time/Duration.java	Mon Jan 04 19:48:44 2016 -0800
+++ b/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/test/java/time/tck/java/time/TCKDuration.java	Mon Jan 04 19:48:44 2016 -0800
+++ b/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" +