Home | History | Annotate | Download | only in chrono
      1 /*
      2  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
      3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      4  *
      5  * This code is free software; you can redistribute it and/or modify it
      6  * under the terms of the GNU General Public License version 2 only, as
      7  * published by the Free Software Foundation.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle in the LICENSE file that accompanied this code.
     10  *
     11  * This code is distributed in the hope that it will be useful, but WITHOUT
     12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     14  * version 2 for more details (a copy is included in the LICENSE file that
     15  * accompanied this code).
     16  *
     17  * You should have received a copy of the GNU General Public License version
     18  * 2 along with this work; if not, write to the Free Software Foundation,
     19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     20  *
     21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 
     26 package test.java.time.chrono;
     27 
     28 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
     29 import static java.time.temporal.ChronoField.DAY_OF_YEAR;
     30 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
     31 import static java.time.temporal.ChronoField.YEAR;
     32 import static org.testng.Assert.assertEquals;
     33 import static org.testng.Assert.assertFalse;
     34 import static org.testng.Assert.assertTrue;
     35 import static org.testng.Assert.fail;
     36 
     37 import java.time.DateTimeException;
     38 import java.time.DayOfWeek;
     39 import java.time.LocalDate;
     40 import java.time.LocalDateTime;
     41 import java.time.LocalTime;
     42 import java.time.OffsetDateTime;
     43 import java.time.ZoneId;
     44 import java.time.ZoneOffset;
     45 import java.time.ZonedDateTime;
     46 import java.time.chrono.ChronoLocalDate;
     47 import java.time.chrono.ChronoLocalDateTime;
     48 import java.time.chrono.ChronoPeriod;
     49 import java.time.chrono.ChronoZonedDateTime;
     50 import java.time.chrono.Chronology;
     51 import java.time.chrono.HijrahChronology;
     52 import java.time.chrono.HijrahDate;
     53 import java.time.chrono.JapaneseChronology;
     54 import java.time.chrono.JapaneseDate;
     55 import java.time.chrono.MinguoChronology;
     56 import java.time.chrono.MinguoDate;
     57 import java.time.chrono.ThaiBuddhistChronology;
     58 import java.time.chrono.ThaiBuddhistDate;
     59 import java.time.format.DateTimeFormatter;
     60 import java.time.format.FormatStyle;
     61 import java.time.temporal.ChronoField;
     62 import java.time.temporal.ChronoUnit;
     63 import java.time.temporal.TemporalAccessor;
     64 import java.time.temporal.TemporalAdjusters;
     65 import java.time.temporal.ValueRange;
     66 import java.time.temporal.WeekFields;
     67 import java.util.Locale;
     68 
     69 import org.testng.annotations.DataProvider;
     70 import org.testng.annotations.Test;
     71 
     72 /**
     73  * Tests for the Umm alQura chronology and data.
     74  * Note: The dates used for testing are just a sample of calendar data.
     75  */
     76 @Test
     77 public class TestUmmAlQuraChronology {
     78 
     79     private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2);
     80     private static final ZoneId ZONE_RIYADH = ZoneId.of("Asia/Riyadh");
     81 
     82     // Test for HijrahChronology Aliases
     83     @Test
     84     public void test_aliases() {
     85         HijrahChronology hc = (HijrahChronology) Chronology.of("Hijrah");
     86         assertEquals(hc, HijrahChronology.INSTANCE, "Alias for Hijrah-umalqura");
     87         hc = (HijrahChronology) Chronology.of("islamic");
     88         assertEquals(hc, HijrahChronology.INSTANCE, "Alias for Hijrah-umalqura");
     89     }
     90 
     91     // Test to check if the exception is thrown for an incorrect chronology id
     92     @Test(expectedExceptions=DateTimeException.class)
     93     public void test_badChronology() {
     94         Chronology test = Chronology.of("Hijrah-ummalqura");
     95     }
     96 
     97     //--------------------------------------------------------------------------
     98     // regular data factory for Umm alQura dates and the corresponding ISO dates
     99     //--------------------------------------------------------------------------
    100     @DataProvider(name = "UmmAlQuraVsISODates")
    101     Object[][] data_UmmAlQuraVsISODates() {
    102         return new Object[][] {
    103             {HijrahDate.of(1318, 1, 1), LocalDate.of(1900, 04, 30)},
    104             {HijrahDate.of(1318, 12, 29), LocalDate.of(1901, 04, 19)},
    105             {HijrahDate.of(1319, 01, 01), LocalDate.of(1901, 04, 20)},
    106             {HijrahDate.of(1433, 12, 29), LocalDate.of(2012, 11, 14)},
    107             {HijrahDate.of(1434, 01, 01), LocalDate.of(2012, 11, 15)},
    108             {HijrahDate.of(1434, 02, 18), LocalDate.of(2012, 12, 31)},
    109             {HijrahDate.of(1502, 12, 29), LocalDate.of(2079, 10, 25)},
    110         };
    111     }
    112 
    113     // Test to verify the epoch days for given Hijrah & ISO date instances
    114     @Test(dataProvider="UmmAlQuraVsISODates")
    115         public void Test_UmmAlQuraVsISODates(HijrahDate hd, LocalDate ld) {
    116         assertEquals(hd.toEpochDay(), ld.toEpochDay(), "Umm alQura date and ISO date should have same epochDay");
    117     }
    118 
    119     // UmmAlQura chronology ranges for year, month and days for the HijrahChronology
    120     @Test
    121     public void Test_UmmAlQuraChronoRange() {
    122         HijrahChronology chrono = HijrahChronology.INSTANCE;
    123         ValueRange year = chrono.range(YEAR);
    124         assertEquals(year.getMinimum(), 1300, "Minimum year");
    125         assertEquals(year.getLargestMinimum(), 1300, "Largest minimum year");
    126         assertEquals(year.getMaximum(), 1600, "Largest year");
    127         assertEquals(year.getSmallestMaximum(), 1600, "Smallest Maximum year");
    128 
    129         ValueRange month = chrono.range(MONTH_OF_YEAR);
    130         assertEquals(month.getMinimum(), 1, "Minimum month");
    131         assertEquals(month.getLargestMinimum(), 1, "Largest minimum month");
    132         assertEquals(month.getMaximum(), 12, "Largest month");
    133         assertEquals(month.getSmallestMaximum(), 12, "Smallest Maximum month");
    134 
    135         ValueRange day = chrono.range(DAY_OF_MONTH);
    136         assertEquals(day.getMinimum(), 1, "Minimum day");
    137         assertEquals(day.getLargestMinimum(), 1, "Largest minimum day");
    138         assertEquals(day.getMaximum(), 30, "Largest day");
    139         assertEquals(day.getSmallestMaximum(), 29, "Smallest Maximum day");
    140     }
    141 
    142     //-----------------------------------------------------------------------
    143     // regular data factory for dates and the corresponding range values
    144     //-----------------------------------------------------------------------
    145     @DataProvider(name = "dates")
    146     Object[][] data_dates() {
    147         return new Object[][]{
    148             {HijrahDate.of(1300, 5, 1), 1300, 1600, 1, 12, 1, 30, 30},
    149             {HijrahDate.of(1300, 6, 1), 1300, 1600, 1, 12, 1, 29, 30},
    150             {HijrahDate.of(1434, 12, 1), 1300, 1600, 1, 12, 1, 29, 30},
    151             {HijrahDate.of(1500, 4, 1), 1300, 1600, 1, 12, 1, 30, 30},
    152             {HijrahDate.of(1600, 6, 1), 1300, 1600, 1, 12, 1, 29, 30},
    153         };
    154     }
    155 
    156     // Test to verify the min/max field ranges for given dates
    157     @Test(dataProvider="dates")
    158     public void Test_UmmAlQuraRanges(HijrahDate date,
    159                         int minYear, int maxYear,
    160                         int minMonth, int maxMonth,
    161                         int minDay, int maxDay, int maxChronoDay) {
    162         // Check the chronology ranges
    163         HijrahChronology chrono = date.getChronology();
    164         ValueRange yearRange = chrono.range(YEAR);
    165         assertEquals(yearRange.getMinimum(), minYear, "Minimum year for Hijrah chronology");
    166         assertEquals(yearRange.getLargestMinimum(), minYear, "Largest minimum year for Hijrah chronology");
    167         assertEquals(yearRange.getMaximum(), maxYear, "Maximum year for Hijrah chronology");
    168         assertEquals(yearRange.getSmallestMaximum(), maxYear, "Smallest Maximum year for Hijrah chronology");
    169 
    170         ValueRange monthRange = chrono.range(MONTH_OF_YEAR);
    171         assertEquals(monthRange.getMinimum(), minMonth, "Minimum month for Hijrah chronology");
    172         assertEquals(monthRange.getMaximum(), maxMonth, "Maximum month for Hijrah chronology");
    173 
    174         ValueRange daysRange = chrono.range(DAY_OF_MONTH);
    175         assertEquals(daysRange.getMinimum(), minDay, "Minimum day for chronology");
    176         assertEquals(daysRange.getMaximum(), maxChronoDay, "Maximum day for Hijrah chronology");
    177 
    178         // Check the date ranges
    179         yearRange = date.range(YEAR);
    180         assertEquals(yearRange.getMinimum(), minYear, "Minimum year for Hijrah date");
    181         assertEquals(yearRange.getLargestMinimum(), minYear, "Largest minimum  year for Hijrah date");
    182         assertEquals(yearRange.getMaximum(), maxYear, "Maximum year for Hijrah date");
    183         assertEquals(yearRange.getSmallestMaximum(), maxYear, "Smallest maximum year for Hijrah date");
    184 
    185         monthRange = date.range(MONTH_OF_YEAR);
    186         assertEquals(monthRange.getMinimum(), minMonth, "Minimum month for HijrahDate");
    187         assertEquals(monthRange.getMaximum(), maxMonth, "Maximum month for HijrahDate");
    188 
    189         daysRange = date.range(DAY_OF_MONTH);
    190         assertEquals(daysRange.getMinimum(), minDay, "Minimum day for HijrahDate");
    191         assertEquals(daysRange.getMaximum(), maxDay, "Maximum day for HijrahDate");
    192 
    193     }
    194 
    195     // Check the date limits
    196     @Test
    197     public void test_hijrahDateLimits() {
    198         HijrahChronology chrono = HijrahChronology.INSTANCE;
    199         ValueRange yearRange = chrono.range(YEAR);
    200         ValueRange monthRange = chrono.range(MONTH_OF_YEAR);
    201         ValueRange dayRange = chrono.range(DAY_OF_MONTH);
    202 
    203         HijrahDate xx = chrono.date(1434, 1, 1);
    204         HijrahDate minDate = chrono.date((int)yearRange.getLargestMinimum(),
    205                 (int)monthRange.getMinimum(), (int)dayRange.getMinimum());
    206         try {
    207             HijrahDate before = minDate.minus(1, ChronoUnit.DAYS);
    208             fail("Exception did not occur, minDate: " + minDate + ".minus(1, DAYS) = " + before);
    209 
    210         } catch (DateTimeException ex) {
    211             // ignore, this exception was expected
    212         }
    213 
    214         HijrahDate maxDate = chrono.date((int)yearRange.getSmallestMaximum(),
    215                 (int)monthRange.getMaximum(), 1);
    216         int monthLen = maxDate.lengthOfMonth();
    217         maxDate = maxDate.with(DAY_OF_MONTH, monthLen);
    218         try {
    219             HijrahDate after = maxDate.plus(1, ChronoUnit.DAYS);
    220             fail("Exception did not occur, maxDate: " + maxDate + ".plus(1, DAYS) = " + after);
    221         } catch (DateTimeException ex) {
    222             // ignore, this exception was expected
    223         }
    224     }
    225 
    226     // Data provider to verify the dateYearDay() method
    227     @DataProvider(name="dateYearDay")
    228     Object[][] data_dateYearDay() {
    229         return new Object[][] {
    230             {HijrahChronology.INSTANCE.dateYearDay(1434, 42), HijrahChronology.INSTANCE.date(1434, 02, 13)},
    231             {HijrahChronology.INSTANCE.dateYearDay(1330, 354), HijrahChronology.INSTANCE.date(1330, 12, 29)},
    232             {HijrahChronology.INSTANCE.dateYearDay(1600, 1), HijrahChronology.INSTANCE.date(1600, 1, 1)},
    233             {HijrahChronology.INSTANCE.dateYearDay(1400, 175), HijrahChronology.INSTANCE.date(1400, 6, 28)},
    234             {HijrahChronology.INSTANCE.dateYearDay(1520, 190), HijrahChronology.INSTANCE.date(1520, 7, 13)},
    235             {HijrahChronology.INSTANCE.dateYearDay(1521, 112), HijrahChronology.INSTANCE.date(1521, 4, 25)},
    236         };
    237     }
    238 
    239     // Test to verify the dateYearDay() method
    240     @Test(dataProvider="dateYearDay")
    241     public void test_DateYearDay(ChronoLocalDate date1,   ChronoLocalDate date2) {
    242        assertEquals(date1, date2);
    243     }
    244 
    245     //-----------------------------------------------------------------------
    246     // HijrahDate.with(DAY_OF_YEAR, n)
    247     //-----------------------------------------------------------------------
    248     @Test
    249     public void test_getDayOfYear() {
    250         HijrahDate hd1 = HijrahChronology.INSTANCE.dateYearDay(1434, 1);
    251         for (int i = 1; i <= hd1.lengthOfYear(); i++) {
    252             HijrahDate hd = HijrahChronology.INSTANCE.dateYearDay(1434, i);
    253             int doy = hd.get(DAY_OF_YEAR);
    254             assertEquals(doy, i, "get(DAY_OF_YEAR) incorrect for " + i);
    255         }
    256     }
    257 
    258     @Test
    259     public void test_withDayOfYear() {
    260         HijrahDate hd = HijrahChronology.INSTANCE.dateYearDay(1434, 1);
    261         for (int i = 1; i <= hd.lengthOfYear(); i++) {
    262             HijrahDate hd2 = hd.with(DAY_OF_YEAR, i);
    263             int doy = hd2.get(DAY_OF_YEAR);
    264             assertEquals(doy, i, "with(DAY_OF_YEAR) incorrect for " + i + " " + hd2);
    265         }
    266     }
    267 
    268     @Test(expectedExceptions=java.time.DateTimeException.class)
    269     public void test_withDayOfYearTooSmall() {
    270         HijrahDate hd = HijrahChronology.INSTANCE.dateYearDay(1435, 1);
    271         HijrahDate hd2 = hd.with(DAY_OF_YEAR, 0);
    272     }
    273 
    274     @Test(expectedExceptions=java.time.DateTimeException.class)
    275     public void test_withDayOfYearTooLarge() {
    276         HijrahDate hd = HijrahChronology.INSTANCE.dateYearDay(1435, 1);
    277         HijrahDate hd2 = hd.with(DAY_OF_YEAR, hd.lengthOfYear() + 1);
    278     }
    279 
    280     // Test to verify the with() method with ChronoField is set to DAY_OF_WEEK
    281     @Test
    282     public void test_adjustWithDayOfWeek() {
    283         assertEquals(HijrahChronology.INSTANCE.date(1320, 1, 15).with(ChronoField.DAY_OF_WEEK, 4), HijrahDate.of(1320, 1, 15));
    284         assertEquals(HijrahChronology.INSTANCE.date(1421, 11, 15).with(ChronoField.DAY_OF_WEEK, 1), HijrahDate.of(1421, 11, 11));
    285         assertEquals(HijrahChronology.INSTANCE.date(1529, 7, 18).with(ChronoField.DAY_OF_WEEK, 6), HijrahDate.of(1529, 7, 20));
    286         assertEquals(HijrahChronology.INSTANCE.date(1534, 2, 10).with(ChronoField.DAY_OF_WEEK, 5), HijrahDate.of(1534, 2, 12));
    287         assertEquals(HijrahChronology.INSTANCE.date(1552, 4, 1).with(ChronoField.DAY_OF_WEEK, 2), HijrahDate.of(1552, 3, 26));
    288     }
    289 
    290     // Test to verify the with() method with ChronoField is set to DAY_OF_MONTH
    291     @Test
    292     public void test_adjustWithDayOfMonth() {
    293         assertEquals(HijrahChronology.INSTANCE.date(1320, 1, 15).with(ChronoField.DAY_OF_MONTH, 2), HijrahDate.of(1320, 1, 2));
    294         assertEquals(HijrahChronology.INSTANCE.date(1421, 11, 15).with(ChronoField.DAY_OF_MONTH, 9), HijrahDate.of(1421, 11, 9));
    295         assertEquals(HijrahChronology.INSTANCE.date(1529, 7, 18).with(ChronoField.DAY_OF_MONTH, 13), HijrahDate.of(1529, 7, 13));
    296         assertEquals(HijrahChronology.INSTANCE.date(1534, 12, 10).with(ChronoField.DAY_OF_MONTH, 29), HijrahDate.of(1534, 12, 29));
    297         assertEquals(HijrahChronology.INSTANCE.date(1552, 4, 1).with(ChronoField.DAY_OF_MONTH, 6), HijrahDate.of(1552, 4, 6));
    298     }
    299 
    300     // Test to verify the with() method with ChronoField is set to DAY_OF_YEAR
    301     @Test
    302     public void test_adjustWithDayOfYear() {
    303         assertEquals(HijrahChronology.INSTANCE.date(1320, 1, 15).with(ChronoField.DAY_OF_YEAR, 24), HijrahDate.of(1320, 1, 24));
    304         assertEquals(HijrahChronology.INSTANCE.date(1421, 11, 15).with(ChronoField.DAY_OF_YEAR, 135), HijrahDate.of(1421, 5, 18));
    305         assertEquals(HijrahChronology.INSTANCE.date(1529, 7, 18).with(ChronoField.DAY_OF_YEAR, 64), HijrahDate.of(1529, 3, 5));
    306         assertEquals(HijrahChronology.INSTANCE.date(1534, 2, 10).with(ChronoField.DAY_OF_YEAR, 354), HijrahDate.of(1534, 12, 29));
    307         assertEquals(HijrahChronology.INSTANCE.date(1552, 4, 1).with(ChronoField.DAY_OF_YEAR, 291), HijrahDate.of(1552, 10, 26));
    308     }
    309 
    310     // Data provider to get the difference between two dates in terms of days, months and years
    311     @DataProvider(name="datesForDiff")
    312     Object[][] data_datesForDiffs() {
    313         return new Object[][] {
    314             {HijrahDate.of(1350, 5, 15), HijrahDate.of(1351, 12, 29), 574, 19, 1},
    315             {HijrahDate.of(1434, 5, 1), HijrahDate.of(1434,6, 12), 40, 1, 0},
    316             {HijrahDate.of(1436, 1, 1), HijrahDate.of(1475, 12, 29), 14173, 479, 39},
    317             {HijrahDate.of(1500, 6, 12), HijrahDate.of(1551, 7, 12), 18102, 613, 51},
    318             {HijrahDate.of(1550, 3, 11), HijrahDate.of(1551, 4, 11), 384, 13, 1},
    319         };
    320     }
    321 
    322     // Test to verify the difference between two given dates in terms of days, months and years
    323     @Test(dataProvider="datesForDiff")
    324     public void test_diffBetweenDates(ChronoLocalDate from, ChronoLocalDate to, long days, long months, long years) {
    325           assertEquals(from.until(to, ChronoUnit.DAYS), days);
    326           assertEquals(from.until(to, ChronoUnit.MONTHS), months);
    327           assertEquals(from.until(to, ChronoUnit.YEARS), years);
    328     }
    329 
    330     // Data provider to get the difference between two dates as a period
    331     @DataProvider(name="datesForPeriod")
    332     Object[][] data_Period() {
    333         return new Object[][] {
    334             {HijrahDate.of(1350, 5, 15), HijrahDate.of(1434, 7, 20), HijrahChronology.INSTANCE.period(84, 2, 5)},
    335             {HijrahDate.of(1403, 5, 28), HijrahDate.of(1434, 7, 20), HijrahChronology.INSTANCE.period(31, 1, 22)},
    336             {HijrahDate.of(1434, 7, 20), HijrahDate.of(1484, 2, 15), HijrahChronology.INSTANCE.period(49, 6, 24)},
    337             {HijrahDate.of(1500, 6, 12), HijrahDate.of(1450, 4, 21), HijrahChronology.INSTANCE.period(-50, -1, -20)},
    338             {HijrahDate.of(1549, 3, 11), HijrahDate.of(1550, 3, 10), HijrahChronology.INSTANCE.period(0, 11, 28)},
    339         };
    340     }
    341 
    342     // Test to get the Period between two given dates
    343     @Test(dataProvider="datesForPeriod")
    344     public void test_until(HijrahDate h1, HijrahDate h2, ChronoPeriod p) {
    345         ChronoPeriod period = h1.until(h2);
    346         assertEquals(period, p);
    347     }
    348 
    349     // Test to get the Period between dates in different chronologies
    350     @Test(dataProvider="datesForPeriod")
    351     public void test_periodUntilDiffChrono(HijrahDate h1, HijrahDate h2, ChronoPeriod p) {
    352         MinguoDate m = MinguoChronology.INSTANCE.date(h2);
    353         ChronoPeriod period = h1.until(m);
    354         assertEquals(period, p);
    355     }
    356 
    357     // Test to get the adjusted date from a given date using TemporalAdjuster methods
    358     @Test
    359     public void test_temporalDayAdjustments() {
    360         HijrahDate date = HijrahDate.of(1554, 7, 21);
    361         assertEquals(date.with(TemporalAdjusters.firstDayOfMonth()), HijrahDate.of(1554, 7, 1));
    362         assertEquals(date.with(TemporalAdjusters.lastDayOfMonth()), HijrahDate.of(1554, 7, 29));
    363         assertEquals(date.with(TemporalAdjusters.firstDayOfNextMonth()), HijrahDate.of(1554, 8, 1));
    364         assertEquals(date.with(TemporalAdjusters.firstDayOfNextYear()), HijrahDate.of(1555, 1, 1));
    365         assertEquals(date.with(TemporalAdjusters.firstDayOfYear()), HijrahDate.of(1554, 1, 1));
    366         assertEquals(date.with(TemporalAdjusters.lastDayOfYear()), HijrahDate.of(1554, 12, 30));
    367     }
    368 
    369     // Data provider for string representation of the date instances
    370     @DataProvider(name="toString")
    371     Object[][] data_toString() {
    372         return new Object[][] {
    373             {HijrahChronology.INSTANCE.date(1320, 1, 1), "Hijrah-umalqura AH 1320-01-01"},
    374             {HijrahChronology.INSTANCE.date(1500, 10, 28), "Hijrah-umalqura AH 1500-10-28"},
    375             {HijrahChronology.INSTANCE.date(1500, 10, 29), "Hijrah-umalqura AH 1500-10-29"},
    376             {HijrahChronology.INSTANCE.date(1434, 12, 5), "Hijrah-umalqura AH 1434-12-05"},
    377             {HijrahChronology.INSTANCE.date(1434, 12, 6), "Hijrah-umalqura AH 1434-12-06"},
    378         };
    379     }
    380 
    381     // Test to verify the returned string value of a given date instance
    382     @Test(dataProvider="toString")
    383     public void test_toString(ChronoLocalDate hijrahDate, String expected) {
    384         assertEquals(hijrahDate.toString(), expected);
    385     }
    386 
    387     // Data provider for maximum number of days
    388     @DataProvider(name="monthDays")
    389     Object[][] data_monthDays() {
    390         return new Object[][] {
    391             {1432, 1, 29},
    392             {1432, 4, 30},
    393             {1433, 12, 29},
    394             {1434, 1, 29},
    395             {1435, 8, 29},
    396             {1435, 9, 30},
    397         };
    398     }
    399 
    400     // Test to verify the maximum number of days by adding one month to a given date
    401     @Test (dataProvider="monthDays")
    402     public void test_valueRange_monthDays(int year, int month, int maxlength) {
    403         ChronoLocalDate date = HijrahChronology.INSTANCE.date(year, month, 1);
    404         ValueRange range = null;
    405         for (int i=1; i<=12; i++) {
    406             range = date.range(ChronoField.DAY_OF_MONTH);
    407             date = date.plus(1, ChronoUnit.MONTHS);
    408             assertEquals(range.getMaximum(), month, maxlength);
    409         }
    410     }
    411 
    412     // Test to get the last day of the month by adjusting the date with lastDayOfMonth() method
    413     @Test(dataProvider="monthDays")
    414     public void test_lastDayOfMonth(int year, int month, int numDays) {
    415         HijrahDate hDate = HijrahChronology.INSTANCE.date(year, month, 1);
    416         hDate = hDate.with(TemporalAdjusters.lastDayOfMonth());
    417         assertEquals(hDate.get(ChronoField.DAY_OF_MONTH), numDays);
    418     }
    419 
    420     // Data provider for the 12 islamic month names in a formatted date
    421     @DataProvider(name="patternMonthNames")
    422     Object[][] data_patternMonthNames() {
    423         return new Object[][] {
    424             {1434, 1, 1, "01 AH Thu Muharram 1434"},
    425             {1434, 2, 1, "01 AH Fri Safar 1434"},
    426             {1434, 3, 1, "01 AH Sun Rabi\u02bb I 1434"},//the actual month name is Rabi Al-Awwal, but the locale data contains short form.
    427             {1434, 4, 1, "01 AH Mon Rabi\u02bb II 1434"},//the actual month name is Rabi Al-Akhar, but the locale data contains short form.
    428             {1434, 5, 1, "01 AH Wed Jumada I 1434"},//the actual month name is Jumada Al-Awwal, but the locale data contains short form.
    429             {1434, 6, 1, "01 AH Thu Jumada II 1434"},//the actual month name is Jumada Al-Akhar, but the locale data contains short form.
    430             {1434, 7, 1, "01 AH Sat Rajab 1434"},
    431             {1434, 8, 1, "01 AH Mon Sha\u02bbban 1434"},
    432             {1434, 9, 1, "01 AH Tue Ramadan 1434"},
    433             {1434, 10, 1, "01 AH Thu Shawwal 1434"},
    434             {1434, 11, 1, "01 AH Sat Dhu\u02bbl-Qi\u02bbdah 1434"},
    435             {1434, 12, 1, "01 AH Sun Dhu\u02bbl-Hijjah 1434"},
    436         };
    437     }
    438 
    439     // Test to verify the formatted dates
    440     @Test(dataProvider="patternMonthNames")
    441     public void test_ofPattern(int year, int month, int day, String expected) {
    442         DateTimeFormatter test = DateTimeFormatter.ofPattern("dd G E MMMM yyyy", Locale.US);
    443         assertEquals(test.format(HijrahDate.of(year, month, day)), expected);
    444     }
    445 
    446     // Data provider for localized dates
    447     @DataProvider(name="chronoDateTimes")
    448    Object[][] data_chronodatetimes() {
    449         return new Object[][] {
    450             {1432, 12, 29, "Safar 1, 1434 AH"},
    451             {1433, 1, 30, "Safar 30, 1434 AH"},
    452             {1434, 6, 30, "Rajab 30, 1435 AH"},
    453         };
    454     }
    455 
    456     // Test to verify the localized dates using ofLocalizedDate() method
    457     @Test(dataProvider="chronoDateTimes")
    458     public void test_formatterOfLocalizedDate(int year, int month, int day, String expected) {
    459         HijrahDate hd = HijrahChronology.INSTANCE.date(year, month, day);
    460         ChronoLocalDateTime<HijrahDate> hdt = hd.atTime(LocalTime.NOON);
    461         hdt = hdt.plus(1, ChronoUnit.YEARS);
    462         hdt = hdt.plus(1, ChronoUnit.MONTHS);
    463         hdt = hdt.plus(1, ChronoUnit.DAYS);
    464         hdt = hdt.plus(1, ChronoUnit.HOURS);
    465         hdt = hdt.plus(1, ChronoUnit.MINUTES);
    466         hdt = hdt.plus(1, ChronoUnit.SECONDS);
    467         DateTimeFormatter df = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).withChronology(Chronology.of("Hijrah-umalqura")).withLocale(Locale.US);
    468         assertEquals(df.format(hdt), expected);
    469     }
    470 
    471     // Data provider to get the day of the week in a given date
    472     // The day of the week varies if the week starts with a saturday or sunday
    473     @DataProvider(name="dayOfWeek")
    474     Object[][] data_dayOfweek() {
    475         return new Object[][] {
    476             {HijrahDate.of(1434, 6, 24), 1, 7},
    477             {HijrahDate.of(1432, 9, 3), 5, 4},
    478             {HijrahDate.of(1334, 12, 29), 7, 6},
    479             {HijrahDate.of(1354, 5, 24), 1, 7},
    480             {HijrahDate.of(1465, 10, 2), 2, 1},
    481         };
    482     }
    483 
    484     // Test to get the day of the week based on a Saturday/Sunday as the first day of the week
    485     @Test(dataProvider="dayOfWeek")
    486     public void test_dayOfWeek(HijrahDate date, int satStart, int sunStart) {
    487         assertEquals(date.get(WeekFields.of(DayOfWeek.SATURDAY, 7).dayOfWeek()), satStart);
    488         assertEquals(date.get(WeekFields.of(DayOfWeek.SUNDAY, 7).dayOfWeek()), sunStart);
    489     }
    490 
    491     // Data sample to get the epoch days of a date instance
    492     @DataProvider(name="epochDays")
    493     Object[][] data_epochdays() {
    494         return new Object[][] {
    495             {1332, -20486},
    496             {1334, -19777},
    497             {1336, -19068},
    498             {1432, 14950},
    499             {1434, 15659},
    500             {1534, 51096},
    501             {1535, 51450},
    502         };
    503     }
    504 
    505     // Test to verify the number of epoch days of a date instance
    506     @Test(dataProvider="epochDays")
    507     public void test_epochDays(int y, long epoch) {
    508         HijrahDate date = HijrahDate.of(y, 1, 1);
    509         assertEquals(date.toEpochDay(), epoch);
    510     }
    511 
    512     // Data provider to verify whether a given hijrah year is a leap year or not
    513     @DataProvider(name="leapYears")
    514     Object[][] data_leapyears() {
    515         return new Object[][] {
    516             {1302, true},
    517             {1305, false},
    518             {1315, false},
    519             {1534, false},
    520             {1411, true},
    521             {1429, false},
    522             {1433, true},
    523             {1443, true},
    524         };
    525     }
    526 
    527     // Test to verify whether a given hijrah year is a leap year or not
    528     @Test(dataProvider="leapYears")
    529     public void test_leapYears(int y, boolean leapyear) {
    530         HijrahDate date = HijrahDate.of(y, 1, 1);
    531         assertEquals(date.isLeapYear(), leapyear);
    532     }
    533 
    534     // Data provider to verify that a given hijrah year is outside the range of supported years
    535     // The values are dependent on the currently configured UmmAlQura calendar data
    536     @DataProvider(name="OutOfRangeLeapYears")
    537     Object[][] data_invalid_leapyears() {
    538         return new Object[][] {
    539                 {1299},
    540                 {1601},
    541                 {Integer.MAX_VALUE},
    542                 {Integer.MIN_VALUE},
    543         };
    544     }
    545 
    546     @Test(dataProvider="OutOfRangeLeapYears")
    547     public void test_notLeapYears(int y) {
    548         assertFalse(HijrahChronology.INSTANCE.isLeapYear(y), "Out of range leap year");
    549     }
    550 
    551     // Date samples to convert HijrahDate to LocalDate and vice versa
    552     @DataProvider(name="samples")
    553     Object[][] data_samples() {
    554         return new Object[][] {
    555             {HijrahChronology.INSTANCE.date(1319, 12, 30), LocalDate.of(1902, 4, 9)},
    556             {HijrahChronology.INSTANCE.date(1320, 1, 1), LocalDate.of(1902, 4, 10)},
    557             {HijrahChronology.INSTANCE.date(1321, 12, 30), LocalDate.of(1904, 3, 18)},
    558             {HijrahChronology.INSTANCE.date(1433, 7, 29), LocalDate.of(2012, 6, 19)},
    559             {HijrahChronology.INSTANCE.date(1434, 10, 12), LocalDate.of(2013, 8, 19)},
    560             {HijrahChronology.INSTANCE.date(1500, 3, 3), LocalDate.of(2077, 1, 28)},
    561         };
    562     }
    563 
    564     // Test to get LocalDate instance from a given HijrahDate
    565     @Test(dataProvider="samples")
    566     public void test_toLocalDate(ChronoLocalDate hijrahDate, LocalDate iso) {
    567         assertEquals(LocalDate.from(hijrahDate), iso);
    568     }
    569 
    570     // Test to adjust HijrahDate with a given LocalDate
    571     @Test(dataProvider="samples")
    572     public void test_adjust_toLocalDate(ChronoLocalDate hijrahDate, LocalDate iso) {
    573         assertEquals(hijrahDate.with(iso), hijrahDate);
    574     }
    575 
    576     // Test to get a HijrahDate from a calendrical
    577     @Test(dataProvider="samples")
    578     public void test_fromCalendrical(ChronoLocalDate hijrahDate, LocalDate iso) {
    579         assertEquals(HijrahChronology.INSTANCE.date(iso), hijrahDate);
    580     }
    581 
    582     // Test to verify the day of week of a given HijrahDate and LocalDate
    583     @Test(dataProvider="samples")
    584     public void test_dayOfWeekEqualIsoDayOfWeek(ChronoLocalDate hijrahDate, LocalDate iso) {
    585         assertEquals(hijrahDate.get(ChronoField.DAY_OF_WEEK), iso.get(ChronoField.DAY_OF_WEEK), "Hijrah day of week should be same as ISO day of week");
    586     }
    587 
    588     // Test to get the local date by applying the MIN adjustment with hijrah date
    589     @Test(dataProvider="samples")
    590     public void test_LocalDate_adjustToHijrahDate(ChronoLocalDate hijrahDate, LocalDate localDate) {
    591         LocalDate test = LocalDate.MIN.with(hijrahDate);
    592         assertEquals(test, localDate);
    593     }
    594 
    595     // Test to get the local date time by applying the MIN adjustment with hijrah date
    596     @Test(dataProvider="samples")
    597     public void test_LocalDateTime_adjustToHijrahDate(ChronoLocalDate hijrahDate, LocalDate localDate) {
    598         LocalDateTime test = LocalDateTime.MIN.with(hijrahDate);
    599         assertEquals(test, LocalDateTime.of(localDate, LocalTime.MIDNIGHT));
    600     }
    601 
    602     // Sample dates for comparison
    603     @DataProvider(name="datesForComparison")
    604     Object[][] data_datesForComparison() {
    605         return new Object[][] {
    606             {HijrahChronology.INSTANCE.date(1434, 6, 26), LocalDate.of(2013, 5, 5), -1, 1},
    607             {HijrahChronology.INSTANCE.date(1433, 4, 15), LocalDate.of(2012, 3, 15), 1, -1},
    608             {HijrahChronology.INSTANCE.date(1432, 5, 21), LocalDate.of(2011, 4, 22), -1, 1},
    609             {HijrahChronology.INSTANCE.date(1433, 7, 29), LocalDate.of(2012, 6, 2), -1, 1},
    610             {HijrahChronology.INSTANCE.date(1434, 10, 12), LocalDate.of(2013, 8, 2), -1, 1},
    611         };
    612     }
    613 
    614     // Test to compare dates in both forward and reverse order
    615     @Test(dataProvider="datesForComparison")
    616     public void test_compareDates(HijrahDate hdate, LocalDate ldate, int result1, int result2) {
    617         assertEquals(ldate.compareTo(hdate), result1);
    618         assertEquals(hdate.compareTo(ldate), result2);
    619     }
    620 
    621     // Test to verify the values of various chrono fields for a given hijrah date instance
    622     @Test
    623     public void test_chronoFields() {
    624         ChronoLocalDate hdate = HijrahChronology.INSTANCE.date(1434, 6, 28);
    625         assertEquals(hdate.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), 3);
    626         assertEquals(hdate.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), 7);
    627         assertEquals(hdate.get(ChronoField.ALIGNED_WEEK_OF_MONTH), 4);
    628         assertEquals(hdate.get(ChronoField.ALIGNED_WEEK_OF_YEAR), 25);
    629         assertEquals(hdate.get(ChronoField.ERA), 1);
    630         assertEquals(hdate.get(ChronoField.YEAR_OF_ERA), 1434);
    631         assertEquals(hdate.get(ChronoField.MONTH_OF_YEAR), 6);
    632         assertEquals(hdate.get(ChronoField.DAY_OF_MONTH), 28);
    633         assertEquals(hdate.get(ChronoField.DAY_OF_WEEK), 3);
    634         assertEquals(hdate.get(ChronoField.DAY_OF_YEAR), 175);
    635     }
    636 
    637     // Test to verify the returned hijrah date after adjusting the day of week as Saturday
    638     @Test
    639     public void test_adjustInto() {
    640         assertEquals(DayOfWeek.SATURDAY.adjustInto(HijrahDate.of(1434, 6, 28)), HijrahDate.of(1434, 7, 1));
    641         assertEquals(DayOfWeek.SATURDAY.adjustInto(HijrahDate.of(1432, 4, 13)), HijrahDate.of(1432, 4, 14));
    642         assertEquals(DayOfWeek.SATURDAY.adjustInto(HijrahDate.of(1433, 11, 29)), HijrahDate.of(1433, 12, 4));
    643         assertEquals(DayOfWeek.SATURDAY.adjustInto(HijrahDate.of(1434, 5, 10)), HijrahDate.of(1434, 5, 11));
    644         assertEquals(DayOfWeek.SATURDAY.adjustInto(HijrahDate.of(1434, 9, 11)), HijrahDate.of(1434, 9, 12));
    645     }
    646 
    647     //-----------------------------------------------------------------------
    648     // zonedDateTime(TemporalAccessor)
    649     //-----------------------------------------------------------------------
    650     @DataProvider(name="zonedDateTime")
    651     Object[][] data_zonedDateTime() {
    652         return new Object[][] {
    653             {ZonedDateTime.of(2012, 2, 29, 2, 7, 1, 1, ZONE_RIYADH), HijrahChronology.INSTANCE.date(1433, 4, 7), LocalTime.of(2, 7, 1, 1), null},
    654             {OffsetDateTime.of(2012, 2, 29, 2, 7, 1, 1, OFFSET_PTWO), HijrahChronology.INSTANCE.date(1433, 4, 7), LocalTime.of(2, 7, 1, 1), null},
    655             {LocalDateTime.of(2012, 2, 29, 2, 7), null, null, DateTimeException.class},
    656             {JapaneseDate.of(2012, 2, 29), null, null, DateTimeException.class},
    657             {ThaiBuddhistDate.of(2012 + 543, 2, 29), null, null, DateTimeException.class},
    658             {LocalDate.of(2012, 2, 29), null, null, DateTimeException.class},
    659             {LocalTime.of(20, 30, 29, 0), null, null, DateTimeException.class},
    660         };
    661     }
    662 
    663     // Test to check the zoned date times
    664     @Test(dataProvider="zonedDateTime")
    665     public void test_zonedDateTime(TemporalAccessor accessor,  HijrahDate expectedDate, LocalTime expectedTime, Class<?> expectedEx) {
    666         if (expectedEx == null) {
    667             ChronoZonedDateTime<HijrahDate> result = HijrahChronology.INSTANCE.zonedDateTime(accessor);
    668             assertEquals(result.toLocalDate(), expectedDate);
    669             assertEquals(HijrahDate.from(accessor), expectedDate);
    670             assertEquals(result.toLocalTime(), expectedTime);
    671 
    672         } else {
    673             try {
    674                 ChronoZonedDateTime<HijrahDate> result = HijrahChronology.INSTANCE.zonedDateTime(accessor);
    675                 fail();
    676             } catch (Exception ex) {
    677                 assertTrue(expectedEx.isInstance(ex));
    678             }
    679         }
    680     }
    681 
    682     //-----------------------------------------------------------------------
    683     // zonedDateTime(Instant, ZoneId )
    684     //-----------------------------------------------------------------------
    685     @Test
    686     public void test_Instant_zonedDateTime() {
    687         OffsetDateTime offsetDateTime = OffsetDateTime.of(2012, 2, 29, 2, 7, 1, 1, OFFSET_PTWO);
    688         ZonedDateTime zonedDateTime = ZonedDateTime.of(2012, 2, 29, 2, 7, 1, 1, ZONE_RIYADH);
    689 
    690         ChronoZonedDateTime<HijrahDate> result = HijrahChronology.INSTANCE.zonedDateTime(offsetDateTime.toInstant(), offsetDateTime.getOffset());
    691         assertEquals(result.toLocalDate(), HijrahChronology.INSTANCE.date(1433, 4, 7));
    692         assertEquals(result.toLocalTime(), LocalTime.of(2, 7, 1, 1));
    693 
    694         result = HijrahChronology.INSTANCE.zonedDateTime(zonedDateTime.toInstant(), zonedDateTime.getOffset());
    695         assertEquals(result.toLocalDate(), HijrahChronology.INSTANCE.date(1433, 4, 7));
    696         assertEquals(result.toLocalTime(), LocalTime.of(2, 7, 1, 1));
    697     }
    698 
    699     //-----------------------------------------------------------------------
    700     // localDateTime()
    701     //-----------------------------------------------------------------------
    702     @DataProvider(name="localDateTime")
    703     Object[][] data_localDateTime() {
    704         return new Object[][] {
    705             {LocalDateTime.of(2012, 2, 29, 2, 7), HijrahChronology.INSTANCE.date(1433, 4, 7), LocalTime.of(2, 7), null},
    706             {ZonedDateTime.of(2012, 2, 29, 2, 7, 1, 1, ZONE_RIYADH), HijrahChronology.INSTANCE.date(1433, 4, 7), LocalTime.of(2, 7, 1, 1), null},
    707             {OffsetDateTime.of(2012, 2, 29, 2, 7, 1, 1, OFFSET_PTWO), HijrahChronology.INSTANCE.date(1433, 4, 7), LocalTime.of(2, 7, 1, 1), null},
    708             {JapaneseDate.of(2012, 2, 29), null, null, DateTimeException.class},
    709             {ThaiBuddhistDate.of(2012 + 543, 2, 29), null, null, DateTimeException.class},
    710             {LocalDate.of(2012, 2, 29), null, null, DateTimeException.class},
    711             {LocalTime.of(20, 30, 29, 0), null, null, DateTimeException.class},
    712         };
    713     }
    714 
    715     // Test to verify local date time values from various date instances defined in the localDateTime data provider
    716     @Test(dataProvider="localDateTime")
    717     public void test_localDateTime(TemporalAccessor accessor,  HijrahDate expectedDate, LocalTime expectedTime, Class<?> expectedEx) {
    718         if (expectedEx == null) {
    719             ChronoLocalDateTime<HijrahDate> result = HijrahChronology.INSTANCE.localDateTime(accessor);
    720             assertEquals(result.toLocalDate(), expectedDate);
    721             assertEquals(HijrahDate.from(accessor), expectedDate);
    722             assertEquals(result.toLocalTime(), expectedTime);
    723         } else {
    724             try {
    725                 ChronoLocalDateTime<HijrahDate> result = HijrahChronology.INSTANCE.localDateTime(accessor);
    726                 fail();
    727             } catch (Exception ex) {
    728                 assertTrue(expectedEx.isInstance(ex));
    729             }
    730         }
    731     }
    732 
    733     // Sample Hijrah & Minguo Dates
    734     @DataProvider(name="hijrahToMinguo")
    735     Object[][] data_hijrahToMinguo() {
    736         return new Object[][] {
    737             {HijrahDate.of(1350,5,15), MinguoDate.of(20,9,28)},
    738             {HijrahDate.of(1434,5,1), MinguoDate.of(102,3,13)},
    739             {HijrahDate.of(1436,1,1), MinguoDate.of(103,10,25)},
    740             {HijrahDate.of(1500,6,12), MinguoDate.of(166,5,5)},
    741             {HijrahDate.of(1550,3,11), MinguoDate.of(214,8,11)},
    742         };
    743     }
    744 
    745     // Test to verify the date conversion from Hijrah to Minguo chronology
    746     @Test(dataProvider="hijrahToMinguo")
    747     public void test_hijrahToMinguo(HijrahDate hijrah, MinguoDate minguo) {
    748         assertEquals(MinguoChronology.INSTANCE.date(hijrah), minguo);
    749     }
    750 
    751     // Sample Hijrah & Thai Dates
    752     @DataProvider(name="hijrahToThai")
    753     Object[][] data_hijrahToThai() {
    754         return new Object[][] {
    755             {HijrahDate.of(1350,5,15), ThaiBuddhistDate.of(2474,9,28)},
    756             {HijrahDate.of(1434,5,1), ThaiBuddhistDate.of(2556,3,13)},
    757             {HijrahDate.of(1436,1,1), ThaiBuddhistDate.of(2557,10,25)},
    758             {HijrahDate.of(1500,6,12), ThaiBuddhistDate.of(2620,5,5)},
    759             {HijrahDate.of(1550,3,11), ThaiBuddhistDate.of(2668,8,11)},
    760         };
    761     }
    762 
    763     // Test to verify the date conversion from Hijrah to Thai chronology
    764     @Test(dataProvider="hijrahToThai")
    765     public void test_hijrahToThai(HijrahDate hijrah, ThaiBuddhistDate thai) {
    766         assertEquals(ThaiBuddhistChronology.INSTANCE.date(hijrah), thai);
    767     }
    768 
    769     // Sample Hijrah & Japanese Dates
    770     @DataProvider(name="hijrahToJapanese")
    771     Object[][] data_hijrahToJapanese() {
    772         return new Object[][] {
    773             {HijrahDate.of(1350,5,15), "Japanese Showa 6-09-28"},
    774             {HijrahDate.of(1434,5,1), "Japanese Heisei 25-03-13"},
    775             {HijrahDate.of(1436,1,1), "Japanese Heisei 26-10-25"},
    776             {HijrahDate.of(1500,6,12), "Japanese Heisei 89-05-05"},
    777             {HijrahDate.of(1550,3,11), "Japanese Heisei 137-08-11"},
    778         };
    779     }
    780 
    781     // Test to verify the date conversion from Hijrah to Japanese chronology
    782     @Test(dataProvider="hijrahToJapanese")
    783       public void test_hijrahToJapanese(HijrahDate hijrah, String japanese) {
    784           assertEquals(JapaneseChronology.INSTANCE.date(hijrah).toString(), japanese);
    785     }
    786 }
    787