8067800: Unexpected DateTimeException in the java.time.chrono.HijrahChronology.isLeapYear
authorrriggs
Fri, 06 Feb 2015 17:29:11 -0500
changeset 28848 824124d1cba5
parent 28847 5667388e3a79
child 28849 ccf9d86e52ec
8067800: Unexpected DateTimeException in the java.time.chrono.HijrahChronology.isLeapYear Summary: Check the year range consistently with other Hijrah date years Reviewed-by: lancea, scolebourne
jdk/src/java.base/share/classes/java/time/chrono/Chronology.java
jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java
jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java
--- a/jdk/src/java.base/share/classes/java/time/chrono/Chronology.java	Fri Feb 06 08:05:44 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/time/chrono/Chronology.java	Fri Feb 06 17:29:11 2015 -0500
@@ -538,7 +538,14 @@
      * <ul>
      * <li>a leap-year must imply a year-length longer than a non leap-year.
      * <li>a chronology that does not support the concept of a year must return false.
+     * <li>the correct result must be returned for all years within the
+     *     valid range of years for the chronology.
      * </ul>
+     * <p>
+     * Outside the range of valid years an implementation is free to return
+     * either a best guess or false.
+     * An implementation must not throw an exception, even if the year is
+     * outside the range of valid years.
      *
      * @param prolepticYear  the proleptic-year to check, not validated for range
      * @return true if the year is a leap year
--- a/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java	Fri Feb 06 08:05:44 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java	Fri Feb 06 17:29:11 2015 -0500
@@ -475,10 +475,10 @@
     @Override
     public boolean isLeapYear(long prolepticYear) {
         checkCalendarInit();
+        if (prolepticYear < getMinimumYear() || prolepticYear > getMaximumYear()) {
+            return false;
+        }
         int epochMonth = yearToEpochMonth((int) prolepticYear);
-        if (epochMonth < 0 || epochMonth > maxEpochDay) {
-            throw new DateTimeException("Hijrah date out of range");
-        }
         int len = getYearLength((int) prolepticYear);
         return (len > 354);
     }
--- a/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java	Fri Feb 06 08:05:44 2015 -0800
+++ b/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java	Fri Feb 06 17:29:11 2015 -0500
@@ -30,6 +30,7 @@
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
 import static java.time.temporal.ChronoField.YEAR;
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
@@ -71,6 +72,7 @@
 /**
  * Tests for the Umm alQura chronology and data.
  * Note: The dates used for testing are just a sample of calendar data.
+ * @bug 8067800
  */
 @Test
 public class TestUmmAlQuraChronology {
@@ -530,6 +532,24 @@
         assertEquals(date.isLeapYear(), leapyear);
     }
 
+    // Data provider to verify that a given hijrah year is outside the range of supported years
+    // The values are dependent on the currently configured UmmAlQura calendar data
+    @DataProvider(name="OutOfRangeLeapYears")
+    Object[][] data_invalid_leapyears() {
+        return new Object[][] {
+                {1299},
+                {1601},
+                {Integer.MAX_VALUE},
+                {Integer.MIN_VALUE},
+        };
+    }
+
+    @Test(dataProvider="OutOfRangeLeapYears")
+    public void test_notLeapYears(int y) {
+        assertFalse(HijrahChronology.INSTANCE.isLeapYear(y), "Out of range leap year");
+    }
+
+
     // Date samples to convert HijrahDate to LocalDate and vice versa
     @DataProvider(name="samples")
     Object[][] data_samples() {