8054978: java.time.Duration.parse() fails for negative duration with 0 seconds and nanos
authorntv
Fri, 13 Nov 2015 11:52:56 -0500
changeset 33824 a156e182382b
parent 33823 d0a9fcbf6789
child 33825 e7ed5c869dc7
8054978: java.time.Duration.parse() fails for negative duration with 0 seconds and nanos Reviewed-by: rriggs, scolebourne
jdk/src/java.base/share/classes/java/time/Duration.java
jdk/test/java/time/tck/java/time/TCKDuration.java
--- a/jdk/src/java.base/share/classes/java/time/Duration.java	Fri Nov 13 07:22:48 2015 -0500
+++ b/jdk/src/java.base/share/classes/java/time/Duration.java	Fri Nov 13 11:52:56 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -359,8 +359,8 @@
      * there must be at least one section after the "T".
      * The number part of each section must consist of one or more ASCII digits.
      * The number may be prefixed by the ASCII negative or positive symbol.
-     * The number of days, hours and minutes must parse to an {@code long}.
-     * The number of seconds must parse to an {@code long} with optional fraction.
+     * The number of days, hours and minutes must parse to a {@code long}.
+     * The number of seconds must parse to a {@code long} with optional fraction.
      * The decimal point may be either a dot or a comma.
      * The fractional part may have from zero to 9 digits.
      * <p>
@@ -374,9 +374,9 @@
      *    "PT10H"     -- parses as "10 hours" (where an hour is 3600 seconds)
      *    "P2D"       -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
      *    "P2DT3H4M"  -- parses as "2 days, 3 hours and 4 minutes"
-     *    "P-6H3M"    -- parses as "-6 hours and +3 minutes"
-     *    "-P6H3M"    -- parses as "-6 hours and -3 minutes"
-     *    "-P-6H+3M"  -- parses as "+6 hours and -3 minutes"
+     *    "PT-6H3M"    -- parses as "-6 hours and +3 minutes"
+     *    "-PT6H3M"    -- parses as "-6 hours and -3 minutes"
+     *    "-PT-6H+3M"  -- parses as "+6 hours and -3 minutes"
      * </pre>
      *
      * @param text  the text to parse, not null
@@ -402,7 +402,8 @@
                     long hoursAsSecs = parseNumber(text, hourStart, hourEnd, SECONDS_PER_HOUR, "hours");
                     long minsAsSecs = parseNumber(text, minuteStart, minuteEnd, SECONDS_PER_MINUTE, "minutes");
                     long seconds = parseNumber(text, secondStart, secondEnd, 1, "seconds");
-                    int nanos = parseFraction(text, fractionStart, fractionEnd, seconds < 0 ? -1 : 1);
+                    boolean negativeSecs = secondStart >= 0 && text.charAt(secondStart) == '-';
+                    int nanos = parseFraction(text, fractionStart, fractionEnd, negativeSecs ? -1 : 1);
                     try {
                         return create(negate, daysAsSecs, hoursAsSecs, minsAsSecs, seconds, nanos);
                     } catch (ArithmeticException ex) {
--- a/jdk/test/java/time/tck/java/time/TCKDuration.java	Fri Nov 13 07:22:48 2015 -0500
+++ b/jdk/test/java/time/tck/java/time/TCKDuration.java	Fri Nov 13 11:52:56 2015 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -521,6 +521,8 @@
                 {"PT-123456789S", -123456789, 0},
                 {"PT" + Long.MIN_VALUE + "S", Long.MIN_VALUE, 0},
 
+
+                {"PT0.1S", 0, 100000000},
                 {"PT1.1S", 1, 100000000},
                 {"PT1.12S", 1, 120000000},
                 {"PT1.123S", 1, 123000000},
@@ -531,6 +533,7 @@
                 {"PT1.12345678S", 1, 123456780},
                 {"PT1.123456789S", 1, 123456789},
 
+                {"PT-0.1S", -1, 1000000000 - 100000000},
                 {"PT-1.1S", -2, 1000000000 - 100000000},
                 {"PT-1.12S", -2, 1000000000 - 120000000},
                 {"PT-1.123S", -2, 1000000000 - 123000000},
@@ -544,6 +547,24 @@
                 {"PT" + Long.MAX_VALUE + ".123456789S", Long.MAX_VALUE, 123456789},
                 {"PT" + Long.MIN_VALUE + ".000000000S", Long.MIN_VALUE, 0},
 
+                {"PT12M", 12 * 60, 0},
+                {"PT12M0.35S", 12 * 60, 350000000},
+                {"PT12M1.35S", 12 * 60 + 1, 350000000},
+                {"PT12M-0.35S", 12 * 60 - 1, 1000000000 - 350000000},
+                {"PT12M-1.35S", 12 * 60 - 2, 1000000000 - 350000000},
+
+                {"PT12H", 12 * 3600, 0},
+                {"PT12H0.35S", 12 * 3600, 350000000},
+                {"PT12H1.35S", 12 * 3600 + 1, 350000000},
+                {"PT12H-0.35S", 12 * 3600 - 1, 1000000000 - 350000000},
+                {"PT12H-1.35S", 12 * 3600 - 2, 1000000000 - 350000000},
+
+                {"P12D", 12 * 24 * 3600, 0},
+                {"P12DT0.35S", 12 * 24 * 3600, 350000000},
+                {"P12DT1.35S", 12 * 24 * 3600 + 1, 350000000},
+                {"P12DT-0.35S", 12 * 24 * 3600 - 1, 1000000000 - 350000000},
+                {"P12DT-1.35S", 12 * 24 * 3600 - 2, 1000000000 - 350000000},
+
                 {"PT01S", 1, 0},
                 {"PT001S", 1, 0},
                 {"PT000S", 0, 0},