1/*
2 * Copyright (c) 2012, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * This file is available under and governed by the GNU General Public
26 * License version 2 only, as published by the Free Software Foundation.
27 * However, the following notice accompanied the original version of this
28 * file:
29 *
30 * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
31 *
32 * All rights reserved.
33 *
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions are met:
36 *
37 *  * Redistributions of source code must retain the above copyright notice,
38 *    this list of conditions and the following disclaimer.
39 *
40 *  * Redistributions in binary form must reproduce the above copyright notice,
41 *    this list of conditions and the following disclaimer in the documentation
42 *    and/or other materials provided with the distribution.
43 *
44 *  * Neither the name of JSR-310 nor the names of its contributors
45 *    may be used to endorse or promote products derived from this software
46 *    without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
49 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
50 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
51 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
52 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
53 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
54 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
55 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
56 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
57 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
58 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59 */
60package tck.java.time;
61
62import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH;
63import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR;
64import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH;
65import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR;
66import static java.time.temporal.ChronoField.DAY_OF_MONTH;
67import static java.time.temporal.ChronoField.DAY_OF_WEEK;
68import static java.time.temporal.ChronoField.DAY_OF_YEAR;
69import static java.time.temporal.ChronoField.EPOCH_DAY;
70import static java.time.temporal.ChronoField.ERA;
71import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
72import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;
73import static java.time.temporal.ChronoField.YEAR;
74import static java.time.temporal.ChronoField.YEAR_OF_ERA;
75import static java.time.temporal.ChronoUnit.CENTURIES;
76import static java.time.temporal.ChronoUnit.DAYS;
77import static java.time.temporal.ChronoUnit.DECADES;
78import static java.time.temporal.ChronoUnit.HOURS;
79import static java.time.temporal.ChronoUnit.MILLENNIA;
80import static java.time.temporal.ChronoUnit.MONTHS;
81import static java.time.temporal.ChronoUnit.WEEKS;
82import static java.time.temporal.ChronoUnit.YEARS;
83import static org.testng.Assert.assertEquals;
84import static org.testng.Assert.assertFalse;
85import static org.testng.Assert.assertNotNull;
86import static org.testng.Assert.assertSame;
87import static org.testng.Assert.assertTrue;
88
89import java.io.ByteArrayOutputStream;
90import java.io.DataOutputStream;
91import java.time.Clock;
92import java.time.DateTimeException;
93import java.time.DayOfWeek;
94import java.time.Instant;
95import java.time.LocalDate;
96import java.time.LocalDateTime;
97import java.time.LocalTime;
98import java.time.Month;
99import java.time.OffsetDateTime;
100import java.time.OffsetTime;
101import java.time.Period;
102import java.time.Year;
103import java.time.ZoneId;
104import java.time.ZoneOffset;
105import java.time.ZonedDateTime;
106import java.time.chrono.IsoChronology;
107import java.time.format.DateTimeFormatter;
108import java.time.format.DateTimeParseException;
109import java.time.temporal.ChronoField;
110import java.time.temporal.ChronoUnit;
111import java.time.temporal.JulianFields;
112import java.time.temporal.Temporal;
113import java.time.temporal.TemporalAccessor;
114import java.time.temporal.TemporalAdjuster;
115import java.time.temporal.TemporalField;
116import java.time.temporal.TemporalQueries;
117import java.time.temporal.TemporalQuery;
118import java.time.temporal.TemporalUnit;
119import java.time.temporal.UnsupportedTemporalTypeException;
120import java.util.ArrayList;
121import java.util.Arrays;
122import java.util.List;
123
124import org.testng.annotations.BeforeClass;
125import org.testng.annotations.DataProvider;
126import org.testng.annotations.Test;
127import test.java.time.MockSimplePeriod;
128import test.java.time.temporal.MockFieldNoValue;
129
130/**
131 * Test LocalDate.
132 */
133@Test
134public class TCKLocalDate extends AbstractDateTimeTest {
135
136    private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1);
137    private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2);
138    private static final ZoneId ZONE_PARIS = ZoneId.of("Europe/Paris");
139    private static final ZoneId ZONE_GAZA = ZoneId.of("Asia/Gaza");
140
141    // Android-changed: These wer originally non-static and initialized in @BeforeMethod,
142    // but @BeforeMethod is run after @DataProvider methods are run, so it only worked by accident,
143    // since multiple test methods were run and the first one did not require this value.
144    private static LocalDate TEST_2007_07_15;
145    private static long MAX_VALID_EPOCHDAYS;
146    private static long MIN_VALID_EPOCHDAYS;
147    private static LocalDate MAX_DATE;
148    private static LocalDate MIN_DATE;
149    private static Instant MAX_INSTANT;
150    private static Instant MIN_INSTANT;
151
152    @BeforeClass
153    public static void setUp() {
154        TEST_2007_07_15 = LocalDate.of(2007, 7, 15);
155
156        LocalDate max = LocalDate.MAX;
157        LocalDate min = LocalDate.MIN;
158        MAX_VALID_EPOCHDAYS = max.toEpochDay();
159        MIN_VALID_EPOCHDAYS = min.toEpochDay();
160        MAX_DATE = max;
161        MIN_DATE = min;
162        MAX_INSTANT = max.atStartOfDay(ZoneOffset.UTC).toInstant();
163        MIN_INSTANT = min.atStartOfDay(ZoneOffset.UTC).toInstant();
164    }
165
166    //-----------------------------------------------------------------------
167    @Override
168    protected List<TemporalAccessor> samples() {
169        TemporalAccessor[] array = {TEST_2007_07_15, LocalDate.MAX, LocalDate.MIN, };
170        return Arrays.asList(array);
171    }
172
173    @Override
174    protected List<TemporalField> validFields() {
175        TemporalField[] array = {
176            DAY_OF_WEEK,
177            ALIGNED_DAY_OF_WEEK_IN_MONTH,
178            ALIGNED_DAY_OF_WEEK_IN_YEAR,
179            DAY_OF_MONTH,
180            DAY_OF_YEAR,
181            EPOCH_DAY,
182            ALIGNED_WEEK_OF_MONTH,
183            ALIGNED_WEEK_OF_YEAR,
184            MONTH_OF_YEAR,
185            PROLEPTIC_MONTH,
186            YEAR_OF_ERA,
187            YEAR,
188            ERA,
189            JulianFields.JULIAN_DAY,
190            JulianFields.MODIFIED_JULIAN_DAY,
191            JulianFields.RATA_DIE,
192        };
193        return Arrays.asList(array);
194    }
195
196    @Override
197    protected List<TemporalField> invalidFields() {
198        List<TemporalField> list = new ArrayList<>(Arrays.<TemporalField>asList(ChronoField.values()));
199        list.removeAll(validFields());
200        return list;
201    }
202
203    //-----------------------------------------------------------------------
204    private void check(LocalDate test, int y, int m, int d) {
205        assertEquals(test.getYear(), y);
206        assertEquals(test.getMonth().getValue(), m);
207        assertEquals(test.getDayOfMonth(), d);
208        assertEquals(test, test);
209        assertEquals(test.hashCode(), test.hashCode());
210        assertEquals(LocalDate.of(y, m, d), test);
211    }
212
213    //-----------------------------------------------------------------------
214    // constants
215    //-----------------------------------------------------------------------
216    @Test
217    public void constant_MIN() {
218        check(LocalDate.MIN, Year.MIN_VALUE, 1, 1);
219    }
220
221    @Test
222    public void constant_MAX() {
223        check(LocalDate.MAX, Year.MAX_VALUE, 12, 31);
224    }
225
226    //-----------------------------------------------------------------------
227    // now()
228    //-----------------------------------------------------------------------
229    @Test
230    public void now() {
231        LocalDate expected = LocalDate.now(Clock.systemDefaultZone());
232        LocalDate test = LocalDate.now();
233        for (int i = 0; i < 100; i++) {
234            if (expected.equals(test)) {
235                return;
236            }
237            expected = LocalDate.now(Clock.systemDefaultZone());
238            test = LocalDate.now();
239        }
240        assertEquals(test, expected);
241    }
242
243    //-----------------------------------------------------------------------
244    // now(ZoneId)
245    //-----------------------------------------------------------------------
246    @Test(expectedExceptions=NullPointerException.class)
247    public void now_ZoneId_nullZoneId() {
248        LocalDate.now((ZoneId) null);
249    }
250
251    @Test
252    public void now_ZoneId() {
253        ZoneId zone = ZoneId.of("UTC+01:02:03");
254        LocalDate expected = LocalDate.now(Clock.system(zone));
255        LocalDate test = LocalDate.now(zone);
256        for (int i = 0; i < 100; i++) {
257            if (expected.equals(test)) {
258                return;
259            }
260            expected = LocalDate.now(Clock.system(zone));
261            test = LocalDate.now(zone);
262        }
263        assertEquals(test, expected);
264    }
265
266    //-----------------------------------------------------------------------
267    // now(Clock)
268    //-----------------------------------------------------------------------
269    @Test(expectedExceptions=NullPointerException.class)
270    public void now_Clock_nullClock() {
271        LocalDate.now((Clock) null);
272    }
273
274    @Test
275    public void now_Clock_allSecsInDay_utc() {
276        for (int i = 0; i < (2 * 24 * 60 * 60); i++) {
277            Instant instant = Instant.ofEpochSecond(i);
278            Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
279            LocalDate test = LocalDate.now(clock);
280            assertEquals(test.getYear(), 1970);
281            assertEquals(test.getMonth(), Month.JANUARY);
282            assertEquals(test.getDayOfMonth(), (i < 24 * 60 * 60 ? 1 : 2));
283        }
284    }
285
286    @Test
287    public void now_Clock_allSecsInDay_offset() {
288        for (int i = 0; i < (2 * 24 * 60 * 60); i++) {
289            Instant instant = Instant.ofEpochSecond(i);
290            Clock clock = Clock.fixed(instant.minusSeconds(OFFSET_PONE.getTotalSeconds()), OFFSET_PONE);
291            LocalDate test = LocalDate.now(clock);
292            assertEquals(test.getYear(), 1970);
293            assertEquals(test.getMonth(), Month.JANUARY);
294            assertEquals(test.getDayOfMonth(), (i < 24 * 60 * 60) ? 1 : 2);
295        }
296    }
297
298    @Test
299    public void now_Clock_allSecsInDay_beforeEpoch() {
300        for (int i =-1; i >= -(2 * 24 * 60 * 60); i--) {
301            Instant instant = Instant.ofEpochSecond(i);
302            Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
303            LocalDate test = LocalDate.now(clock);
304            assertEquals(test.getYear(), 1969);
305            assertEquals(test.getMonth(), Month.DECEMBER);
306            assertEquals(test.getDayOfMonth(), (i >= -24 * 60 * 60 ? 31 : 30));
307        }
308    }
309
310    //-----------------------------------------------------------------------
311    @Test
312    public void now_Clock_maxYear() {
313        Clock clock = Clock.fixed(MAX_INSTANT, ZoneOffset.UTC);
314        LocalDate test = LocalDate.now(clock);
315        assertEquals(test, MAX_DATE);
316    }
317
318    @Test(expectedExceptions=DateTimeException.class)
319    public void now_Clock_tooBig() {
320        Clock clock = Clock.fixed(MAX_INSTANT.plusSeconds(24 * 60 * 60), ZoneOffset.UTC);
321        LocalDate.now(clock);
322    }
323
324    @Test
325    public void now_Clock_minYear() {
326        Clock clock = Clock.fixed(MIN_INSTANT, ZoneOffset.UTC);
327        LocalDate test = LocalDate.now(clock);
328        assertEquals(test, MIN_DATE);
329    }
330
331    @Test(expectedExceptions=DateTimeException.class)
332    public void now_Clock_tooLow() {
333        Clock clock = Clock.fixed(MIN_INSTANT.minusNanos(1), ZoneOffset.UTC);
334        LocalDate.now(clock);
335    }
336
337    //-----------------------------------------------------------------------
338    // of() factories
339    //-----------------------------------------------------------------------
340    @Test
341    public void factory_of_intsMonth() {
342        assertEquals(TEST_2007_07_15, LocalDate.of(2007, Month.JULY, 15));
343    }
344
345    @Test(expectedExceptions=DateTimeException.class)
346    public void factory_of_intsMonth_29febNonLeap() {
347        LocalDate.of(2007, Month.FEBRUARY, 29);
348    }
349
350    @Test(expectedExceptions=DateTimeException.class)
351    public void factory_of_intsMonth_31apr() {
352        LocalDate.of(2007, Month.APRIL, 31);
353    }
354
355    @Test(expectedExceptions=DateTimeException.class)
356    public void factory_of_intsMonth_dayTooLow() {
357        LocalDate.of(2007, Month.JANUARY, 0);
358    }
359
360    @Test(expectedExceptions=DateTimeException.class)
361    public void factory_of_intsMonth_dayTooHigh() {
362        LocalDate.of(2007, Month.JANUARY, 32);
363    }
364
365    @Test(expectedExceptions=NullPointerException.class)
366    public void factory_of_intsMonth_nullMonth() {
367        LocalDate.of(2007, null, 30);
368    }
369
370    @Test(expectedExceptions=DateTimeException.class)
371    public void factory_of_intsMonth_yearTooLow() {
372        LocalDate.of(Integer.MIN_VALUE, Month.JANUARY, 1);
373    }
374
375    //-----------------------------------------------------------------------
376    @Test
377    public void factory_of_ints() {
378        check(TEST_2007_07_15, 2007, 7, 15);
379    }
380
381    @Test(expectedExceptions=DateTimeException.class)
382    public void factory_of_ints_29febNonLeap() {
383        LocalDate.of(2007, 2, 29);
384    }
385
386    @Test(expectedExceptions=DateTimeException.class)
387    public void factory_of_ints_31apr() {
388        LocalDate.of(2007, 4, 31);
389    }
390
391    @Test(expectedExceptions=DateTimeException.class)
392    public void factory_of_ints_dayTooLow() {
393        LocalDate.of(2007, 1, 0);
394    }
395
396    @Test(expectedExceptions=DateTimeException.class)
397    public void factory_of_ints_dayTooHigh() {
398        LocalDate.of(2007, 1, 32);
399    }
400
401    @Test(expectedExceptions=DateTimeException.class)
402    public void factory_of_ints_monthTooLow() {
403        LocalDate.of(2007, 0, 1);
404    }
405
406    @Test(expectedExceptions=DateTimeException.class)
407    public void factory_of_ints_monthTooHigh() {
408        LocalDate.of(2007, 13, 1);
409    }
410
411    @Test(expectedExceptions=DateTimeException.class)
412    public void factory_of_ints_yearTooLow() {
413        LocalDate.of(Integer.MIN_VALUE, 1, 1);
414    }
415
416    //-----------------------------------------------------------------------
417    @Test
418    public void factory_ofYearDay_ints_nonLeap() {
419        LocalDate date = LocalDate.of(2007, 1, 1);
420        for (int i = 1; i < 365; i++) {
421            assertEquals(LocalDate.ofYearDay(2007, i), date);
422            date = next(date);
423        }
424    }
425
426    @Test
427    public void factory_ofYearDay_ints_leap() {
428        LocalDate date = LocalDate.of(2008, 1, 1);
429        for (int i = 1; i < 366; i++) {
430            assertEquals(LocalDate.ofYearDay(2008, i), date);
431            date = next(date);
432        }
433    }
434
435    @Test(expectedExceptions=DateTimeException.class)
436    public void factory_ofYearDay_ints_366nonLeap() {
437        LocalDate.ofYearDay(2007, 366);
438    }
439
440    @Test(expectedExceptions=DateTimeException.class)
441    public void factory_ofYearDay_ints_dayTooLow() {
442        LocalDate.ofYearDay(2007, 0);
443    }
444
445    @Test(expectedExceptions=DateTimeException.class)
446    public void factory_ofYearDay_ints_dayTooHigh() {
447        LocalDate.ofYearDay(2007, 367);
448    }
449
450    @Test(expectedExceptions=DateTimeException.class)
451    public void factory_ofYearDay_ints_yearTooLow() {
452        LocalDate.ofYearDay(Integer.MIN_VALUE, 1);
453    }
454
455    //-----------------------------------------------------------------------
456    // Since plusDays/minusDays actually depends on MJDays, it cannot be used for testing
457    private LocalDate next(LocalDate date) {
458        int newDayOfMonth = date.getDayOfMonth() + 1;
459        if (newDayOfMonth <= date.getMonth().length(isIsoLeap(date.getYear()))) {
460            return date.withDayOfMonth(newDayOfMonth);
461        }
462        date = date.withDayOfMonth(1);
463        if (date.getMonth() == Month.DECEMBER) {
464            date = date.withYear(date.getYear() + 1);
465        }
466        return date.with(date.getMonth().plus(1));
467    }
468
469    private LocalDate previous(LocalDate date) {
470        int newDayOfMonth = date.getDayOfMonth() - 1;
471        if (newDayOfMonth > 0) {
472            return date.withDayOfMonth(newDayOfMonth);
473        }
474        date = date.with(date.getMonth().minus(1));
475        if (date.getMonth() == Month.DECEMBER) {
476            date = date.withYear(date.getYear() - 1);
477        }
478        return date.withDayOfMonth(date.getMonth().length(isIsoLeap(date.getYear())));
479    }
480
481    //-----------------------------------------------------------------------
482    // ofEpochDay()
483    //-----------------------------------------------------------------------
484    @Test
485    public void factory_ofEpochDay() {
486        long date_0000_01_01 = -678941 - 40587;
487        assertEquals(LocalDate.ofEpochDay(0), LocalDate.of(1970, 1, 1));
488        assertEquals(LocalDate.ofEpochDay(date_0000_01_01), LocalDate.of(0, 1, 1));
489        assertEquals(LocalDate.ofEpochDay(date_0000_01_01 - 1), LocalDate.of(-1, 12, 31));
490        assertEquals(LocalDate.ofEpochDay(MAX_VALID_EPOCHDAYS), LocalDate.of(Year.MAX_VALUE, 12, 31));
491        assertEquals(LocalDate.ofEpochDay(MIN_VALID_EPOCHDAYS), LocalDate.of(Year.MIN_VALUE, 1, 1));
492
493        LocalDate test = LocalDate.of(0, 1, 1);
494        for (long i = date_0000_01_01; i < 700000; i++) {
495            assertEquals(LocalDate.ofEpochDay(i), test);
496            test = next(test);
497        }
498        test = LocalDate.of(0, 1, 1);
499        for (long i = date_0000_01_01; i > -2000000; i--) {
500            assertEquals(LocalDate.ofEpochDay(i), test);
501            test = previous(test);
502        }
503    }
504
505    @Test(expectedExceptions=DateTimeException.class)
506    public void factory_ofEpochDay_aboveMax() {
507        LocalDate.ofEpochDay(MAX_VALID_EPOCHDAYS + 1);
508    }
509
510    @Test(expectedExceptions=DateTimeException.class)
511    public void factory_ofEpochDay_belowMin() {
512        LocalDate.ofEpochDay(MIN_VALID_EPOCHDAYS - 1);
513    }
514
515    //-----------------------------------------------------------------------
516    // from()
517    //-----------------------------------------------------------------------
518    @Test
519    public void test_from_TemporalAccessor() {
520        assertEquals(LocalDate.from(LocalDate.of(2007, 7, 15)), LocalDate.of(2007, 7, 15));
521        assertEquals(LocalDate.from(LocalDateTime.of(2007, 7, 15, 12, 30)), LocalDate.of(2007, 7, 15));
522    }
523
524    @Test(expectedExceptions=DateTimeException.class)
525    public void test_from_TemporalAccessor_invalid_noDerive() {
526        LocalDate.from(LocalTime.of(12, 30));
527    }
528
529    @Test(expectedExceptions=NullPointerException.class)
530    public void test_from_TemporalAccessor_null() {
531        LocalDate.from((TemporalAccessor) null);
532    }
533
534    //-----------------------------------------------------------------------
535    // parse()
536    //-----------------------------------------------------------------------
537    @Test(dataProvider="sampleToString")
538    public void factory_parse_validText(int y, int m, int d, String parsable) {
539        LocalDate t = LocalDate.parse(parsable);
540        assertNotNull(t, parsable);
541        assertEquals(t.getYear(), y, parsable);
542        assertEquals(t.getMonth().getValue(), m, parsable);
543        assertEquals(t.getDayOfMonth(), d, parsable);
544    }
545
546    @DataProvider(name="sampleBadParse")
547    Object[][] provider_sampleBadParse() {
548        return new Object[][]{
549                {"2008/07/05"},
550                {"10000-01-01"},
551                {"2008-1-1"},
552                {"2008--01"},
553                {"ABCD-02-01"},
554                {"2008-AB-01"},
555                {"2008-02-AB"},
556                {"-0000-02-01"},
557                {"2008-02-01Z"},
558                {"2008-02-01+01:00"},
559                {"2008-02-01+01:00[Europe/Paris]"},
560        };
561    }
562
563    @Test(dataProvider="sampleBadParse", expectedExceptions={DateTimeParseException.class})
564    public void factory_parse_invalidText(String unparsable) {
565        LocalDate.parse(unparsable);
566    }
567
568    @Test(expectedExceptions=DateTimeParseException.class)
569    public void factory_parse_illegalValue() {
570        LocalDate.parse("2008-06-32");
571    }
572
573    @Test(expectedExceptions=DateTimeParseException.class)
574    public void factory_parse_invalidValue() {
575        LocalDate.parse("2008-06-31");
576    }
577
578    @Test(expectedExceptions=NullPointerException.class)
579    public void factory_parse_nullText() {
580        LocalDate.parse((String) null);
581    }
582
583    //-----------------------------------------------------------------------
584    // parse(DateTimeFormatter)
585    //-----------------------------------------------------------------------
586    @Test
587    public void factory_parse_formatter() {
588        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d");
589        LocalDate test = LocalDate.parse("2010 12 3", f);
590        assertEquals(test, LocalDate.of(2010, 12, 3));
591    }
592
593    @Test(expectedExceptions=NullPointerException.class)
594    public void factory_parse_formatter_nullText() {
595        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d");
596        LocalDate.parse((String) null, f);
597    }
598
599    @Test(expectedExceptions=NullPointerException.class)
600    public void factory_parse_formatter_nullFormatter() {
601        LocalDate.parse("ANY", null);
602    }
603
604    //-----------------------------------------------------------------------
605    // isSupported(TemporalField)
606    //-----------------------------------------------------------------------
607    @Test
608    public void test_isSupported_TemporalField() {
609        assertEquals(TEST_2007_07_15.isSupported((TemporalField) null), false);
610        assertEquals(TEST_2007_07_15.isSupported(ChronoField.NANO_OF_SECOND), false);
611        assertEquals(TEST_2007_07_15.isSupported(ChronoField.NANO_OF_DAY), false);
612        assertEquals(TEST_2007_07_15.isSupported(ChronoField.MICRO_OF_SECOND), false);
613        assertEquals(TEST_2007_07_15.isSupported(ChronoField.MICRO_OF_DAY), false);
614        assertEquals(TEST_2007_07_15.isSupported(ChronoField.MILLI_OF_SECOND), false);
615        assertEquals(TEST_2007_07_15.isSupported(ChronoField.MILLI_OF_DAY), false);
616        assertEquals(TEST_2007_07_15.isSupported(ChronoField.SECOND_OF_MINUTE), false);
617        assertEquals(TEST_2007_07_15.isSupported(ChronoField.SECOND_OF_DAY), false);
618        assertEquals(TEST_2007_07_15.isSupported(ChronoField.MINUTE_OF_HOUR), false);
619        assertEquals(TEST_2007_07_15.isSupported(ChronoField.MINUTE_OF_DAY), false);
620        assertEquals(TEST_2007_07_15.isSupported(ChronoField.HOUR_OF_AMPM), false);
621        assertEquals(TEST_2007_07_15.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), false);
622        assertEquals(TEST_2007_07_15.isSupported(ChronoField.HOUR_OF_DAY), false);
623        assertEquals(TEST_2007_07_15.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), false);
624        assertEquals(TEST_2007_07_15.isSupported(ChronoField.AMPM_OF_DAY), false);
625        assertEquals(TEST_2007_07_15.isSupported(ChronoField.DAY_OF_WEEK), true);
626        assertEquals(TEST_2007_07_15.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), true);
627        assertEquals(TEST_2007_07_15.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), true);
628        assertEquals(TEST_2007_07_15.isSupported(ChronoField.DAY_OF_MONTH), true);
629        assertEquals(TEST_2007_07_15.isSupported(ChronoField.DAY_OF_YEAR), true);
630        assertEquals(TEST_2007_07_15.isSupported(ChronoField.EPOCH_DAY), true);
631        assertEquals(TEST_2007_07_15.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), true);
632        assertEquals(TEST_2007_07_15.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), true);
633        assertEquals(TEST_2007_07_15.isSupported(ChronoField.MONTH_OF_YEAR), true);
634        assertEquals(TEST_2007_07_15.isSupported(ChronoField.PROLEPTIC_MONTH), true);
635        assertEquals(TEST_2007_07_15.isSupported(ChronoField.YEAR), true);
636        assertEquals(TEST_2007_07_15.isSupported(ChronoField.YEAR_OF_ERA), true);
637        assertEquals(TEST_2007_07_15.isSupported(ChronoField.ERA), true);
638        assertEquals(TEST_2007_07_15.isSupported(ChronoField.INSTANT_SECONDS), false);
639        assertEquals(TEST_2007_07_15.isSupported(ChronoField.OFFSET_SECONDS), false);
640    }
641
642    //-----------------------------------------------------------------------
643    // isSupported(TemporalUnit)
644    //-----------------------------------------------------------------------
645    @Test
646    public void test_isSupported_TemporalUnit() {
647        assertEquals(TEST_2007_07_15.isSupported((TemporalUnit) null), false);
648        assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.NANOS), false);
649        assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.MICROS), false);
650        assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.MILLIS), false);
651        assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.SECONDS), false);
652        assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.MINUTES), false);
653        assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.HOURS), false);
654        assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.HALF_DAYS), false);
655        assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.DAYS), true);
656        assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.WEEKS), true);
657        assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.MONTHS), true);
658        assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.YEARS), true);
659        assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.DECADES), true);
660        assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.CENTURIES), true);
661        assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.MILLENNIA), true);
662        assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.ERAS), true);
663        assertEquals(TEST_2007_07_15.isSupported(ChronoUnit.FOREVER), false);
664    }
665
666    //-----------------------------------------------------------------------
667    // get(TemporalField)
668    //-----------------------------------------------------------------------
669    @Test
670    public void test_get_TemporalField() {
671        LocalDate test = LocalDate.of(2008, 6, 30);
672        assertEquals(test.get(YEAR), 2008);
673        assertEquals(test.get(MONTH_OF_YEAR), 6);
674        assertEquals(test.get(YEAR_OF_ERA), 2008);
675        assertEquals(test.get(ERA), 1);
676        assertEquals(test.get(DAY_OF_MONTH), 30);
677        assertEquals(test.get(DAY_OF_WEEK), 1);
678        assertEquals(test.get(DAY_OF_YEAR), 182);
679    }
680
681    @Test
682    public void test_getLong_TemporalField() {
683        LocalDate test = LocalDate.of(2008, 6, 30);
684        assertEquals(test.getLong(YEAR), 2008);
685        assertEquals(test.getLong(MONTH_OF_YEAR), 6);
686        assertEquals(test.getLong(YEAR_OF_ERA), 2008);
687        assertEquals(test.getLong(ERA), 1);
688        assertEquals(test.getLong(PROLEPTIC_MONTH), 2008 * 12 + 6 - 1);
689        assertEquals(test.getLong(DAY_OF_MONTH), 30);
690        assertEquals(test.getLong(DAY_OF_WEEK), 1);
691        assertEquals(test.getLong(DAY_OF_YEAR), 182);
692    }
693
694    //-----------------------------------------------------------------------
695    // query(TemporalQuery)
696    //-----------------------------------------------------------------------
697    @DataProvider(name="query")
698    Object[][] data_query() {
699        return new Object[][] {
700                {TEST_2007_07_15, TemporalQueries.chronology(), IsoChronology.INSTANCE},
701                {TEST_2007_07_15, TemporalQueries.zoneId(), null},
702                {TEST_2007_07_15, TemporalQueries.precision(), ChronoUnit.DAYS},
703                {TEST_2007_07_15, TemporalQueries.zone(), null},
704                {TEST_2007_07_15, TemporalQueries.offset(), null},
705                {TEST_2007_07_15, TemporalQueries.localDate(), TEST_2007_07_15},
706                {TEST_2007_07_15, TemporalQueries.localTime(), null},
707        };
708    }
709
710    @Test(dataProvider="query")
711    public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
712        assertEquals(temporal.query(query), expected);
713    }
714
715    @Test(dataProvider="query")
716    public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
717        assertEquals(query.queryFrom(temporal), expected);
718    }
719
720    @Test(expectedExceptions=NullPointerException.class)
721    public void test_query_null() {
722        TEST_2007_07_15.query(null);
723    }
724
725    //-----------------------------------------------------------------------
726    // get*()
727    //-----------------------------------------------------------------------
728    @DataProvider(name="sampleDates")
729    Object[][] provider_sampleDates() {
730        return new Object[][] {
731            {2008, 7, 5},
732            {2007, 7, 5},
733            {2006, 7, 5},
734            {2005, 7, 5},
735            {2004, 1, 1},
736            {-1, 1, 2},
737        };
738    }
739
740    //-----------------------------------------------------------------------
741    @Test(dataProvider="sampleDates")
742    public void test_get(int y, int m, int d) {
743        LocalDate a = LocalDate.of(y, m, d);
744        assertEquals(a.getYear(), y);
745        assertEquals(a.getMonth(), Month.of(m));
746        assertEquals(a.getDayOfMonth(), d);
747    }
748
749    @Test(dataProvider="sampleDates")
750    public void test_getDOY(int y, int m, int d) {
751        LocalDate a = LocalDate.of(y, m, d);
752        int total = 0;
753        for (int i = 1; i < m; i++) {
754            total += Month.of(i).length(isIsoLeap(y));
755        }
756        int doy = total + d;
757        assertEquals(a.getDayOfYear(), doy);
758    }
759
760    @Test
761    public void test_getDayOfWeek() {
762        DayOfWeek dow = DayOfWeek.MONDAY;
763        for (Month month : Month.values()) {
764            int length = month.length(false);
765            for (int i = 1; i <= length; i++) {
766                LocalDate d = LocalDate.of(2007, month, i);
767                assertSame(d.getDayOfWeek(), dow);
768                dow = dow.plus(1);
769            }
770        }
771    }
772
773    //-----------------------------------------------------------------------
774    // isLeapYear()
775    //-----------------------------------------------------------------------
776    @Test
777    public void test_isLeapYear() {
778        assertEquals(LocalDate.of(1999, 1, 1).isLeapYear(), false);
779        assertEquals(LocalDate.of(2000, 1, 1).isLeapYear(), true);
780        assertEquals(LocalDate.of(2001, 1, 1).isLeapYear(), false);
781        assertEquals(LocalDate.of(2002, 1, 1).isLeapYear(), false);
782        assertEquals(LocalDate.of(2003, 1, 1).isLeapYear(), false);
783        assertEquals(LocalDate.of(2004, 1, 1).isLeapYear(), true);
784        assertEquals(LocalDate.of(2005, 1, 1).isLeapYear(), false);
785
786        assertEquals(LocalDate.of(1500, 1, 1).isLeapYear(), false);
787        assertEquals(LocalDate.of(1600, 1, 1).isLeapYear(), true);
788        assertEquals(LocalDate.of(1700, 1, 1).isLeapYear(), false);
789        assertEquals(LocalDate.of(1800, 1, 1).isLeapYear(), false);
790        assertEquals(LocalDate.of(1900, 1, 1).isLeapYear(), false);
791    }
792
793    //-----------------------------------------------------------------------
794    // lengthOfMonth()
795    //-----------------------------------------------------------------------
796    @Test
797    public void test_lengthOfMonth_notLeapYear() {
798        assertEquals(LocalDate.of(2007, 1, 1).lengthOfMonth(), 31);
799        assertEquals(LocalDate.of(2007, 2, 1).lengthOfMonth(), 28);
800        assertEquals(LocalDate.of(2007, 3, 1).lengthOfMonth(), 31);
801        assertEquals(LocalDate.of(2007, 4, 1).lengthOfMonth(), 30);
802        assertEquals(LocalDate.of(2007, 5, 1).lengthOfMonth(), 31);
803        assertEquals(LocalDate.of(2007, 6, 1).lengthOfMonth(), 30);
804        assertEquals(LocalDate.of(2007, 7, 1).lengthOfMonth(), 31);
805        assertEquals(LocalDate.of(2007, 8, 1).lengthOfMonth(), 31);
806        assertEquals(LocalDate.of(2007, 9, 1).lengthOfMonth(), 30);
807        assertEquals(LocalDate.of(2007, 10, 1).lengthOfMonth(), 31);
808        assertEquals(LocalDate.of(2007, 11, 1).lengthOfMonth(), 30);
809        assertEquals(LocalDate.of(2007, 12, 1).lengthOfMonth(), 31);
810    }
811
812    @Test
813    public void test_lengthOfMonth_leapYear() {
814        assertEquals(LocalDate.of(2008, 1, 1).lengthOfMonth(), 31);
815        assertEquals(LocalDate.of(2008, 2, 1).lengthOfMonth(), 29);
816        assertEquals(LocalDate.of(2008, 3, 1).lengthOfMonth(), 31);
817        assertEquals(LocalDate.of(2008, 4, 1).lengthOfMonth(), 30);
818        assertEquals(LocalDate.of(2008, 5, 1).lengthOfMonth(), 31);
819        assertEquals(LocalDate.of(2008, 6, 1).lengthOfMonth(), 30);
820        assertEquals(LocalDate.of(2008, 7, 1).lengthOfMonth(), 31);
821        assertEquals(LocalDate.of(2008, 8, 1).lengthOfMonth(), 31);
822        assertEquals(LocalDate.of(2008, 9, 1).lengthOfMonth(), 30);
823        assertEquals(LocalDate.of(2008, 10, 1).lengthOfMonth(), 31);
824        assertEquals(LocalDate.of(2008, 11, 1).lengthOfMonth(), 30);
825        assertEquals(LocalDate.of(2008, 12, 1).lengthOfMonth(), 31);
826    }
827
828    //-----------------------------------------------------------------------
829    // lengthOfYear()
830    //-----------------------------------------------------------------------
831    @Test
832    public void test_lengthOfYear() {
833        assertEquals(LocalDate.of(2007, 1, 1).lengthOfYear(), 365);
834        assertEquals(LocalDate.of(2008, 1, 1).lengthOfYear(), 366);
835    }
836
837    //-----------------------------------------------------------------------
838    // with()
839    //-----------------------------------------------------------------------
840    @Test
841    public void test_with_adjustment() {
842        final LocalDate sample = LocalDate.of(2012, 3, 4);
843        TemporalAdjuster adjuster = new TemporalAdjuster() {
844            @Override
845            public Temporal adjustInto(Temporal dateTime) {
846                return sample;
847            }
848        };
849        assertEquals(TEST_2007_07_15.with(adjuster), sample);
850    }
851
852    @Test(expectedExceptions=NullPointerException.class)
853    public void test_with_adjustment_null() {
854        TEST_2007_07_15.with((TemporalAdjuster) null);
855    }
856
857    //-----------------------------------------------------------------------
858    // with(TemporalField,long)
859    //-----------------------------------------------------------------------
860    @Test
861    public void test_with_TemporalField_long_normal() {
862        LocalDate t = TEST_2007_07_15.with(YEAR, 2008);
863        assertEquals(t, LocalDate.of(2008, 7, 15));
864    }
865
866    @Test(expectedExceptions=NullPointerException.class )
867    public void test_with_TemporalField_long_null() {
868        TEST_2007_07_15.with((TemporalField) null, 1);
869    }
870
871    @Test(expectedExceptions=DateTimeException.class )
872    public void test_with_TemporalField_long_invalidField() {
873        TEST_2007_07_15.with(MockFieldNoValue.INSTANCE, 1);
874    }
875
876    @Test(expectedExceptions=DateTimeException.class )
877    public void test_with_TemporalField_long_timeField() {
878        TEST_2007_07_15.with(ChronoField.AMPM_OF_DAY, 1);
879    }
880
881    @Test(expectedExceptions=DateTimeException.class )
882    public void test_with_TemporalField_long_invalidValue() {
883        TEST_2007_07_15.with(ChronoField.DAY_OF_WEEK, -1);
884    }
885
886    //-----------------------------------------------------------------------
887    // withYear()
888    //-----------------------------------------------------------------------
889    @Test
890    public void test_withYear_int_normal() {
891        LocalDate t = TEST_2007_07_15.withYear(2008);
892        assertEquals(t, LocalDate.of(2008, 7, 15));
893    }
894
895    @Test(expectedExceptions=DateTimeException.class)
896    public void test_withYear_int_invalid() {
897        TEST_2007_07_15.withYear(Year.MIN_VALUE - 1);
898    }
899
900    @Test
901    public void test_withYear_int_adjustDay() {
902        LocalDate t = LocalDate.of(2008, 2, 29).withYear(2007);
903        LocalDate expected = LocalDate.of(2007, 2, 28);
904        assertEquals(t, expected);
905    }
906
907    //-----------------------------------------------------------------------
908    // withMonth()
909    //-----------------------------------------------------------------------
910    @Test
911    public void test_withMonth_int_normal() {
912        LocalDate t = TEST_2007_07_15.withMonth(1);
913        assertEquals(t, LocalDate.of(2007, 1, 15));
914    }
915
916    @Test(expectedExceptions=DateTimeException.class)
917    public void test_withMonth_int_invalid() {
918        TEST_2007_07_15.withMonth(13);
919    }
920
921    @Test
922    public void test_withMonth_int_adjustDay() {
923        LocalDate t = LocalDate.of(2007, 12, 31).withMonth(11);
924        LocalDate expected = LocalDate.of(2007, 11, 30);
925        assertEquals(t, expected);
926    }
927
928    //-----------------------------------------------------------------------
929    // withDayOfMonth()
930    //-----------------------------------------------------------------------
931    @Test
932    public void test_withDayOfMonth_normal() {
933        LocalDate t = TEST_2007_07_15.withDayOfMonth(1);
934        assertEquals(t, LocalDate.of(2007, 7, 1));
935    }
936
937    @Test(expectedExceptions=DateTimeException.class)
938    public void test_withDayOfMonth_illegal() {
939        TEST_2007_07_15.withDayOfMonth(32);
940    }
941
942    @Test(expectedExceptions=DateTimeException.class)
943    public void test_withDayOfMonth_invalid() {
944        LocalDate.of(2007, 11, 30).withDayOfMonth(31);
945    }
946
947    //-----------------------------------------------------------------------
948    // withDayOfYear(int)
949    //-----------------------------------------------------------------------
950    @Test
951    public void test_withDayOfYear_normal() {
952        LocalDate t = TEST_2007_07_15.withDayOfYear(33);
953        assertEquals(t, LocalDate.of(2007, 2, 2));
954    }
955
956    @Test(expectedExceptions=DateTimeException.class)
957    public void test_withDayOfYear_illegal() {
958        TEST_2007_07_15.withDayOfYear(367);
959    }
960
961    @Test(expectedExceptions=DateTimeException.class)
962    public void test_withDayOfYear_invalid() {
963        TEST_2007_07_15.withDayOfYear(366);
964    }
965
966    //-----------------------------------------------------------------------
967    // plus(Period)
968    //-----------------------------------------------------------------------
969    @Test
970    public void test_plus_Period_positiveMonths() {
971        MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
972        LocalDate t = TEST_2007_07_15.plus(period);
973        assertEquals(t, LocalDate.of(2008, 2, 15));
974    }
975
976    @Test
977    public void test_plus_Period_negativeDays() {
978        MockSimplePeriod period = MockSimplePeriod.of(-25, ChronoUnit.DAYS);
979        LocalDate t = TEST_2007_07_15.plus(period);
980        assertEquals(t, LocalDate.of(2007, 6, 20));
981    }
982
983    @Test(expectedExceptions=DateTimeException.class)
984    public void test_plus_Period_timeNotAllowed() {
985        MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.HOURS);
986        TEST_2007_07_15.plus(period);
987    }
988
989    @Test(expectedExceptions=NullPointerException.class)
990    public void test_plus_Period_null() {
991        TEST_2007_07_15.plus((MockSimplePeriod) null);
992    }
993
994    @Test(expectedExceptions=DateTimeException.class)
995    public void test_plus_Period_invalidTooLarge() {
996        MockSimplePeriod period = MockSimplePeriod.of(1, ChronoUnit.YEARS);
997        LocalDate.of(Year.MAX_VALUE, 1, 1).plus(period);
998    }
999
1000    @Test(expectedExceptions=DateTimeException.class)
1001    public void test_plus_Period_invalidTooSmall() {
1002        MockSimplePeriod period = MockSimplePeriod.of(-1, ChronoUnit.YEARS);
1003        LocalDate.of(Year.MIN_VALUE, 1, 1).plus(period);
1004    }
1005
1006    //-----------------------------------------------------------------------
1007    // plus(long,TemporalUnit)
1008    //-----------------------------------------------------------------------
1009    @Test
1010    public void test_plus_longTemporalUnit_positiveMonths() {
1011        LocalDate t = TEST_2007_07_15.plus(7, ChronoUnit.MONTHS);
1012        assertEquals(t, LocalDate.of(2008, 2, 15));
1013    }
1014
1015    @Test
1016    public void test_plus_longTemporalUnit_negativeDays() {
1017        LocalDate t = TEST_2007_07_15.plus(-25, ChronoUnit.DAYS);
1018        assertEquals(t, LocalDate.of(2007, 6, 20));
1019    }
1020
1021    @Test(expectedExceptions=DateTimeException.class)
1022    public void test_plus_longTemporalUnit_timeNotAllowed() {
1023        TEST_2007_07_15.plus(7, ChronoUnit.HOURS);
1024    }
1025
1026    @Test(expectedExceptions=NullPointerException.class)
1027    public void test_plus_longTemporalUnit_null() {
1028        TEST_2007_07_15.plus(1, (TemporalUnit) null);
1029    }
1030
1031    @Test(expectedExceptions=DateTimeException.class)
1032    public void test_plus_longTemporalUnit_invalidTooLarge() {
1033        LocalDate.of(Year.MAX_VALUE, 1, 1).plus(1, ChronoUnit.YEARS);
1034    }
1035
1036    @Test(expectedExceptions=DateTimeException.class)
1037    public void test_plus_longTemporalUnit_invalidTooSmall() {
1038        LocalDate.of(Year.MIN_VALUE, 1, 1).plus(-1, ChronoUnit.YEARS);
1039    }
1040
1041    //-----------------------------------------------------------------------
1042    // plusYears()
1043    //-----------------------------------------------------------------------
1044    @Test
1045    public void test_plusYears_long_normal() {
1046        LocalDate t = TEST_2007_07_15.plusYears(1);
1047        assertEquals(t, LocalDate.of(2008, 7, 15));
1048    }
1049
1050    @Test
1051    public void test_plusYears_long_negative() {
1052        LocalDate t = TEST_2007_07_15.plusYears(-1);
1053        assertEquals(t, LocalDate.of(2006, 7, 15));
1054    }
1055
1056    @Test
1057    public void test_plusYears_long_adjustDay() {
1058        LocalDate t = LocalDate.of(2008, 2, 29).plusYears(1);
1059        LocalDate expected = LocalDate.of(2009, 2, 28);
1060        assertEquals(t, expected);
1061    }
1062
1063    @Test
1064    public void test_plusYears_long_big() {
1065        long years = 20L + Year.MAX_VALUE;
1066        LocalDate test = LocalDate.of(-40, 6, 1).plusYears(years);
1067        assertEquals(test, LocalDate.of((int) (-40L + years), 6, 1));
1068    }
1069
1070    @Test(expectedExceptions=DateTimeException.class)
1071    public void test_plusYears_long_invalidTooLarge() {
1072        LocalDate test = LocalDate.of(Year.MAX_VALUE, 6, 1);
1073        test.plusYears(1);
1074    }
1075
1076    @Test(expectedExceptions=DateTimeException.class)
1077    public void test_plusYears_long_invalidTooLargeMaxAddMax() {
1078        LocalDate test = LocalDate.of(Year.MAX_VALUE, 12, 1);
1079        test.plusYears(Long.MAX_VALUE);
1080    }
1081
1082    @Test(expectedExceptions=DateTimeException.class)
1083    public void test_plusYears_long_invalidTooLargeMaxAddMin() {
1084        LocalDate test = LocalDate.of(Year.MAX_VALUE, 12, 1);
1085        test.plusYears(Long.MIN_VALUE);
1086    }
1087
1088    @Test(expectedExceptions=DateTimeException.class)
1089    public void test_plusYears_long_invalidTooSmall_validInt() {
1090        LocalDate.of(Year.MIN_VALUE, 1, 1).plusYears(-1);
1091    }
1092
1093    @Test(expectedExceptions=DateTimeException.class)
1094    public void test_plusYears_long_invalidTooSmall_invalidInt() {
1095        LocalDate.of(Year.MIN_VALUE, 1, 1).plusYears(-10);
1096    }
1097
1098    //-----------------------------------------------------------------------
1099    // plusMonths()
1100    //-----------------------------------------------------------------------
1101    @Test
1102    public void test_plusMonths_long_normal() {
1103        LocalDate t = TEST_2007_07_15.plusMonths(1);
1104        assertEquals(t, LocalDate.of(2007, 8, 15));
1105    }
1106
1107    @Test
1108    public void test_plusMonths_long_overYears() {
1109        LocalDate t = TEST_2007_07_15.plusMonths(25);
1110        assertEquals(t, LocalDate.of(2009, 8, 15));
1111    }
1112
1113    @Test
1114    public void test_plusMonths_long_negative() {
1115        LocalDate t = TEST_2007_07_15.plusMonths(-1);
1116        assertEquals(t, LocalDate.of(2007, 6, 15));
1117    }
1118
1119    @Test
1120    public void test_plusMonths_long_negativeAcrossYear() {
1121        LocalDate t = TEST_2007_07_15.plusMonths(-7);
1122        assertEquals(t, LocalDate.of(2006, 12, 15));
1123    }
1124
1125    @Test
1126    public void test_plusMonths_long_negativeOverYears() {
1127        LocalDate t = TEST_2007_07_15.plusMonths(-31);
1128        assertEquals(t, LocalDate.of(2004, 12, 15));
1129    }
1130
1131    @Test
1132    public void test_plusMonths_long_adjustDayFromLeapYear() {
1133        LocalDate t = LocalDate.of(2008, 2, 29).plusMonths(12);
1134        LocalDate expected = LocalDate.of(2009, 2, 28);
1135        assertEquals(t, expected);
1136    }
1137
1138    @Test
1139    public void test_plusMonths_long_adjustDayFromMonthLength() {
1140        LocalDate t = LocalDate.of(2007, 3, 31).plusMonths(1);
1141        LocalDate expected = LocalDate.of(2007, 4, 30);
1142        assertEquals(t, expected);
1143    }
1144
1145    @Test
1146    public void test_plusMonths_long_big() {
1147        long months = 20L + Integer.MAX_VALUE;
1148        LocalDate test = LocalDate.of(-40, 6, 1).plusMonths(months);
1149        assertEquals(test, LocalDate.of((int) (-40L + months / 12), 6 + (int) (months % 12), 1));
1150    }
1151
1152    @Test(expectedExceptions={DateTimeException.class})
1153    public void test_plusMonths_long_invalidTooLarge() {
1154        LocalDate.of(Year.MAX_VALUE, 12, 1).plusMonths(1);
1155    }
1156
1157    @Test(expectedExceptions=DateTimeException.class)
1158    public void test_plusMonths_long_invalidTooLargeMaxAddMax() {
1159        LocalDate test = LocalDate.of(Year.MAX_VALUE, 12, 1);
1160        test.plusMonths(Long.MAX_VALUE);
1161    }
1162
1163    @Test(expectedExceptions=DateTimeException.class)
1164    public void test_plusMonths_long_invalidTooLargeMaxAddMin() {
1165        LocalDate test = LocalDate.of(Year.MAX_VALUE, 12, 1);
1166        test.plusMonths(Long.MIN_VALUE);
1167    }
1168
1169    @Test(expectedExceptions={DateTimeException.class})
1170    public void test_plusMonths_long_invalidTooSmall() {
1171        LocalDate.of(Year.MIN_VALUE, 1, 1).plusMonths(-1);
1172    }
1173
1174    @Test
1175    public void test_plusWeeks_normal() {
1176        LocalDate t = TEST_2007_07_15.plusWeeks(1);
1177        assertEquals(t, LocalDate.of(2007, 7, 22));
1178    }
1179
1180    @Test
1181    public void test_plusWeeks_overMonths() {
1182        LocalDate t = TEST_2007_07_15.plusWeeks(9);
1183        assertEquals(t, LocalDate.of(2007, 9, 16));
1184    }
1185
1186    @Test
1187    public void test_plusWeeks_overYears() {
1188        LocalDate t = LocalDate.of(2006, 7, 16).plusWeeks(52);
1189        assertEquals(t, TEST_2007_07_15);
1190    }
1191
1192    @Test
1193    public void test_plusWeeks_overLeapYears() {
1194        LocalDate t = TEST_2007_07_15.plusYears(-1).plusWeeks(104);
1195        assertEquals(t, LocalDate.of(2008, 7, 12));
1196    }
1197
1198    @Test
1199    public void test_plusWeeks_negative() {
1200        LocalDate t = TEST_2007_07_15.plusWeeks(-1);
1201        assertEquals(t, LocalDate.of(2007, 7, 8));
1202    }
1203
1204    @Test
1205    public void test_plusWeeks_negativeAcrossYear() {
1206        LocalDate t = TEST_2007_07_15.plusWeeks(-28);
1207        assertEquals(t, LocalDate.of(2006, 12, 31));
1208    }
1209
1210    @Test
1211    public void test_plusWeeks_negativeOverYears() {
1212        LocalDate t = TEST_2007_07_15.plusWeeks(-104);
1213        assertEquals(t, LocalDate.of(2005, 7, 17));
1214    }
1215
1216    @Test
1217    public void test_plusWeeks_maximum() {
1218        LocalDate t = LocalDate.of(Year.MAX_VALUE, 12, 24).plusWeeks(1);
1219        LocalDate expected = LocalDate.of(Year.MAX_VALUE, 12, 31);
1220        assertEquals(t, expected);
1221    }
1222
1223    @Test
1224    public void test_plusWeeks_minimum() {
1225        LocalDate t = LocalDate.of(Year.MIN_VALUE, 1, 8).plusWeeks(-1);
1226        LocalDate expected = LocalDate.of(Year.MIN_VALUE, 1, 1);
1227        assertEquals(t, expected);
1228    }
1229
1230    @Test(expectedExceptions={DateTimeException.class})
1231    public void test_plusWeeks_invalidTooLarge() {
1232        LocalDate.of(Year.MAX_VALUE, 12, 25).plusWeeks(1);
1233    }
1234
1235    @Test(expectedExceptions={DateTimeException.class})
1236    public void test_plusWeeks_invalidTooSmall() {
1237        LocalDate.of(Year.MIN_VALUE, 1, 7).plusWeeks(-1);
1238    }
1239
1240    @Test(expectedExceptions={ArithmeticException.class})
1241    public void test_plusWeeks_invalidMaxMinusMax() {
1242        LocalDate.of(Year.MAX_VALUE, 12, 25).plusWeeks(Long.MAX_VALUE);
1243    }
1244
1245    @Test(expectedExceptions={ArithmeticException.class})
1246    public void test_plusWeeks_invalidMaxMinusMin() {
1247        LocalDate.of(Year.MAX_VALUE, 12, 25).plusWeeks(Long.MIN_VALUE);
1248    }
1249
1250    @Test
1251    public void test_plusDays_normal() {
1252        LocalDate t = TEST_2007_07_15.plusDays(1);
1253        assertEquals(t, LocalDate.of(2007, 7, 16));
1254    }
1255
1256    @Test
1257    public void test_plusDays_overMonths() {
1258        LocalDate t = TEST_2007_07_15.plusDays(62);
1259        assertEquals(t, LocalDate.of(2007, 9, 15));
1260    }
1261
1262    @Test
1263    public void test_plusDays_overYears() {
1264        LocalDate t = LocalDate.of(2006, 7, 14).plusDays(366);
1265        assertEquals(t, TEST_2007_07_15);
1266    }
1267
1268    @Test
1269    public void test_plusDays_overLeapYears() {
1270        LocalDate t = TEST_2007_07_15.plusYears(-1).plusDays(365 + 366);
1271        assertEquals(t, LocalDate.of(2008, 7, 15));
1272    }
1273
1274    @Test
1275    public void test_plusDays_negative() {
1276        LocalDate t = TEST_2007_07_15.plusDays(-1);
1277        assertEquals(t, LocalDate.of(2007, 7, 14));
1278    }
1279
1280    @Test
1281    public void test_plusDays_negativeAcrossYear() {
1282        LocalDate t = TEST_2007_07_15.plusDays(-196);
1283        assertEquals(t, LocalDate.of(2006, 12, 31));
1284    }
1285
1286    @Test
1287    public void test_plusDays_negativeOverYears() {
1288        LocalDate t = TEST_2007_07_15.plusDays(-730);
1289        assertEquals(t, LocalDate.of(2005, 7, 15));
1290    }
1291
1292    @Test
1293    public void test_plusDays_maximum() {
1294        LocalDate t = LocalDate.of(Year.MAX_VALUE, 12, 30).plusDays(1);
1295        LocalDate expected = LocalDate.of(Year.MAX_VALUE, 12, 31);
1296        assertEquals(t, expected);
1297    }
1298
1299    @Test
1300    public void test_plusDays_minimum() {
1301        LocalDate t = LocalDate.of(Year.MIN_VALUE, 1, 2).plusDays(-1);
1302        LocalDate expected = LocalDate.of(Year.MIN_VALUE, 1, 1);
1303        assertEquals(t, expected);
1304    }
1305
1306    @Test(expectedExceptions={DateTimeException.class})
1307    public void test_plusDays_invalidTooLarge() {
1308        LocalDate.of(Year.MAX_VALUE, 12, 31).plusDays(1);
1309    }
1310
1311    @Test(expectedExceptions={DateTimeException.class})
1312    public void test_plusDays_invalidTooSmall() {
1313        LocalDate.of(Year.MIN_VALUE, 1, 1).plusDays(-1);
1314    }
1315
1316    @Test(expectedExceptions=ArithmeticException.class)
1317    public void test_plusDays_overflowTooLarge() {
1318        LocalDate.of(Year.MAX_VALUE, 12, 31).plusDays(Long.MAX_VALUE);
1319    }
1320
1321    @Test(expectedExceptions=ArithmeticException.class)
1322    public void test_plusDays_overflowTooSmall() {
1323        LocalDate.of(Year.MIN_VALUE, 1, 1).plusDays(Long.MIN_VALUE);
1324    }
1325
1326    //-----------------------------------------------------------------------
1327    // minus(Period)
1328    //-----------------------------------------------------------------------
1329    @Test
1330    public void test_minus_Period_positiveMonths() {
1331        MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
1332        LocalDate t = TEST_2007_07_15.minus(period);
1333        assertEquals(t, LocalDate.of(2006, 12, 15));
1334    }
1335
1336    @Test
1337    public void test_minus_Period_negativeDays() {
1338        MockSimplePeriod period = MockSimplePeriod.of(-25, ChronoUnit.DAYS);
1339        LocalDate t = TEST_2007_07_15.minus(period);
1340        assertEquals(t, LocalDate.of(2007, 8, 9));
1341    }
1342
1343    @Test(expectedExceptions=DateTimeException.class)
1344    public void test_minus_Period_timeNotAllowed() {
1345        MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.HOURS);
1346        TEST_2007_07_15.minus(period);
1347    }
1348
1349    @Test(expectedExceptions=NullPointerException.class)
1350    public void test_minus_Period_null() {
1351        TEST_2007_07_15.minus((MockSimplePeriod) null);
1352    }
1353
1354    @Test(expectedExceptions=DateTimeException.class)
1355    public void test_minus_Period_invalidTooLarge() {
1356        MockSimplePeriod period = MockSimplePeriod.of(-1, ChronoUnit.YEARS);
1357        LocalDate.of(Year.MAX_VALUE, 1, 1).minus(period);
1358    }
1359
1360    @Test(expectedExceptions=DateTimeException.class)
1361    public void test_minus_Period_invalidTooSmall() {
1362        MockSimplePeriod period = MockSimplePeriod.of(1, ChronoUnit.YEARS);
1363        LocalDate.of(Year.MIN_VALUE, 1, 1).minus(period);
1364    }
1365
1366    //-----------------------------------------------------------------------
1367    // minus(long,TemporalUnit)
1368    //-----------------------------------------------------------------------
1369    @Test
1370    public void test_minus_longTemporalUnit_positiveMonths() {
1371        LocalDate t = TEST_2007_07_15.minus(7, ChronoUnit.MONTHS);
1372        assertEquals(t, LocalDate.of(2006, 12, 15));
1373    }
1374
1375    @Test
1376    public void test_minus_longTemporalUnit_negativeDays() {
1377        LocalDate t = TEST_2007_07_15.minus(-25, ChronoUnit.DAYS);
1378        assertEquals(t, LocalDate.of(2007, 8, 9));
1379    }
1380
1381    @Test(expectedExceptions=DateTimeException.class)
1382    public void test_minus_longTemporalUnit_timeNotAllowed() {
1383        TEST_2007_07_15.minus(7, ChronoUnit.HOURS);
1384    }
1385
1386    @Test(expectedExceptions=NullPointerException.class)
1387    public void test_minus_longTemporalUnit_null() {
1388        TEST_2007_07_15.minus(1, (TemporalUnit) null);
1389    }
1390
1391    @Test(expectedExceptions=DateTimeException.class)
1392    public void test_minus_longTemporalUnit_invalidTooLarge() {
1393        LocalDate.of(Year.MAX_VALUE, 1, 1).minus(-1, ChronoUnit.YEARS);
1394    }
1395
1396    @Test(expectedExceptions=DateTimeException.class)
1397    public void test_minus_longTemporalUnit_invalidTooSmall() {
1398        LocalDate.of(Year.MIN_VALUE, 1, 1).minus(1, ChronoUnit.YEARS);
1399    }
1400
1401    //-----------------------------------------------------------------------
1402    // minusYears()
1403    //-----------------------------------------------------------------------
1404    @Test
1405    public void test_minusYears_long_normal() {
1406        LocalDate t = TEST_2007_07_15.minusYears(1);
1407        assertEquals(t, LocalDate.of(2006, 7, 15));
1408    }
1409
1410    @Test
1411    public void test_minusYears_long_negative() {
1412        LocalDate t = TEST_2007_07_15.minusYears(-1);
1413        assertEquals(t, LocalDate.of(2008, 7, 15));
1414    }
1415
1416    @Test
1417    public void test_minusYears_long_adjustDay() {
1418        LocalDate t = LocalDate.of(2008, 2, 29).minusYears(1);
1419        LocalDate expected = LocalDate.of(2007, 2, 28);
1420        assertEquals(t, expected);
1421    }
1422
1423    @Test
1424    public void test_minusYears_long_big() {
1425        long years = 20L + Year.MAX_VALUE;
1426        LocalDate test = LocalDate.of(40, 6, 1).minusYears(years);
1427        assertEquals(test, LocalDate.of((int) (40L - years), 6, 1));
1428    }
1429
1430    @Test(expectedExceptions=DateTimeException.class)
1431    public void test_minusYears_long_invalidTooLarge() {
1432        LocalDate test = LocalDate.of(Year.MAX_VALUE, 6, 1);
1433        test.minusYears(-1);
1434    }
1435
1436    @Test(expectedExceptions=DateTimeException.class)
1437    public void test_minusYears_long_invalidTooLargeMaxAddMax() {
1438        LocalDate test = LocalDate.of(Year.MAX_VALUE, 12, 1);
1439        test.minusYears(Long.MAX_VALUE);
1440    }
1441
1442    @Test(expectedExceptions=DateTimeException.class)
1443    public void test_minusYears_long_invalidTooLargeMaxAddMin() {
1444        LocalDate test = LocalDate.of(Year.MAX_VALUE, 12, 1);
1445        test.minusYears(Long.MIN_VALUE);
1446    }
1447
1448    @Test(expectedExceptions=DateTimeException.class)
1449    public void test_minusYears_long_invalidTooSmall() {
1450        LocalDate.of(Year.MIN_VALUE, 1, 1).minusYears(1);
1451    }
1452
1453    //-----------------------------------------------------------------------
1454    // minusMonths()
1455    //-----------------------------------------------------------------------
1456    @Test
1457    public void test_minusMonths_long_normal() {
1458        LocalDate t = TEST_2007_07_15.minusMonths(1);
1459        assertEquals(t, LocalDate.of(2007, 6, 15));
1460    }
1461
1462    @Test
1463    public void test_minusMonths_long_overYears() {
1464        LocalDate t = TEST_2007_07_15.minusMonths(25);
1465        assertEquals(t, LocalDate.of(2005, 6, 15));
1466    }
1467
1468    @Test
1469    public void test_minusMonths_long_negative() {
1470        LocalDate t = TEST_2007_07_15.minusMonths(-1);
1471        assertEquals(t, LocalDate.of(2007, 8, 15));
1472    }
1473
1474    @Test
1475    public void test_minusMonths_long_negativeAcrossYear() {
1476        LocalDate t = TEST_2007_07_15.minusMonths(-7);
1477        assertEquals(t, LocalDate.of(2008, 2, 15));
1478    }
1479
1480    @Test
1481    public void test_minusMonths_long_negativeOverYears() {
1482        LocalDate t = TEST_2007_07_15.minusMonths(-31);
1483        assertEquals(t, LocalDate.of(2010, 2, 15));
1484    }
1485
1486    @Test
1487    public void test_minusMonths_long_adjustDayFromLeapYear() {
1488        LocalDate t = LocalDate.of(2008, 2, 29).minusMonths(12);
1489        LocalDate expected = LocalDate.of(2007, 2, 28);
1490        assertEquals(t, expected);
1491    }
1492
1493    @Test
1494    public void test_minusMonths_long_adjustDayFromMonthLength() {
1495        LocalDate t = LocalDate.of(2007, 3, 31).minusMonths(1);
1496        LocalDate expected = LocalDate.of(2007, 2, 28);
1497        assertEquals(t, expected);
1498    }
1499
1500    @Test
1501    public void test_minusMonths_long_big() {
1502        long months = 20L + Integer.MAX_VALUE;
1503        LocalDate test = LocalDate.of(40, 6, 1).minusMonths(months);
1504        assertEquals(test, LocalDate.of((int) (40L - months / 12), 6 - (int) (months % 12), 1));
1505    }
1506
1507    @Test(expectedExceptions={DateTimeException.class})
1508    public void test_minusMonths_long_invalidTooLarge() {
1509        LocalDate.of(Year.MAX_VALUE, 12, 1).minusMonths(-1);
1510    }
1511
1512    @Test(expectedExceptions=DateTimeException.class)
1513    public void test_minusMonths_long_invalidTooLargeMaxAddMax() {
1514        LocalDate test = LocalDate.of(Year.MAX_VALUE, 12, 1);
1515        test.minusMonths(Long.MAX_VALUE);
1516    }
1517
1518    @Test(expectedExceptions=DateTimeException.class)
1519    public void test_minusMonths_long_invalidTooLargeMaxAddMin() {
1520        LocalDate test = LocalDate.of(Year.MAX_VALUE, 12, 1);
1521        test.minusMonths(Long.MIN_VALUE);
1522    }
1523
1524    @Test(expectedExceptions={DateTimeException.class})
1525    public void test_minusMonths_long_invalidTooSmall() {
1526        LocalDate.of(Year.MIN_VALUE, 1, 1).minusMonths(1);
1527    }
1528
1529    @Test
1530    public void test_minusWeeks_normal() {
1531        LocalDate t = TEST_2007_07_15.minusWeeks(1);
1532        assertEquals(t, LocalDate.of(2007, 7, 8));
1533    }
1534
1535    @Test
1536    public void test_minusWeeks_overMonths() {
1537        LocalDate t = TEST_2007_07_15.minusWeeks(9);
1538        assertEquals(t, LocalDate.of(2007, 5, 13));
1539    }
1540
1541    @Test
1542    public void test_minusWeeks_overYears() {
1543        LocalDate t = LocalDate.of(2008, 7, 13).minusWeeks(52);
1544        assertEquals(t, TEST_2007_07_15);
1545    }
1546
1547    @Test
1548    public void test_minusWeeks_overLeapYears() {
1549        LocalDate t = TEST_2007_07_15.minusYears(-1).minusWeeks(104);
1550        assertEquals(t, LocalDate.of(2006, 7, 18));
1551    }
1552
1553    @Test
1554    public void test_minusWeeks_negative() {
1555        LocalDate t = TEST_2007_07_15.minusWeeks(-1);
1556        assertEquals(t, LocalDate.of(2007, 7, 22));
1557    }
1558
1559    @Test
1560    public void test_minusWeeks_negativeAcrossYear() {
1561        LocalDate t = TEST_2007_07_15.minusWeeks(-28);
1562        assertEquals(t, LocalDate.of(2008, 1, 27));
1563    }
1564
1565    @Test
1566    public void test_minusWeeks_negativeOverYears() {
1567        LocalDate t = TEST_2007_07_15.minusWeeks(-104);
1568        assertEquals(t, LocalDate.of(2009, 7, 12));
1569    }
1570
1571    @Test
1572    public void test_minusWeeks_maximum() {
1573        LocalDate t = LocalDate.of(Year.MAX_VALUE, 12, 24).minusWeeks(-1);
1574        LocalDate expected = LocalDate.of(Year.MAX_VALUE, 12, 31);
1575        assertEquals(t, expected);
1576    }
1577
1578    @Test
1579    public void test_minusWeeks_minimum() {
1580        LocalDate t = LocalDate.of(Year.MIN_VALUE, 1, 8).minusWeeks(1);
1581        LocalDate expected = LocalDate.of(Year.MIN_VALUE, 1, 1);
1582        assertEquals(t, expected);
1583    }
1584
1585    @Test(expectedExceptions={DateTimeException.class})
1586    public void test_minusWeeks_invalidTooLarge() {
1587        LocalDate.of(Year.MAX_VALUE, 12, 25).minusWeeks(-1);
1588    }
1589
1590    @Test(expectedExceptions={DateTimeException.class})
1591    public void test_minusWeeks_invalidTooSmall() {
1592        LocalDate.of(Year.MIN_VALUE, 1, 7).minusWeeks(1);
1593    }
1594
1595    @Test(expectedExceptions={ArithmeticException.class})
1596    public void test_minusWeeks_invalidMaxMinusMax() {
1597        LocalDate.of(Year.MAX_VALUE, 12, 25).minusWeeks(Long.MAX_VALUE);
1598    }
1599
1600    @Test(expectedExceptions={ArithmeticException.class})
1601    public void test_minusWeeks_invalidMaxMinusMin() {
1602        LocalDate.of(Year.MAX_VALUE, 12, 25).minusWeeks(Long.MIN_VALUE);
1603    }
1604
1605    @Test
1606    public void test_minusDays_normal() {
1607        LocalDate t = TEST_2007_07_15.minusDays(1);
1608        assertEquals(t, LocalDate.of(2007, 7, 14));
1609    }
1610
1611    @Test
1612    public void test_minusDays_overMonths() {
1613        LocalDate t = TEST_2007_07_15.minusDays(62);
1614        assertEquals(t, LocalDate.of(2007, 5, 14));
1615    }
1616
1617    @Test
1618    public void test_minusDays_overYears() {
1619        LocalDate t = LocalDate.of(2008, 7, 16).minusDays(367);
1620        assertEquals(t, TEST_2007_07_15);
1621    }
1622
1623    @Test
1624    public void test_minusDays_overLeapYears() {
1625        LocalDate t = TEST_2007_07_15.plusYears(2).minusDays(365 + 366);
1626        assertEquals(t, TEST_2007_07_15);
1627    }
1628
1629    @Test
1630    public void test_minusDays_negative() {
1631        LocalDate t = TEST_2007_07_15.minusDays(-1);
1632        assertEquals(t, LocalDate.of(2007, 7, 16));
1633    }
1634
1635    @Test
1636    public void test_minusDays_negativeAcrossYear() {
1637        LocalDate t = TEST_2007_07_15.minusDays(-169);
1638        assertEquals(t, LocalDate.of(2007, 12, 31));
1639    }
1640
1641    @Test
1642    public void test_minusDays_negativeOverYears() {
1643        LocalDate t = TEST_2007_07_15.minusDays(-731);
1644        assertEquals(t, LocalDate.of(2009, 7, 15));
1645    }
1646
1647    @Test
1648    public void test_minusDays_maximum() {
1649        LocalDate t = LocalDate.of(Year.MAX_VALUE, 12, 30).minusDays(-1);
1650        LocalDate expected = LocalDate.of(Year.MAX_VALUE, 12, 31);
1651        assertEquals(t, expected);
1652    }
1653
1654    @Test
1655    public void test_minusDays_minimum() {
1656        LocalDate t = LocalDate.of(Year.MIN_VALUE, 1, 2).minusDays(1);
1657        LocalDate expected = LocalDate.of(Year.MIN_VALUE, 1, 1);
1658        assertEquals(t, expected);
1659    }
1660
1661    @Test(expectedExceptions={DateTimeException.class})
1662    public void test_minusDays_invalidTooLarge() {
1663        LocalDate.of(Year.MAX_VALUE, 12, 31).minusDays(-1);
1664    }
1665
1666    @Test(expectedExceptions={DateTimeException.class})
1667    public void test_minusDays_invalidTooSmall() {
1668        LocalDate.of(Year.MIN_VALUE, 1, 1).minusDays(1);
1669    }
1670
1671    @Test(expectedExceptions=ArithmeticException.class)
1672    public void test_minusDays_overflowTooLarge() {
1673        LocalDate.of(Year.MAX_VALUE, 12, 31).minusDays(Long.MIN_VALUE);
1674    }
1675
1676    @Test(expectedExceptions=ArithmeticException.class)
1677    public void test_minusDays_overflowTooSmall() {
1678        LocalDate.of(Year.MIN_VALUE, 1, 1).minusDays(Long.MAX_VALUE);
1679    }
1680
1681    //-----------------------------------------------------------------------
1682    // until(Temporal, TemporalUnit)
1683    //-----------------------------------------------------------------------
1684    @DataProvider(name="periodUntilUnit")
1685    Object[][] data_periodUntilUnit() {
1686        return new Object[][] {
1687                {date(2000, 1, 1), date(2000, 1, 1), DAYS, 0},
1688                {date(2000, 1, 1), date(2000, 1, 1), WEEKS, 0},
1689                {date(2000, 1, 1), date(2000, 1, 1), MONTHS, 0},
1690                {date(2000, 1, 1), date(2000, 1, 1), YEARS, 0},
1691                {date(2000, 1, 1), date(2000, 1, 1), DECADES, 0},
1692                {date(2000, 1, 1), date(2000, 1, 1), CENTURIES, 0},
1693                {date(2000, 1, 1), date(2000, 1, 1), MILLENNIA, 0},
1694
1695                {date(2000, 1, 15), date(2000, 2, 14), DAYS, 30},
1696                {date(2000, 1, 15), date(2000, 2, 15), DAYS, 31},
1697                {date(2000, 1, 15), date(2000, 2, 16), DAYS, 32},
1698
1699                {date(2000, 1, 15), date(2000, 2, 17), WEEKS, 4},
1700                {date(2000, 1, 15), date(2000, 2, 18), WEEKS, 4},
1701                {date(2000, 1, 15), date(2000, 2, 19), WEEKS, 5},
1702                {date(2000, 1, 15), date(2000, 2, 20), WEEKS, 5},
1703
1704                {date(2000, 1, 15), date(2000, 2, 14), MONTHS, 0},
1705                {date(2000, 1, 15), date(2000, 2, 15), MONTHS, 1},
1706                {date(2000, 1, 15), date(2000, 2, 16), MONTHS, 1},
1707                {date(2000, 1, 15), date(2000, 3, 14), MONTHS, 1},
1708                {date(2000, 1, 15), date(2000, 3, 15), MONTHS, 2},
1709                {date(2000, 1, 15), date(2000, 3, 16), MONTHS, 2},
1710
1711                {date(2000, 1, 15), date(2001, 1, 14), YEARS, 0},
1712                {date(2000, 1, 15), date(2001, 1, 15), YEARS, 1},
1713                {date(2000, 1, 15), date(2001, 1, 16), YEARS, 1},
1714                {date(2000, 1, 15), date(2004, 1, 14), YEARS, 3},
1715                {date(2000, 1, 15), date(2004, 1, 15), YEARS, 4},
1716                {date(2000, 1, 15), date(2004, 1, 16), YEARS, 4},
1717
1718                {date(2000, 1, 15), date(2010, 1, 14), DECADES, 0},
1719                {date(2000, 1, 15), date(2010, 1, 15), DECADES, 1},
1720
1721                {date(2000, 1, 15), date(2100, 1, 14), CENTURIES, 0},
1722                {date(2000, 1, 15), date(2100, 1, 15), CENTURIES, 1},
1723
1724                {date(2000, 1, 15), date(3000, 1, 14), MILLENNIA, 0},
1725                {date(2000, 1, 15), date(3000, 1, 15), MILLENNIA, 1},
1726        };
1727    }
1728
1729    @Test(dataProvider="periodUntilUnit")
1730    public void test_until_TemporalUnit(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) {
1731        long amount = date1.until(date2, unit);
1732        assertEquals(amount, expected);
1733    }
1734
1735    @Test(dataProvider="periodUntilUnit")
1736    public void test_until_TemporalUnit_negated(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) {
1737        long amount = date2.until(date1, unit);
1738        assertEquals(amount, -expected);
1739    }
1740
1741    @Test(dataProvider="periodUntilUnit")
1742    public void test_until_TemporalUnit_between(LocalDate date1, LocalDate date2, TemporalUnit unit, long expected) {
1743        long amount = unit.between(date1, date2);
1744        assertEquals(amount, expected);
1745    }
1746
1747    @Test
1748    public void test_until_convertedType() {
1749        LocalDate start = LocalDate.of(2010, 6, 30);
1750        OffsetDateTime end = start.plusDays(2).atStartOfDay().atOffset(OFFSET_PONE);
1751        assertEquals(start.until(end, DAYS), 2);
1752    }
1753
1754    @Test(expectedExceptions=DateTimeException.class)
1755    public void test_until_invalidType() {
1756        LocalDate start = LocalDate.of(2010, 6, 30);
1757        start.until(LocalTime.of(11, 30), DAYS);
1758    }
1759
1760    @Test(expectedExceptions = UnsupportedTemporalTypeException.class)
1761    public void test_until_TemporalUnit_unsupportedUnit() {
1762        TEST_2007_07_15.until(TEST_2007_07_15, HOURS);
1763    }
1764
1765    @Test(expectedExceptions = NullPointerException.class)
1766    public void test_until_TemporalUnit_nullEnd() {
1767        TEST_2007_07_15.until(null, DAYS);
1768    }
1769
1770    @Test(expectedExceptions = NullPointerException.class)
1771    public void test_until_TemporalUnit_nullUnit() {
1772        TEST_2007_07_15.until(TEST_2007_07_15, null);
1773    }
1774
1775    //-----------------------------------------------------------------------
1776    // until(ChronoLocalDate)
1777    //-----------------------------------------------------------------------
1778    @DataProvider(name="until")
1779    Object[][] data_periodUntil() {
1780        return new Object[][] {
1781                {2010, 1, 1, 2010, 1, 1, 0, 0, 0},
1782                {2010, 1, 1, 2010, 1, 2, 0, 0, 1},
1783                {2010, 1, 1, 2010, 1, 31, 0, 0, 30},
1784                {2010, 1, 1, 2010, 2, 1, 0, 1, 0},
1785                {2010, 1, 1, 2010, 2, 28, 0, 1, 27},
1786                {2010, 1, 1, 2010, 3, 1, 0, 2, 0},
1787                {2010, 1, 1, 2010, 12, 31, 0, 11, 30},
1788                {2010, 1, 1, 2011, 1, 1, 1, 0, 0},
1789                {2010, 1, 1, 2011, 12, 31, 1, 11, 30},
1790                {2010, 1, 1, 2012, 1, 1, 2, 0, 0},
1791
1792                {2010, 1, 10, 2010, 1, 1, 0, 0, -9},
1793                {2010, 1, 10, 2010, 1, 2, 0, 0, -8},
1794                {2010, 1, 10, 2010, 1, 9, 0, 0, -1},
1795                {2010, 1, 10, 2010, 1, 10, 0, 0, 0},
1796                {2010, 1, 10, 2010, 1, 11, 0, 0, 1},
1797                {2010, 1, 10, 2010, 1, 31, 0, 0, 21},
1798                {2010, 1, 10, 2010, 2, 1, 0, 0, 22},
1799                {2010, 1, 10, 2010, 2, 9, 0, 0, 30},
1800                {2010, 1, 10, 2010, 2, 10, 0, 1, 0},
1801                {2010, 1, 10, 2010, 2, 28, 0, 1, 18},
1802                {2010, 1, 10, 2010, 3, 1, 0, 1, 19},
1803                {2010, 1, 10, 2010, 3, 9, 0, 1, 27},
1804                {2010, 1, 10, 2010, 3, 10, 0, 2, 0},
1805                {2010, 1, 10, 2010, 12, 31, 0, 11, 21},
1806                {2010, 1, 10, 2011, 1, 1, 0, 11, 22},
1807                {2010, 1, 10, 2011, 1, 9, 0, 11, 30},
1808                {2010, 1, 10, 2011, 1, 10, 1, 0, 0},
1809
1810                {2010, 3, 30, 2011, 5, 1, 1, 1, 1},
1811                {2010, 4, 30, 2011, 5, 1, 1, 0, 1},
1812
1813                {2010, 2, 28, 2012, 2, 27, 1, 11, 30},
1814                {2010, 2, 28, 2012, 2, 28, 2, 0, 0},
1815                {2010, 2, 28, 2012, 2, 29, 2, 0, 1},
1816
1817                {2012, 2, 28, 2014, 2, 27, 1, 11, 30},
1818                {2012, 2, 28, 2014, 2, 28, 2, 0, 0},
1819                {2012, 2, 28, 2014, 3, 1, 2, 0, 1},
1820
1821                {2012, 2, 29, 2014, 2, 28, 1, 11, 30},
1822                {2012, 2, 29, 2014, 3, 1, 2, 0, 1},
1823                {2012, 2, 29, 2014, 3, 2, 2, 0, 2},
1824
1825                {2012, 2, 29, 2016, 2, 28, 3, 11, 30},
1826                {2012, 2, 29, 2016, 2, 29, 4, 0, 0},
1827                {2012, 2, 29, 2016, 3, 1, 4, 0, 1},
1828
1829                {2010, 1, 1, 2009, 12, 31, 0, 0, -1},
1830                {2010, 1, 1, 2009, 12, 30, 0, 0, -2},
1831                {2010, 1, 1, 2009, 12, 2, 0, 0, -30},
1832                {2010, 1, 1, 2009, 12, 1, 0, -1, 0},
1833                {2010, 1, 1, 2009, 11, 30, 0, -1, -1},
1834                {2010, 1, 1, 2009, 11, 2, 0, -1, -29},
1835                {2010, 1, 1, 2009, 11, 1, 0, -2, 0},
1836                {2010, 1, 1, 2009, 1, 2, 0, -11, -30},
1837                {2010, 1, 1, 2009, 1, 1, -1, 0, 0},
1838
1839                {2010, 1, 15, 2010, 1, 15, 0, 0, 0},
1840                {2010, 1, 15, 2010, 1, 14, 0, 0, -1},
1841                {2010, 1, 15, 2010, 1, 1, 0, 0, -14},
1842                {2010, 1, 15, 2009, 12, 31, 0, 0, -15},
1843                {2010, 1, 15, 2009, 12, 16, 0, 0, -30},
1844                {2010, 1, 15, 2009, 12, 15, 0, -1, 0},
1845                {2010, 1, 15, 2009, 12, 14, 0, -1, -1},
1846
1847                {2010, 2, 28, 2009, 3, 1, 0, -11, -27},
1848                {2010, 2, 28, 2009, 2, 28, -1, 0, 0},
1849                {2010, 2, 28, 2009, 2, 27, -1, 0, -1},
1850
1851                {2010, 2, 28, 2008, 2, 29, -1, -11, -28},
1852                {2010, 2, 28, 2008, 2, 28, -2, 0, 0},
1853                {2010, 2, 28, 2008, 2, 27, -2, 0, -1},
1854
1855                {2012, 2, 29, 2009, 3, 1, -2, -11, -28},
1856                {2012, 2, 29, 2009, 2, 28, -3, 0, -1},
1857                {2012, 2, 29, 2009, 2, 27, -3, 0, -2},
1858
1859                {2012, 2, 29, 2008, 3, 1, -3, -11, -28},
1860                {2012, 2, 29, 2008, 2, 29, -4, 0, 0},
1861                {2012, 2, 29, 2008, 2, 28, -4, 0, -1},
1862        };
1863    }
1864
1865    @Test(dataProvider="until")
1866    public void test_periodUntil_LocalDate(int y1, int m1, int d1, int y2, int m2, int d2, int ye, int me, int de) {
1867        LocalDate start = LocalDate.of(y1, m1, d1);
1868        LocalDate end = LocalDate.of(y2, m2, d2);
1869        Period test = start.until(end);
1870        assertEquals(test.getYears(), ye);
1871        assertEquals(test.getMonths(), me);
1872        assertEquals(test.getDays(), de);
1873    }
1874
1875    @Test
1876    public void test_periodUntil_LocalDate_max() {
1877        int years = Math.toIntExact((long) Year.MAX_VALUE - (long) Year.MIN_VALUE);
1878        assertEquals(LocalDate.MIN.until(LocalDate.MAX), Period.of(years, 11, 30));
1879    }
1880
1881    @Test(expectedExceptions=NullPointerException.class)
1882    public void test_periodUntil_LocalDate_null() {
1883        TEST_2007_07_15.until(null);
1884    }
1885
1886    //-----------------------------------------------------------------------
1887    // format(DateTimeFormatter)
1888    //-----------------------------------------------------------------------
1889    @Test
1890    public void test_format_formatter() {
1891        DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d");
1892        String t = LocalDate.of(2010, 12, 3).format(f);
1893        assertEquals(t, "2010 12 3");
1894    }
1895
1896    @Test(expectedExceptions=NullPointerException.class)
1897    public void test_format_formatter_null() {
1898        LocalDate.of(2010, 12, 3).format(null);
1899    }
1900
1901    //-----------------------------------------------------------------------
1902    // atTime()
1903    //-----------------------------------------------------------------------
1904    @Test
1905    public void test_atTime_LocalTime() {
1906        LocalDate t = LocalDate.of(2008, 6, 30);
1907        assertEquals(t.atTime(LocalTime.of(11, 30)), LocalDateTime.of(2008, 6, 30, 11, 30));
1908    }
1909
1910    @Test(expectedExceptions=NullPointerException.class)
1911    public void test_atTime_LocalTime_null() {
1912        LocalDate t = LocalDate.of(2008, 6, 30);
1913        t.atTime((LocalTime) null);
1914    }
1915
1916    //-------------------------------------------------------------------------
1917    @Test
1918    public void test_atTime_int_int() {
1919        LocalDate t = LocalDate.of(2008, 6, 30);
1920        assertEquals(t.atTime(11, 30), LocalDateTime.of(2008, 6, 30, 11, 30));
1921    }
1922
1923    @Test(expectedExceptions=DateTimeException.class)
1924    public void test_atTime_int_int_hourTooSmall() {
1925        LocalDate t = LocalDate.of(2008, 6, 30);
1926        t.atTime(-1, 30);
1927    }
1928
1929    @Test(expectedExceptions=DateTimeException.class)
1930    public void test_atTime_int_int_hourTooBig() {
1931        LocalDate t = LocalDate.of(2008, 6, 30);
1932        t.atTime(24, 30);
1933    }
1934
1935    @Test(expectedExceptions=DateTimeException.class)
1936    public void test_atTime_int_int_minuteTooSmall() {
1937        LocalDate t = LocalDate.of(2008, 6, 30);
1938        t.atTime(11, -1);
1939    }
1940
1941    @Test(expectedExceptions=DateTimeException.class)
1942    public void test_atTime_int_int_minuteTooBig() {
1943        LocalDate t = LocalDate.of(2008, 6, 30);
1944        t.atTime(11, 60);
1945    }
1946
1947    @Test
1948    public void test_atTime_int_int_int() {
1949        LocalDate t = LocalDate.of(2008, 6, 30);
1950        assertEquals(t.atTime(11, 30, 40), LocalDateTime.of(2008, 6, 30, 11, 30, 40));
1951    }
1952
1953    @Test(expectedExceptions=DateTimeException.class)
1954    public void test_atTime_int_int_int_hourTooSmall() {
1955        LocalDate t = LocalDate.of(2008, 6, 30);
1956        t.atTime(-1, 30, 40);
1957    }
1958
1959    @Test(expectedExceptions=DateTimeException.class)
1960    public void test_atTime_int_int_int_hourTooBig() {
1961        LocalDate t = LocalDate.of(2008, 6, 30);
1962        t.atTime(24, 30, 40);
1963    }
1964
1965    @Test(expectedExceptions=DateTimeException.class)
1966    public void test_atTime_int_int_int_minuteTooSmall() {
1967        LocalDate t = LocalDate.of(2008, 6, 30);
1968        t.atTime(11, -1, 40);
1969    }
1970
1971    @Test(expectedExceptions=DateTimeException.class)
1972    public void test_atTime_int_int_int_minuteTooBig() {
1973        LocalDate t = LocalDate.of(2008, 6, 30);
1974        t.atTime(11, 60, 40);
1975    }
1976
1977    @Test(expectedExceptions=DateTimeException.class)
1978    public void test_atTime_int_int_int_secondTooSmall() {
1979        LocalDate t = LocalDate.of(2008, 6, 30);
1980        t.atTime(11, 30, -1);
1981    }
1982
1983    @Test(expectedExceptions=DateTimeException.class)
1984    public void test_atTime_int_int_int_secondTooBig() {
1985        LocalDate t = LocalDate.of(2008, 6, 30);
1986        t.atTime(11, 30, 60);
1987    }
1988
1989    @Test
1990    public void test_atTime_int_int_int_int() {
1991        LocalDate t = LocalDate.of(2008, 6, 30);
1992        assertEquals(t.atTime(11, 30, 40, 50), LocalDateTime.of(2008, 6, 30, 11, 30, 40, 50));
1993    }
1994
1995    @Test(expectedExceptions=DateTimeException.class)
1996    public void test_atTime_int_int_int_int_hourTooSmall() {
1997        LocalDate t = LocalDate.of(2008, 6, 30);
1998        t.atTime(-1, 30, 40, 50);
1999    }
2000
2001    @Test(expectedExceptions=DateTimeException.class)
2002    public void test_atTime_int_int_int_int_hourTooBig() {
2003        LocalDate t = LocalDate.of(2008, 6, 30);
2004        t.atTime(24, 30, 40, 50);
2005    }
2006
2007    @Test(expectedExceptions=DateTimeException.class)
2008    public void test_atTime_int_int_int_int_minuteTooSmall() {
2009        LocalDate t = LocalDate.of(2008, 6, 30);
2010        t.atTime(11, -1, 40, 50);
2011    }
2012
2013    @Test(expectedExceptions=DateTimeException.class)
2014    public void test_atTime_int_int_int_int_minuteTooBig() {
2015        LocalDate t = LocalDate.of(2008, 6, 30);
2016        t.atTime(11, 60, 40, 50);
2017    }
2018
2019    @Test(expectedExceptions=DateTimeException.class)
2020    public void test_atTime_int_int_int_int_secondTooSmall() {
2021        LocalDate t = LocalDate.of(2008, 6, 30);
2022        t.atTime(11, 30, -1, 50);
2023    }
2024
2025    @Test(expectedExceptions=DateTimeException.class)
2026    public void test_atTime_int_int_int_int_secondTooBig() {
2027        LocalDate t = LocalDate.of(2008, 6, 30);
2028        t.atTime(11, 30, 60, 50);
2029    }
2030
2031    @Test(expectedExceptions=DateTimeException.class)
2032    public void test_atTime_int_int_int_int_nanoTooSmall() {
2033        LocalDate t = LocalDate.of(2008, 6, 30);
2034        t.atTime(11, 30, 40, -1);
2035    }
2036
2037    @Test(expectedExceptions=DateTimeException.class)
2038    public void test_atTime_int_int_int_int_nanoTooBig() {
2039        LocalDate t = LocalDate.of(2008, 6, 30);
2040        t.atTime(11, 30, 40, 1000000000);
2041    }
2042
2043    //-----------------------------------------------------------------------
2044    @Test
2045    public void test_atTime_OffsetTime() {
2046        LocalDate t = LocalDate.of(2008, 6, 30);
2047        assertEquals(t.atTime(OffsetTime.of(11, 30, 0, 0, OFFSET_PONE)), OffsetDateTime.of(2008, 6, 30, 11, 30, 0, 0, OFFSET_PONE));
2048    }
2049
2050    @Test(expectedExceptions=NullPointerException.class)
2051    public void test_atTime_OffsetTime_null() {
2052        LocalDate t = LocalDate.of(2008, 6, 30);
2053        t.atTime((OffsetTime) null);
2054    }
2055
2056    //-----------------------------------------------------------------------
2057    // atStartOfDay()
2058    //-----------------------------------------------------------------------
2059    @DataProvider(name="atStartOfDay")
2060    Object[][] data_atStartOfDay() {
2061        return new Object[][] {
2062                {LocalDate.of(2008, 6, 30), LocalDateTime.of(2008, 6, 30, 0, 0)},
2063                {LocalDate.of(-12, 6, 30), LocalDateTime.of(-12, 6, 30, 0, 0)},
2064        };
2065    }
2066
2067    @Test(dataProvider="atStartOfDay")
2068    public void test_atStartOfDay(LocalDate test, LocalDateTime expected) {
2069        assertEquals(test.atStartOfDay(), expected);
2070    }
2071
2072    //-----------------------------------------------------------------------
2073    // atStartOfDay(ZoneId)
2074    //-----------------------------------------------------------------------
2075    @DataProvider(name="atStartOfDayZoneId")
2076    Object[][] data_atStartOfDayZoneId() {
2077        return new Object[][] {
2078                {LocalDate.of(2008, 6, 30), ZONE_PARIS, ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 0, 0), ZONE_PARIS)},
2079                {LocalDate.of(2008, 6, 30), OFFSET_PONE, ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 0, 0), OFFSET_PONE)},
2080                {LocalDate.of(2007, 4, 1), ZONE_GAZA, ZonedDateTime.of(LocalDateTime.of(2007, 4, 1, 1, 0), ZONE_GAZA)},
2081        };
2082    }
2083
2084    @Test(dataProvider="atStartOfDayZoneId")
2085    public void test_atStartOfDay_ZoneId(LocalDate test, ZoneId zone, ZonedDateTime expected) {
2086        assertEquals(test.atStartOfDay(zone), expected);
2087    }
2088
2089    @Test(expectedExceptions=NullPointerException.class)
2090    public void test_atStartOfDay_ZoneId_null() {
2091        LocalDate t = LocalDate.of(2008, 6, 30);
2092        t.atStartOfDay((ZoneId) null);
2093    }
2094
2095    //-----------------------------------------------------------------------
2096    // toEpochDay()
2097    //-----------------------------------------------------------------------
2098    @Test
2099    public void test_toEpochDay() {
2100        long date_0000_01_01 = -678941 - 40587;
2101
2102        LocalDate test = LocalDate.of(0, 1, 1);
2103        for (long i = date_0000_01_01; i < 700000; i++) {
2104            assertEquals(test.toEpochDay(), i);
2105            test = next(test);
2106        }
2107        test = LocalDate.of(0, 1, 1);
2108        for (long i = date_0000_01_01; i > -2000000; i--) {
2109            assertEquals(test.toEpochDay(), i);
2110            test = previous(test);
2111        }
2112
2113        assertEquals(LocalDate.of(1858, 11, 17).toEpochDay(), -40587);
2114        assertEquals(LocalDate.of(1, 1, 1).toEpochDay(), -678575 - 40587);
2115        assertEquals(LocalDate.of(1995, 9, 27).toEpochDay(), 49987 - 40587);
2116        assertEquals(LocalDate.of(1970, 1, 1).toEpochDay(), 0);
2117        assertEquals(LocalDate.of(-1, 12, 31).toEpochDay(), -678942 - 40587);
2118    }
2119
2120    //-----------------------------------------------------------------------
2121    // compareTo()
2122    //-----------------------------------------------------------------------
2123    @Test
2124    public void test_comparisons() {
2125        doTest_comparisons_LocalDate(
2126            LocalDate.of(Year.MIN_VALUE, 1, 1),
2127            LocalDate.of(Year.MIN_VALUE, 12, 31),
2128            LocalDate.of(-1, 1, 1),
2129            LocalDate.of(-1, 12, 31),
2130            LocalDate.of(0, 1, 1),
2131            LocalDate.of(0, 12, 31),
2132            LocalDate.of(1, 1, 1),
2133            LocalDate.of(1, 12, 31),
2134            LocalDate.of(2006, 1, 1),
2135            LocalDate.of(2006, 12, 31),
2136            LocalDate.of(2007, 1, 1),
2137            LocalDate.of(2007, 12, 31),
2138            LocalDate.of(2008, 1, 1),
2139            LocalDate.of(2008, 2, 29),
2140            LocalDate.of(2008, 12, 31),
2141            LocalDate.of(Year.MAX_VALUE, 1, 1),
2142            LocalDate.of(Year.MAX_VALUE, 12, 31)
2143        );
2144    }
2145
2146    void doTest_comparisons_LocalDate(LocalDate... localDates) {
2147        for (int i = 0; i < localDates.length; i++) {
2148            LocalDate a = localDates[i];
2149            for (int j = 0; j < localDates.length; j++) {
2150                LocalDate b = localDates[j];
2151                if (i < j) {
2152                    assertTrue(a.compareTo(b) < 0, a + " <=> " + b);
2153                    assertEquals(a.isBefore(b), true, a + " <=> " + b);
2154                    assertEquals(a.isAfter(b), false, a + " <=> " + b);
2155                    assertEquals(a.equals(b), false, a + " <=> " + b);
2156                } else if (i > j) {
2157                    assertTrue(a.compareTo(b) > 0, a + " <=> " + b);
2158                    assertEquals(a.isBefore(b), false, a + " <=> " + b);
2159                    assertEquals(a.isAfter(b), true, a + " <=> " + b);
2160                    assertEquals(a.equals(b), false, a + " <=> " + b);
2161                } else {
2162                    assertEquals(a.compareTo(b), 0, a + " <=> " + b);
2163                    assertEquals(a.isBefore(b), false, a + " <=> " + b);
2164                    assertEquals(a.isAfter(b), false, a + " <=> " + b);
2165                    assertEquals(a.equals(b), true, a + " <=> " + b);
2166                }
2167            }
2168        }
2169    }
2170
2171    @Test(expectedExceptions=NullPointerException.class)
2172    public void test_compareTo_ObjectNull() {
2173        TEST_2007_07_15.compareTo(null);
2174    }
2175
2176    @Test
2177    public void test_isBefore() {
2178        assertTrue(TEST_2007_07_15.isBefore(LocalDate.of(2007, 07, 16)));
2179        assertFalse(TEST_2007_07_15.isBefore(LocalDate.of(2007, 07, 14)));
2180        assertFalse(TEST_2007_07_15.isBefore(TEST_2007_07_15));
2181    }
2182
2183    @Test(expectedExceptions=NullPointerException.class)
2184    public void test_isBefore_ObjectNull() {
2185        TEST_2007_07_15.isBefore(null);
2186    }
2187
2188    @Test(expectedExceptions=NullPointerException.class)
2189    public void test_isAfter_ObjectNull() {
2190        TEST_2007_07_15.isAfter(null);
2191    }
2192
2193    @Test
2194    public void test_isAfter() {
2195        assertTrue(TEST_2007_07_15.isAfter(LocalDate.of(2007, 07, 14)));
2196        assertFalse(TEST_2007_07_15.isAfter(LocalDate.of(2007, 07, 16)));
2197        assertFalse(TEST_2007_07_15.isAfter(TEST_2007_07_15));
2198    }
2199
2200    @Test(expectedExceptions=ClassCastException.class)
2201    @SuppressWarnings({"unchecked", "rawtypes"})
2202    public void compareToNonLocalDate() {
2203       Comparable c = TEST_2007_07_15;
2204       c.compareTo(new Object());
2205    }
2206
2207    //-----------------------------------------------------------------------
2208    // equals()
2209    //-----------------------------------------------------------------------
2210    @Test(dataProvider="sampleDates" )
2211    public void test_equals_true(int y, int m, int d) {
2212        LocalDate a = LocalDate.of(y, m, d);
2213        LocalDate b = LocalDate.of(y, m, d);
2214        assertEquals(a.equals(b), true);
2215    }
2216    @Test(dataProvider="sampleDates")
2217    public void test_equals_false_year_differs(int y, int m, int d) {
2218        LocalDate a = LocalDate.of(y, m, d);
2219        LocalDate b = LocalDate.of(y + 1, m, d);
2220        assertEquals(a.equals(b), false);
2221    }
2222    @Test(dataProvider="sampleDates")
2223    public void test_equals_false_month_differs(int y, int m, int d) {
2224        LocalDate a = LocalDate.of(y, m, d);
2225        LocalDate b = LocalDate.of(y, m + 1, d);
2226        assertEquals(a.equals(b), false);
2227    }
2228    @Test(dataProvider="sampleDates")
2229    public void test_equals_false_day_differs(int y, int m, int d) {
2230        LocalDate a = LocalDate.of(y, m, d);
2231        LocalDate b = LocalDate.of(y, m, d + 1);
2232        assertEquals(a.equals(b), false);
2233    }
2234
2235    @Test
2236    public void test_equals_itself_true() {
2237        assertEquals(TEST_2007_07_15.equals(TEST_2007_07_15), true);
2238    }
2239
2240    @Test
2241    public void test_equals_string_false() {
2242        assertEquals(TEST_2007_07_15.equals("2007-07-15"), false);
2243    }
2244
2245    @Test
2246    public void test_equals_null_false() {
2247        assertEquals(TEST_2007_07_15.equals(null), false);
2248    }
2249
2250    //-----------------------------------------------------------------------
2251    // hashCode()
2252    //-----------------------------------------------------------------------
2253    @Test(dataProvider="sampleDates")
2254    public void test_hashCode(int y, int m, int d) {
2255        LocalDate a = LocalDate.of(y, m, d);
2256        assertEquals(a.hashCode(), a.hashCode());
2257        LocalDate b = LocalDate.of(y, m, d);
2258        assertEquals(a.hashCode(), b.hashCode());
2259    }
2260
2261    //-----------------------------------------------------------------------
2262    // toString()
2263    //-----------------------------------------------------------------------
2264    @DataProvider(name="sampleToString")
2265    Object[][] provider_sampleToString() {
2266        return new Object[][] {
2267            {2008, 7, 5, "2008-07-05"},
2268            {2007, 12, 31, "2007-12-31"},
2269            {999, 12, 31, "0999-12-31"},
2270            {-1, 1, 2, "-0001-01-02"},
2271            {9999, 12, 31, "9999-12-31"},
2272            {-9999, 12, 31, "-9999-12-31"},
2273            {10000, 1, 1, "+10000-01-01"},
2274            {-10000, 1, 1, "-10000-01-01"},
2275            {12345678, 1, 1, "+12345678-01-01"},
2276            {-12345678, 1, 1, "-12345678-01-01"},
2277        };
2278    }
2279
2280    @Test(dataProvider="sampleToString")
2281    public void test_toString(int y, int m, int d, String expected) {
2282        LocalDate t = LocalDate.of(y, m, d);
2283        String str = t.toString();
2284        assertEquals(str, expected);
2285    }
2286
2287    private LocalDate date(int year, int month, int day) {
2288        return LocalDate.of(year, month, day);
2289    }
2290
2291}
2292