1 /*
2  * Copyright (c) 2012, 2020, 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) 2008-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  */
60 package tck.java.time;
61 
62 import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH;
63 import static java.time.temporal.ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR;
64 import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_MONTH;
65 import static java.time.temporal.ChronoField.ALIGNED_WEEK_OF_YEAR;
66 import static java.time.temporal.ChronoField.AMPM_OF_DAY;
67 import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_AMPM;
68 import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_DAY;
69 import static java.time.temporal.ChronoField.DAY_OF_MONTH;
70 import static java.time.temporal.ChronoField.DAY_OF_WEEK;
71 import static java.time.temporal.ChronoField.DAY_OF_YEAR;
72 import static java.time.temporal.ChronoField.EPOCH_DAY;
73 import static java.time.temporal.ChronoField.ERA;
74 import static java.time.temporal.ChronoField.HOUR_OF_AMPM;
75 import static java.time.temporal.ChronoField.HOUR_OF_DAY;
76 import static java.time.temporal.ChronoField.MICRO_OF_DAY;
77 import static java.time.temporal.ChronoField.MICRO_OF_SECOND;
78 import static java.time.temporal.ChronoField.MILLI_OF_DAY;
79 import static java.time.temporal.ChronoField.MILLI_OF_SECOND;
80 import static java.time.temporal.ChronoField.MINUTE_OF_DAY;
81 import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
82 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
83 import static java.time.temporal.ChronoField.NANO_OF_DAY;
84 import static java.time.temporal.ChronoField.NANO_OF_SECOND;
85 import static java.time.temporal.ChronoField.PROLEPTIC_MONTH;
86 import static java.time.temporal.ChronoField.SECOND_OF_DAY;
87 import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
88 import static java.time.temporal.ChronoField.YEAR;
89 import static java.time.temporal.ChronoField.YEAR_OF_ERA;
90 import static java.time.temporal.ChronoUnit.CENTURIES;
91 import static java.time.temporal.ChronoUnit.DAYS;
92 import static java.time.temporal.ChronoUnit.DECADES;
93 import static java.time.temporal.ChronoUnit.HALF_DAYS;
94 import static java.time.temporal.ChronoUnit.HOURS;
95 import static java.time.temporal.ChronoUnit.MICROS;
96 import static java.time.temporal.ChronoUnit.MILLENNIA;
97 import static java.time.temporal.ChronoUnit.MILLIS;
98 import static java.time.temporal.ChronoUnit.MINUTES;
99 import static java.time.temporal.ChronoUnit.MONTHS;
100 import static java.time.temporal.ChronoUnit.NANOS;
101 import static java.time.temporal.ChronoUnit.SECONDS;
102 import static java.time.temporal.ChronoUnit.WEEKS;
103 import static java.time.temporal.ChronoUnit.YEARS;
104 import static org.testng.Assert.assertEquals;
105 import static org.testng.Assert.assertFalse;
106 import static org.testng.Assert.assertSame;
107 import static org.testng.Assert.assertTrue;
108 import static org.testng.Assert.fail;
109 
110 import java.time.Clock;
111 import java.time.DateTimeException;
112 import java.time.DayOfWeek;
113 import java.time.Duration;
114 import java.time.Instant;
115 import java.time.LocalDate;
116 import java.time.LocalDateTime;
117 import java.time.LocalTime;
118 import java.time.Month;
119 import java.time.OffsetDateTime;
120 import java.time.OffsetTime;
121 import java.time.Year;
122 import java.time.ZoneId;
123 import java.time.ZoneOffset;
124 import java.time.ZonedDateTime;
125 import java.time.chrono.IsoChronology;
126 import java.time.format.DateTimeFormatter;
127 import java.time.format.DateTimeParseException;
128 import java.time.temporal.ChronoField;
129 import java.time.temporal.ChronoUnit;
130 import java.time.temporal.JulianFields;
131 import java.time.temporal.Temporal;
132 import java.time.temporal.TemporalAccessor;
133 import java.time.temporal.TemporalAdjuster;
134 import java.time.temporal.TemporalAmount;
135 import java.time.temporal.TemporalField;
136 import java.time.temporal.TemporalQueries;
137 import java.time.temporal.TemporalQuery;
138 import java.time.temporal.TemporalUnit;
139 import java.util.ArrayList;
140 import java.util.Arrays;
141 import java.util.Iterator;
142 import java.util.List;
143 
144 import org.testng.annotations.BeforeMethod;
145 import org.testng.annotations.DataProvider;
146 import org.testng.annotations.Test;
147 
148 /**
149  * Test LocalDateTime.
150  */
151 @Test
152 public class TCKLocalDateTime extends AbstractDateTimeTest {
153 
154     private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1);
155     private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2);
156     private static final ZoneOffset OFFSET_MTWO = ZoneOffset.ofHours(-2);
157     private static final ZoneId ZONE_PARIS = ZoneId.of("Europe/Paris");
158     private static final ZoneId ZONE_GAZA = ZoneId.of("Asia/Gaza");
159 
160     private LocalDateTime TEST_2007_07_15_12_30_40_987654321 = LocalDateTime.of(2007, 7, 15, 12, 30, 40, 987654321);
161     private LocalDateTime MAX_DATE_TIME;
162     private LocalDateTime MIN_DATE_TIME;
163     private Instant MAX_INSTANT;
164     private Instant MIN_INSTANT;
165 
166     @BeforeMethod
setUp()167     public void setUp() {
168         MAX_DATE_TIME = LocalDateTime.MAX;
169         MIN_DATE_TIME = LocalDateTime.MIN;
170         MAX_INSTANT = MAX_DATE_TIME.atZone(ZoneOffset.UTC).toInstant();
171         MIN_INSTANT = MIN_DATE_TIME.atZone(ZoneOffset.UTC).toInstant();
172     }
173 
174     //-----------------------------------------------------------------------
175     @Override
samples()176     protected List<TemporalAccessor> samples() {
177         TemporalAccessor[] array = {TEST_2007_07_15_12_30_40_987654321, LocalDateTime.MAX, LocalDateTime.MIN, };
178         return Arrays.asList(array);
179     }
180 
181     @Override
validFields()182     protected List<TemporalField> validFields() {
183         TemporalField[] array = {
184             NANO_OF_SECOND,
185             NANO_OF_DAY,
186             MICRO_OF_SECOND,
187             MICRO_OF_DAY,
188             MILLI_OF_SECOND,
189             MILLI_OF_DAY,
190             SECOND_OF_MINUTE,
191             SECOND_OF_DAY,
192             MINUTE_OF_HOUR,
193             MINUTE_OF_DAY,
194             CLOCK_HOUR_OF_AMPM,
195             HOUR_OF_AMPM,
196             CLOCK_HOUR_OF_DAY,
197             HOUR_OF_DAY,
198             AMPM_OF_DAY,
199             DAY_OF_WEEK,
200             ALIGNED_DAY_OF_WEEK_IN_MONTH,
201             ALIGNED_DAY_OF_WEEK_IN_YEAR,
202             DAY_OF_MONTH,
203             DAY_OF_YEAR,
204             EPOCH_DAY,
205             ALIGNED_WEEK_OF_MONTH,
206             ALIGNED_WEEK_OF_YEAR,
207             MONTH_OF_YEAR,
208             PROLEPTIC_MONTH,
209             YEAR_OF_ERA,
210             YEAR,
211             ERA,
212             JulianFields.JULIAN_DAY,
213             JulianFields.MODIFIED_JULIAN_DAY,
214             JulianFields.RATA_DIE,
215         };
216         return Arrays.asList(array);
217     }
218 
219     @Override
invalidFields()220     protected List<TemporalField> invalidFields() {
221         List<TemporalField> list = new ArrayList<>(Arrays.<TemporalField>asList(ChronoField.values()));
222         list.removeAll(validFields());
223         return list;
224     }
225 
226     //-----------------------------------------------------------------------
check(LocalDateTime test, int y, int m, int d, int h, int mi, int s, int n)227     private void check(LocalDateTime test, int y, int m, int d, int h, int mi, int s, int n) {
228         assertEquals(test.getYear(), y);
229         assertEquals(test.getMonth().getValue(), m);
230         assertEquals(test.getDayOfMonth(), d);
231         assertEquals(test.getHour(), h);
232         assertEquals(test.getMinute(), mi);
233         assertEquals(test.getSecond(), s);
234         assertEquals(test.getNano(), n);
235         assertEquals(test, test);
236         assertEquals(test.hashCode(), test.hashCode());
237         assertEquals(LocalDateTime.of(y, m, d, h, mi, s, n), test);
238     }
239 
createDateMidnight(int year, int month, int day)240     private LocalDateTime createDateMidnight(int year, int month, int day) {
241         return LocalDateTime.of(year, month, day, 0, 0);
242     }
243 
244     //-----------------------------------------------------------------------
245     // constants
246     //-----------------------------------------------------------------------
247     @Test
constant_MIN()248     public void constant_MIN() {
249         check(LocalDateTime.MIN, Year.MIN_VALUE, 1, 1, 0, 0, 0, 0);
250     }
251 
252     @Test
constant_MAX()253     public void constant_MAX() {
254         check(LocalDateTime.MAX, Year.MAX_VALUE, 12, 31, 23, 59, 59, 999999999);
255     }
256 
257     //-----------------------------------------------------------------------
258     // now()
259     //-----------------------------------------------------------------------
260     @Test(timeOut=30000)  // TODO: remove when time zone loading is faster
now()261     public void now() {
262         final long DELTA = 20_000_000_000L;    // 20 seconds of nanos leeway
263         LocalDateTime expected = LocalDateTime.now(Clock.systemDefaultZone());
264         LocalDateTime test = LocalDateTime.now();
265         long diff = Math.abs(test.toLocalTime().toNanoOfDay() - expected.toLocalTime().toNanoOfDay());
266         if (diff >= DELTA) {
267             // may be date change
268             expected = LocalDateTime.now(Clock.systemDefaultZone());
269             test = LocalDateTime.now();
270             diff = Math.abs(test.toLocalTime().toNanoOfDay() - expected.toLocalTime().toNanoOfDay());
271         }
272         assertTrue(diff < DELTA);
273     }
274 
275     //-----------------------------------------------------------------------
276     // now(ZoneId)
277     //-----------------------------------------------------------------------
278     @Test(expectedExceptions=NullPointerException.class)
279     public void now_ZoneId_nullZoneId() {
280         LocalDateTime.now((ZoneId) null);
281     }
282 
283     @Test
284     public void now_ZoneId() {
285         ZoneId zone = ZoneId.of("UTC+01:02:03");
286         LocalDateTime expected = LocalDateTime.now(Clock.system(zone));
287         LocalDateTime test = LocalDateTime.now(zone);
288         assertEquals(Duration.between(expected, test).truncatedTo(ChronoUnit.SECONDS),
289                 Duration.ZERO);
290     }
291 
292     //-----------------------------------------------------------------------
293     // now(Clock)
294     //-----------------------------------------------------------------------
295     @Test(expectedExceptions=NullPointerException.class)
296     public void now_Clock_nullClock() {
297         LocalDateTime.now((Clock) null);
298     }
299 
300     @Test
301     public void now_Clock_allSecsInDay_utc() {
302         for (int i = 0; i < (2 * 24 * 60 * 60); i++) {
303             Instant instant = Instant.ofEpochSecond(i).plusNanos(123456789L);
304             Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
305             LocalDateTime test = LocalDateTime.now(clock);
306             assertEquals(test.getYear(), 1970);
307             assertEquals(test.getMonth(), Month.JANUARY);
308             assertEquals(test.getDayOfMonth(), (i < 24 * 60 * 60 ? 1 : 2));
309             assertEquals(test.getHour(), (i / (60 * 60)) % 24);
310             assertEquals(test.getMinute(), (i / 60) % 60);
311             assertEquals(test.getSecond(), i % 60);
312             assertEquals(test.getNano(), 123456789);
313         }
314     }
315 
316     @Test
317     public void now_Clock_allSecsInDay_offset() {
318         for (int i = 0; i < (2 * 24 * 60 * 60); i++) {
319             Instant instant = Instant.ofEpochSecond(i).plusNanos(123456789L);
320             Clock clock = Clock.fixed(instant.minusSeconds(OFFSET_PONE.getTotalSeconds()), OFFSET_PONE);
321             LocalDateTime test = LocalDateTime.now(clock);
322             assertEquals(test.getYear(), 1970);
323             assertEquals(test.getMonth(), Month.JANUARY);
324             assertEquals(test.getDayOfMonth(), (i < 24 * 60 * 60) ? 1 : 2);
325             assertEquals(test.getHour(), (i / (60 * 60)) % 24);
326             assertEquals(test.getMinute(), (i / 60) % 60);
327             assertEquals(test.getSecond(), i % 60);
328             assertEquals(test.getNano(), 123456789);
329         }
330     }
331 
332     @Test
333     public void now_Clock_allSecsInDay_beforeEpoch() {
334         LocalTime expected = LocalTime.MIDNIGHT.plusNanos(123456789L);
335         for (int i =-1; i >= -(24 * 60 * 60); i--) {
336             Instant instant = Instant.ofEpochSecond(i).plusNanos(123456789L);
337             Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
338             LocalDateTime test = LocalDateTime.now(clock);
339             assertEquals(test.getYear(), 1969);
340             assertEquals(test.getMonth(), Month.DECEMBER);
341             assertEquals(test.getDayOfMonth(), 31);
342             expected = expected.minusSeconds(1);
343             assertEquals(test.toLocalTime(), expected);
344         }
345     }
346 
347     //-----------------------------------------------------------------------
348     @Test
349     public void now_Clock_maxYear() {
350         Clock clock = Clock.fixed(MAX_INSTANT, ZoneOffset.UTC);
351         LocalDateTime test = LocalDateTime.now(clock);
352         assertEquals(test, MAX_DATE_TIME);
353     }
354 
355     @Test(expectedExceptions=DateTimeException.class)
356     public void now_Clock_tooBig() {
357         Clock clock = Clock.fixed(MAX_INSTANT.plusSeconds(24 * 60 * 60), ZoneOffset.UTC);
358         LocalDateTime.now(clock);
359     }
360 
361     @Test
362     public void now_Clock_minYear() {
363         Clock clock = Clock.fixed(MIN_INSTANT, ZoneOffset.UTC);
364         LocalDateTime test = LocalDateTime.now(clock);
365         assertEquals(test, MIN_DATE_TIME);
366     }
367 
368     @Test(expectedExceptions=DateTimeException.class)
369     public void now_Clock_tooLow() {
370         Clock clock = Clock.fixed(MIN_INSTANT.minusNanos(1), ZoneOffset.UTC);
371         LocalDateTime.now(clock);
372     }
373 
374     //-----------------------------------------------------------------------
375     // of() factories
376     //-----------------------------------------------------------------------
377     //-----------------------------------------------------------------------
378     @Test
379     public void factory_of_4intsMonth() {
380         LocalDateTime dateTime = LocalDateTime.of(2007, Month.JULY, 15, 12, 30);
381         check(dateTime, 2007, 7, 15, 12, 30, 0, 0);
382     }
383 
384     @Test(expectedExceptions=DateTimeException.class)
385     public void factory_of_4intsMonth_yearTooLow() {
386         LocalDateTime.of(Integer.MIN_VALUE, Month.JULY, 15, 12, 30);
387     }
388 
389     @Test(expectedExceptions=NullPointerException.class)
390     public void factory_of_4intsMonth_nullMonth() {
391         LocalDateTime.of(2007, null, 15, 12, 30);
392     }
393 
394     @Test(expectedExceptions=DateTimeException.class)
395     public void factory_of_4intsMonth_dayTooLow() {
396         LocalDateTime.of(2007, Month.JULY, -1, 12, 30);
397     }
398 
399     @Test(expectedExceptions=DateTimeException.class)
400     public void factory_of_4intsMonth_dayTooHigh() {
401         LocalDateTime.of(2007, Month.JULY, 32, 12, 30);
402     }
403 
404     @Test(expectedExceptions=DateTimeException.class)
405     public void factory_of_4intsMonth_hourTooLow() {
406         LocalDateTime.of(2007, Month.JULY, 15, -1, 30);
407     }
408 
409     @Test(expectedExceptions=DateTimeException.class)
410     public void factory_of_4intsMonth_hourTooHigh() {
411         LocalDateTime.of(2007, Month.JULY, 15, 24, 30);
412     }
413 
414     @Test(expectedExceptions=DateTimeException.class)
415     public void factory_of_4intsMonth_minuteTooLow() {
416         LocalDateTime.of(2007, Month.JULY, 15, 12, -1);
417     }
418 
419     @Test(expectedExceptions=DateTimeException.class)
420     public void factory_of_4intsMonth_minuteTooHigh() {
421         LocalDateTime.of(2007, Month.JULY, 15, 12, 60);
422     }
423 
424     //-----------------------------------------------------------------------
425     @Test
426     public void factory_of_5intsMonth() {
427         LocalDateTime dateTime = LocalDateTime.of(2007, Month.JULY, 15, 12, 30, 40);
428         check(dateTime, 2007, 7, 15, 12, 30, 40, 0);
429     }
430 
431     @Test(expectedExceptions=DateTimeException.class)
432     public void factory_of_5intsMonth_yearTooLow() {
433         LocalDateTime.of(Integer.MIN_VALUE, Month.JULY, 15, 12, 30, 40);
434     }
435 
436     @Test(expectedExceptions=NullPointerException.class)
437     public void factory_of_5intsMonth_nullMonth() {
438         LocalDateTime.of(2007, null, 15, 12, 30, 40);
439     }
440 
441     @Test(expectedExceptions=DateTimeException.class)
442     public void factory_of_5intsMonth_dayTooLow() {
443         LocalDateTime.of(2007, Month.JULY, -1, 12, 30, 40);
444     }
445 
446     @Test(expectedExceptions=DateTimeException.class)
447     public void factory_of_5intsMonth_dayTooHigh() {
448         LocalDateTime.of(2007, Month.JULY, 32, 12, 30, 40);
449     }
450 
451     @Test(expectedExceptions=DateTimeException.class)
452     public void factory_of_5intsMonth_hourTooLow() {
453         LocalDateTime.of(2007, Month.JULY, 15, -1, 30, 40);
454     }
455 
456     @Test(expectedExceptions=DateTimeException.class)
457     public void factory_of_5intsMonth_hourTooHigh() {
458         LocalDateTime.of(2007, Month.JULY, 15, 24, 30, 40);
459     }
460 
461     @Test(expectedExceptions=DateTimeException.class)
462     public void factory_of_5intsMonth_minuteTooLow() {
463         LocalDateTime.of(2007, Month.JULY, 15, 12, -1, 40);
464     }
465 
466     @Test(expectedExceptions=DateTimeException.class)
467     public void factory_of_5intsMonth_minuteTooHigh() {
468         LocalDateTime.of(2007, Month.JULY, 15, 12, 60, 40);
469     }
470 
471     @Test(expectedExceptions=DateTimeException.class)
472     public void factory_of_5intsMonth_secondTooLow() {
473         LocalDateTime.of(2007, Month.JULY, 15, 12, 30, -1);
474     }
475 
476     @Test(expectedExceptions=DateTimeException.class)
477     public void factory_of_5intsMonth_secondTooHigh() {
478         LocalDateTime.of(2007, Month.JULY, 15, 12, 30, 60);
479     }
480 
481     //-----------------------------------------------------------------------
482     @Test
483     public void factory_of_6intsMonth() {
484         LocalDateTime dateTime = LocalDateTime.of(2007, Month.JULY, 15, 12, 30, 40, 987654321);
485         check(dateTime, 2007, 7, 15, 12, 30, 40, 987654321);
486     }
487 
488     @Test(expectedExceptions=DateTimeException.class)
489     public void factory_of_6intsMonth_yearTooLow() {
490         LocalDateTime.of(Integer.MIN_VALUE, Month.JULY, 15, 12, 30, 40, 987654321);
491     }
492 
493     @Test(expectedExceptions=NullPointerException.class)
494     public void factory_of_6intsMonth_nullMonth() {
495         LocalDateTime.of(2007, null, 15, 12, 30, 40, 987654321);
496     }
497 
498     @Test(expectedExceptions=DateTimeException.class)
499     public void factory_of_6intsMonth_dayTooLow() {
500         LocalDateTime.of(2007, Month.JULY, -1, 12, 30, 40, 987654321);
501     }
502 
503     @Test(expectedExceptions=DateTimeException.class)
504     public void factory_of_6intsMonth_dayTooHigh() {
505         LocalDateTime.of(2007, Month.JULY, 32, 12, 30, 40, 987654321);
506     }
507 
508     @Test(expectedExceptions=DateTimeException.class)
509     public void factory_of_6intsMonth_hourTooLow() {
510         LocalDateTime.of(2007, Month.JULY, 15, -1, 30, 40, 987654321);
511     }
512 
513     @Test(expectedExceptions=DateTimeException.class)
514     public void factory_of_6intsMonth_hourTooHigh() {
515         LocalDateTime.of(2007, Month.JULY, 15, 24, 30, 40, 987654321);
516     }
517 
518     @Test(expectedExceptions=DateTimeException.class)
519     public void factory_of_6intsMonth_minuteTooLow() {
520         LocalDateTime.of(2007, Month.JULY, 15, 12, -1, 40, 987654321);
521     }
522 
523     @Test(expectedExceptions=DateTimeException.class)
524     public void factory_of_6intsMonth_minuteTooHigh() {
525         LocalDateTime.of(2007, Month.JULY, 15, 12, 60, 40, 987654321);
526     }
527 
528     @Test(expectedExceptions=DateTimeException.class)
529     public void factory_of_6intsMonth_secondTooLow() {
530         LocalDateTime.of(2007, Month.JULY, 15, 12, 30, -1, 987654321);
531     }
532 
533     @Test(expectedExceptions=DateTimeException.class)
534     public void factory_of_6intsMonth_secondTooHigh() {
535         LocalDateTime.of(2007, Month.JULY, 15, 12, 30, 60, 987654321);
536     }
537 
538     @Test(expectedExceptions=DateTimeException.class)
539     public void factory_of_6intsMonth_nanoTooLow() {
540         LocalDateTime.of(2007, Month.JULY, 15, 12, 30, 40, -1);
541     }
542 
543     @Test(expectedExceptions=DateTimeException.class)
544     public void factory_of_6intsMonth_nanoTooHigh() {
545         LocalDateTime.of(2007, Month.JULY, 15, 12, 30, 40, 1000000000);
546     }
547 
548     //-----------------------------------------------------------------------
549     @Test
550     public void factory_of_5ints() {
551         LocalDateTime dateTime = LocalDateTime.of(2007, 7, 15, 12, 30);
552         check(dateTime, 2007, 7, 15, 12, 30, 0, 0);
553     }
554 
555     @Test(expectedExceptions=DateTimeException.class)
556     public void factory_of_5ints_yearTooLow() {
557         LocalDateTime.of(Integer.MIN_VALUE, 7, 15, 12, 30);
558     }
559 
560     @Test(expectedExceptions=DateTimeException.class)
561     public void factory_of_5ints_monthTooLow() {
562         LocalDateTime.of(2007, 0, 15, 12, 30);
563     }
564 
565     @Test(expectedExceptions=DateTimeException.class)
566     public void factory_of_5ints_monthTooHigh() {
567         LocalDateTime.of(2007, 13, 15, 12, 30);
568     }
569 
570     @Test(expectedExceptions=DateTimeException.class)
571     public void factory_of_5ints_dayTooLow() {
572         LocalDateTime.of(2007, 7, -1, 12, 30);
573     }
574 
575     @Test(expectedExceptions=DateTimeException.class)
576     public void factory_of_5ints_dayTooHigh() {
577         LocalDateTime.of(2007, 7, 32, 12, 30);
578     }
579 
580     @Test(expectedExceptions=DateTimeException.class)
581     public void factory_of_5ints_hourTooLow() {
582         LocalDateTime.of(2007, 7, 15, -1, 30);
583     }
584 
585     @Test(expectedExceptions=DateTimeException.class)
586     public void factory_of_5ints_hourTooHigh() {
587         LocalDateTime.of(2007, 7, 15, 24, 30);
588     }
589 
590     @Test(expectedExceptions=DateTimeException.class)
591     public void factory_of_5ints_minuteTooLow() {
592         LocalDateTime.of(2007, 7, 15, 12, -1);
593     }
594 
595     @Test(expectedExceptions=DateTimeException.class)
596     public void factory_of_5ints_minuteTooHigh() {
597         LocalDateTime.of(2007, 7, 15, 12, 60);
598     }
599 
600     //-----------------------------------------------------------------------
601     @Test
602     public void factory_of_6ints() {
603         LocalDateTime dateTime = LocalDateTime.of(2007, 7, 15, 12, 30, 40);
604         check(dateTime, 2007, 7, 15, 12, 30, 40, 0);
605     }
606 
607     @Test(expectedExceptions=DateTimeException.class)
608     public void factory_of_6ints_yearTooLow() {
609         LocalDateTime.of(Integer.MIN_VALUE, 7, 15, 12, 30, 40);
610     }
611 
612     @Test(expectedExceptions=DateTimeException.class)
613     public void factory_of_6ints_monthTooLow() {
614         LocalDateTime.of(2007, 0, 15, 12, 30, 40);
615     }
616 
617     @Test(expectedExceptions=DateTimeException.class)
618     public void factory_of_6ints_monthTooHigh() {
619         LocalDateTime.of(2007, 13, 15, 12, 30, 40);
620     }
621 
622     @Test(expectedExceptions=DateTimeException.class)
623     public void factory_of_6ints_dayTooLow() {
624         LocalDateTime.of(2007, 7, -1, 12, 30, 40);
625     }
626 
627     @Test(expectedExceptions=DateTimeException.class)
628     public void factory_of_6ints_dayTooHigh() {
629         LocalDateTime.of(2007, 7, 32, 12, 30, 40);
630     }
631 
632     @Test(expectedExceptions=DateTimeException.class)
633     public void factory_of_6ints_hourTooLow() {
634         LocalDateTime.of(2007, 7, 15, -1, 30, 40);
635     }
636 
637     @Test(expectedExceptions=DateTimeException.class)
638     public void factory_of_6ints_hourTooHigh() {
639         LocalDateTime.of(2007, 7, 15, 24, 30, 40);
640     }
641 
642     @Test(expectedExceptions=DateTimeException.class)
643     public void factory_of_6ints_minuteTooLow() {
644         LocalDateTime.of(2007, 7, 15, 12, -1, 40);
645     }
646 
647     @Test(expectedExceptions=DateTimeException.class)
648     public void factory_of_6ints_minuteTooHigh() {
649         LocalDateTime.of(2007, 7, 15, 12, 60, 40);
650     }
651 
652     @Test(expectedExceptions=DateTimeException.class)
653     public void factory_of_6ints_secondTooLow() {
654         LocalDateTime.of(2007, 7, 15, 12, 30, -1);
655     }
656 
657     @Test(expectedExceptions=DateTimeException.class)
658     public void factory_of_6ints_secondTooHigh() {
659         LocalDateTime.of(2007, 7, 15, 12, 30, 60);
660     }
661 
662     //-----------------------------------------------------------------------
663     @Test
664     public void factory_of_7ints() {
665         LocalDateTime dateTime = LocalDateTime.of(2007, 7, 15, 12, 30, 40, 987654321);
666         check(dateTime, 2007, 7, 15, 12, 30, 40, 987654321);
667     }
668 
669     @Test(expectedExceptions=DateTimeException.class)
670     public void factory_of_7ints_yearTooLow() {
671         LocalDateTime.of(Integer.MIN_VALUE, 7, 15, 12, 30, 40, 987654321);
672     }
673 
674     @Test(expectedExceptions=DateTimeException.class)
675     public void factory_of_7ints_monthTooLow() {
676         LocalDateTime.of(2007, 0, 15, 12, 30, 40, 987654321);
677     }
678 
679     @Test(expectedExceptions=DateTimeException.class)
680     public void factory_of_7ints_monthTooHigh() {
681         LocalDateTime.of(2007, 13, 15, 12, 30, 40, 987654321);
682     }
683 
684     @Test(expectedExceptions=DateTimeException.class)
685     public void factory_of_7ints_dayTooLow() {
686         LocalDateTime.of(2007, 7, -1, 12, 30, 40, 987654321);
687     }
688 
689     @Test(expectedExceptions=DateTimeException.class)
690     public void factory_of_7ints_dayTooHigh() {
691         LocalDateTime.of(2007, 7, 32, 12, 30, 40, 987654321);
692     }
693 
694     @Test(expectedExceptions=DateTimeException.class)
695     public void factory_of_7ints_hourTooLow() {
696         LocalDateTime.of(2007, 7, 15, -1, 30, 40, 987654321);
697     }
698 
699     @Test(expectedExceptions=DateTimeException.class)
700     public void factory_of_7ints_hourTooHigh() {
701         LocalDateTime.of(2007, 7, 15, 24, 30, 40, 987654321);
702     }
703 
704     @Test(expectedExceptions=DateTimeException.class)
705     public void factory_of_7ints_minuteTooLow() {
706         LocalDateTime.of(2007, 7, 15, 12, -1, 40, 987654321);
707     }
708 
709     @Test(expectedExceptions=DateTimeException.class)
710     public void factory_of_7ints_minuteTooHigh() {
711         LocalDateTime.of(2007, 7, 15, 12, 60, 40, 987654321);
712     }
713 
714     @Test(expectedExceptions=DateTimeException.class)
715     public void factory_of_7ints_secondTooLow() {
716         LocalDateTime.of(2007, 7, 15, 12, 30, -1, 987654321);
717     }
718 
719     @Test(expectedExceptions=DateTimeException.class)
720     public void factory_of_7ints_secondTooHigh() {
721         LocalDateTime.of(2007, 7, 15, 12, 30, 60, 987654321);
722     }
723 
724     @Test(expectedExceptions=DateTimeException.class)
725     public void factory_of_7ints_nanoTooLow() {
726         LocalDateTime.of(2007, 7, 15, 12, 30, 40, -1);
727     }
728 
729     @Test(expectedExceptions=DateTimeException.class)
730     public void factory_of_7ints_nanoTooHigh() {
731         LocalDateTime.of(2007, 7, 15, 12, 30, 40, 1000000000);
732     }
733 
734     //-----------------------------------------------------------------------
735     @Test
736     public void factory_of_LocalDate_LocalTime() {
737         LocalDateTime dateTime = LocalDateTime.of(LocalDate.of(2007, 7, 15), LocalTime.of(12, 30, 40, 987654321));
738         check(dateTime, 2007, 7, 15, 12, 30, 40, 987654321);
739     }
740 
741     @Test(expectedExceptions=NullPointerException.class)
742     public void factory_of_LocalDate_LocalTime_nullLocalDate() {
743         LocalDateTime.of(null, LocalTime.of(12, 30, 40, 987654321));
744     }
745 
746     @Test(expectedExceptions=NullPointerException.class)
747     public void factory_of_LocalDate_LocalTime_nullLocalTime() {
748         LocalDateTime.of(LocalDate.of(2007, 7, 15), null);
749     }
750 
751     //-----------------------------------------------------------------------
752     // ofInstant()
753     //-----------------------------------------------------------------------
754     @DataProvider(name="instantFactory")
755     Object[][] data_instantFactory() {
756         return new Object[][] {
757                 {Instant.ofEpochSecond(86400 + 3600 + 120 + 4, 500), ZONE_PARIS, LocalDateTime.of(1970, 1, 2, 2, 2, 4, 500)},
758                 {Instant.ofEpochSecond(86400 + 3600 + 120 + 4, 500), OFFSET_MTWO, LocalDateTime.of(1970, 1, 1, 23, 2, 4, 500)},
759                 {Instant.ofEpochSecond(-86400 + 4, 500), OFFSET_PTWO, LocalDateTime.of(1969, 12, 31, 2, 0, 4, 500)},
760                 {OffsetDateTime.of(LocalDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0), ZoneOffset.UTC).toInstant(),
761                         ZoneOffset.UTC, LocalDateTime.MIN},
762                 {OffsetDateTime.of(LocalDateTime.of(Year.MAX_VALUE, 12, 31, 23, 59, 59, 999_999_999), ZoneOffset.UTC).toInstant(),
763                         ZoneOffset.UTC, LocalDateTime.MAX},
764         };
765     }
766 
767     @Test(dataProvider="instantFactory")
768     public void factory_ofInstant(Instant instant, ZoneId zone, LocalDateTime expected) {
769         LocalDateTime test = LocalDateTime.ofInstant(instant, zone);
770         assertEquals(test, expected);
771     }
772 
773     @Test(expectedExceptions=DateTimeException.class)
774     public void factory_ofInstant_instantTooBig() {
775         LocalDateTime.ofInstant(Instant.MAX, OFFSET_PONE) ;
776     }
777 
778     @Test(expectedExceptions=DateTimeException.class)
779     public void factory_ofInstant_instantTooSmall() {
780         LocalDateTime.ofInstant(Instant.MIN, OFFSET_PONE) ;
781     }
782 
783     @Test(expectedExceptions=NullPointerException.class)
784     public void factory_ofInstant_nullInstant() {
785         LocalDateTime.ofInstant((Instant) null, ZONE_GAZA);
786     }
787 
788     @Test(expectedExceptions=NullPointerException.class)
789     public void factory_ofInstant_nullZone() {
790         LocalDateTime.ofInstant(Instant.EPOCH, (ZoneId) null);
791     }
792 
793     //-----------------------------------------------------------------------
794     // ofEpochSecond()
795     //-----------------------------------------------------------------------
796     @Test
797     public void factory_ofEpochSecond_longOffset_afterEpoch() {
798         LocalDateTime base = LocalDateTime.of(1970, 1, 1, 2, 0, 0, 500);
799         for (int i = 0; i < 100000; i++) {
800             LocalDateTime test = LocalDateTime.ofEpochSecond(i, 500, OFFSET_PTWO);
801             assertEquals(test, base.plusSeconds(i));
802         }
803     }
804 
805     @Test
806     public void factory_ofEpochSecond_longOffset_beforeEpoch() {
807         LocalDateTime base = LocalDateTime.of(1970, 1, 1, 2, 0, 0, 500);
808         for (int i = 0; i < 100000; i++) {
809             LocalDateTime test = LocalDateTime.ofEpochSecond(-i, 500, OFFSET_PTWO);
810             assertEquals(test, base.minusSeconds(i));
811         }
812     }
813 
814     @Test(expectedExceptions=DateTimeException.class)
815     public void factory_ofEpochSecond_longOffset_tooBig() {
816         LocalDateTime.ofEpochSecond(Long.MAX_VALUE, 500, OFFSET_PONE);  // TODO: better test
817     }
818 
819     @Test(expectedExceptions=DateTimeException.class)
820     public void factory_ofEpochSecond_longOffset_tooSmall() {
821         LocalDateTime.ofEpochSecond(Long.MIN_VALUE, 500, OFFSET_PONE);  // TODO: better test
822     }
823 
824     @Test(expectedExceptions=DateTimeException.class)
825     public void factory_ofEpochSecond_badNanos_toBig() {
826         LocalDateTime.ofEpochSecond(0, 1_000_000_000, OFFSET_PONE);
827     }
828 
829     @Test(expectedExceptions=DateTimeException.class)
830     public void factory_ofEpochSecond_badNanos_toSmall() {
831         LocalDateTime.ofEpochSecond(0, -1, OFFSET_PONE);
832     }
833 
834     @Test(expectedExceptions=NullPointerException.class)
835     public void factory_ofEpochSecond_longOffset_nullOffset() {
836         LocalDateTime.ofEpochSecond(0L, 500, null);
837     }
838 
839     //-----------------------------------------------------------------------
840     // from()
841     //-----------------------------------------------------------------------
842     @Test
843     public void test_from_TemporalAccessor() {
844         LocalDateTime base = LocalDateTime.of(2007, 7, 15, 17, 30);
845         assertEquals(LocalDateTime.from(base), base);
846         assertEquals(LocalDateTime.from(ZonedDateTime.of(base, ZoneOffset.ofHours(2))), base);
847     }
848 
849     @Test(expectedExceptions=DateTimeException.class)
850     public void test_from_TemporalAccessor_invalid_noDerive() {
851         LocalDateTime.from(LocalTime.of(12, 30));
852     }
853 
854     @Test(expectedExceptions=NullPointerException.class)
855     public void test_from_TemporalAccessor_null() {
856         LocalDateTime.from((TemporalAccessor) null);
857     }
858 
859     //-----------------------------------------------------------------------
860     // parse()
861     //-----------------------------------------------------------------------
862     @Test(dataProvider="sampleToString")
863     public void test_parse(int y, int month, int d, int h, int m, int s, int n, String text) {
864         LocalDateTime t = LocalDateTime.parse(text);
865         assertEquals(t.getYear(), y);
866         assertEquals(t.getMonth().getValue(), month);
867         assertEquals(t.getDayOfMonth(), d);
868         assertEquals(t.getHour(), h);
869         assertEquals(t.getMinute(), m);
870         assertEquals(t.getSecond(), s);
871         assertEquals(t.getNano(), n);
872     }
873 
874     @Test(expectedExceptions=DateTimeParseException.class)
875     public void factory_parse_illegalValue() {
876         LocalDateTime.parse("2008-06-32T11:15");
877     }
878 
879     @Test(expectedExceptions=DateTimeParseException.class)
880     public void factory_parse_invalidValue() {
881         LocalDateTime.parse("2008-06-31T11:15");
882     }
883 
884     @Test(expectedExceptions=NullPointerException.class)
885     public void factory_parse_nullText() {
886         LocalDateTime.parse((String) null);
887     }
888 
889     //-----------------------------------------------------------------------
890     // parse(DateTimeFormatter)
891     //-----------------------------------------------------------------------
892     @Test
893     public void factory_parse_formatter() {
894         DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s");
895         LocalDateTime test = LocalDateTime.parse("2010 12 3 11 30 45", f);
896         assertEquals(test, LocalDateTime.of(2010, 12, 3, 11, 30, 45));
897     }
898 
899     @Test(expectedExceptions=NullPointerException.class)
900     public void factory_parse_formatter_nullText() {
901         DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s");
902         LocalDateTime.parse((String) null, f);
903     }
904 
905     @Test(expectedExceptions=NullPointerException.class)
906     public void factory_parse_formatter_nullFormatter() {
907         LocalDateTime.parse("ANY", null);
908     }
909 
910     //-----------------------------------------------------------------------
911     // isSupported(TemporalField)
912     //-----------------------------------------------------------------------
913     @Test
914     public void test_isSupported_TemporalField() {
915         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported((TemporalField) null), false);
916         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.NANO_OF_SECOND), true);
917         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.NANO_OF_DAY), true);
918         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MICRO_OF_SECOND), true);
919         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MICRO_OF_DAY), true);
920         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MILLI_OF_SECOND), true);
921         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MILLI_OF_DAY), true);
922         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.SECOND_OF_MINUTE), true);
923         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.SECOND_OF_DAY), true);
924         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MINUTE_OF_HOUR), true);
925         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MINUTE_OF_DAY), true);
926         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.HOUR_OF_AMPM), true);
927         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), true);
928         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.HOUR_OF_DAY), true);
929         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), true);
930         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.AMPM_OF_DAY), true);
931         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.DAY_OF_WEEK), true);
932         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), true);
933         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), true);
934         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.DAY_OF_MONTH), true);
935         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.DAY_OF_YEAR), true);
936         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.EPOCH_DAY), true);
937         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), true);
938         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), true);
939         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.MONTH_OF_YEAR), true);
940         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.PROLEPTIC_MONTH), true);
941         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.YEAR), true);
942         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.YEAR_OF_ERA), true);
943         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.ERA), true);
944         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.INSTANT_SECONDS), false);
945         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoField.OFFSET_SECONDS), false);
946     }
947 
948     //-----------------------------------------------------------------------
949     // isSupported(TemporalUnit)
950     //-----------------------------------------------------------------------
951     @Test
952     public void test_isSupported_TemporalUnit() {
953         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported((TemporalUnit) null), false);
954         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.NANOS), true);
955         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.MICROS), true);
956         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.MILLIS), true);
957         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.SECONDS), true);
958         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.MINUTES), true);
959         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.HOURS), true);
960         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.HALF_DAYS), true);
961         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.DAYS), true);
962         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.WEEKS), true);
963         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.MONTHS), true);
964         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.YEARS), true);
965         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.DECADES), true);
966         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.CENTURIES), true);
967         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.MILLENNIA), true);
968         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.ERAS), true);
969         assertEquals(TEST_2007_07_15_12_30_40_987654321.isSupported(ChronoUnit.FOREVER), false);
970     }
971 
972     //-----------------------------------------------------------------------
973     // get(TemporalField)
974     //-----------------------------------------------------------------------
975     @Test
976     public void test_get_TemporalField() {
977         LocalDateTime test = LocalDateTime.of(2008, 6, 30, 12, 30, 40, 987654321);
978         assertEquals(test.get(ChronoField.YEAR), 2008);
979         assertEquals(test.get(ChronoField.MONTH_OF_YEAR), 6);
980         assertEquals(test.get(ChronoField.DAY_OF_MONTH), 30);
981         assertEquals(test.get(ChronoField.DAY_OF_WEEK), 1);
982         assertEquals(test.get(ChronoField.DAY_OF_YEAR), 182);
983 
984         assertEquals(test.get(ChronoField.HOUR_OF_DAY), 12);
985         assertEquals(test.get(ChronoField.MINUTE_OF_HOUR), 30);
986         assertEquals(test.get(ChronoField.SECOND_OF_MINUTE), 40);
987         assertEquals(test.get(ChronoField.NANO_OF_SECOND), 987654321);
988         assertEquals(test.get(ChronoField.HOUR_OF_AMPM), 0);
989         assertEquals(test.get(ChronoField.AMPM_OF_DAY), 1);
990     }
991 
992     @Test
993     public void test_getLong_TemporalField() {
994         LocalDateTime test = LocalDateTime.of(2008, 6, 30, 12, 30, 40, 987654321);
995         assertEquals(test.getLong(ChronoField.YEAR), 2008);
996         assertEquals(test.getLong(ChronoField.MONTH_OF_YEAR), 6);
997         assertEquals(test.getLong(ChronoField.DAY_OF_MONTH), 30);
998         assertEquals(test.getLong(ChronoField.DAY_OF_WEEK), 1);
999         assertEquals(test.getLong(ChronoField.DAY_OF_YEAR), 182);
1000 
1001         assertEquals(test.getLong(ChronoField.HOUR_OF_DAY), 12);
1002         assertEquals(test.getLong(ChronoField.MINUTE_OF_HOUR), 30);
1003         assertEquals(test.getLong(ChronoField.SECOND_OF_MINUTE), 40);
1004         assertEquals(test.getLong(ChronoField.NANO_OF_SECOND), 987654321);
1005         assertEquals(test.getLong(ChronoField.HOUR_OF_AMPM), 0);
1006         assertEquals(test.getLong(ChronoField.AMPM_OF_DAY), 1);
1007     }
1008 
1009     //-----------------------------------------------------------------------
1010     // query(TemporalQuery)
1011     //-----------------------------------------------------------------------
1012     @DataProvider(name="query")
1013     Object[][] data_query() {
1014         return new Object[][] {
1015                 {TEST_2007_07_15_12_30_40_987654321, TemporalQueries.chronology(), IsoChronology.INSTANCE},
1016                 {TEST_2007_07_15_12_30_40_987654321, TemporalQueries.zoneId(), null},
1017                 {TEST_2007_07_15_12_30_40_987654321, TemporalQueries.precision(), ChronoUnit.NANOS},
1018                 {TEST_2007_07_15_12_30_40_987654321, TemporalQueries.zone(), null},
1019                 {TEST_2007_07_15_12_30_40_987654321, TemporalQueries.offset(), null},
1020                 {TEST_2007_07_15_12_30_40_987654321, TemporalQueries.localDate(), LocalDate.of(2007, 7, 15)},
1021                 {TEST_2007_07_15_12_30_40_987654321, TemporalQueries.localTime(), LocalTime.of(12, 30, 40, 987654321)},
1022         };
1023     }
1024 
1025     @Test(dataProvider="query")
1026     public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
1027         assertEquals(temporal.query(query), expected);
1028     }
1029 
1030     @Test(dataProvider="query")
1031     public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
1032         assertEquals(query.queryFrom(temporal), expected);
1033     }
1034 
1035     @Test(expectedExceptions=NullPointerException.class)
1036     public void test_query_null() {
1037         TEST_2007_07_15_12_30_40_987654321.query(null);
1038     }
1039 
1040     //-----------------------------------------------------------------------
1041     @DataProvider(name="sampleDates")
1042     Object[][] provider_sampleDates() {
1043         return new Object[][] {
1044             {2008, 7, 5},
1045             {2007, 7, 5},
1046             {2006, 7, 5},
1047             {2005, 7, 5},
1048             {2004, 1, 1},
1049             {-1, 1, 2},
1050         };
1051     }
1052 
1053     @DataProvider(name="sampleTimes")
1054     Object[][] provider_sampleTimes() {
1055         return new Object[][] {
1056             {0, 0, 0, 0},
1057             {0, 0, 0, 1},
1058             {0, 0, 1, 0},
1059             {0, 0, 1, 1},
1060             {0, 1, 0, 0},
1061             {0, 1, 0, 1},
1062             {0, 1, 1, 0},
1063             {0, 1, 1, 1},
1064             {1, 0, 0, 0},
1065             {1, 0, 0, 1},
1066             {1, 0, 1, 0},
1067             {1, 0, 1, 1},
1068             {1, 1, 0, 0},
1069             {1, 1, 0, 1},
1070             {1, 1, 1, 0},
1071             {1, 1, 1, 1},
1072         };
1073     }
1074 
1075     //-----------------------------------------------------------------------
1076     // get*()
1077     //-----------------------------------------------------------------------
1078     @Test(dataProvider="sampleDates")
1079     public void test_get_dates(int y, int m, int d) {
1080         LocalDateTime a = LocalDateTime.of(y, m, d, 12, 30);
1081         assertEquals(a.getYear(), y);
1082         assertEquals(a.getMonth(), Month.of(m));
1083         assertEquals(a.getDayOfMonth(), d);
1084     }
1085 
1086     @Test(dataProvider="sampleDates")
1087     public void test_getDOY(int y, int m, int d) {
1088         LocalDateTime a = LocalDateTime.of(y, m, d, 12 ,30);
1089         int total = 0;
1090         for (int i = 1; i < m; i++) {
1091             total += Month.of(i).length(isIsoLeap(y));
1092         }
1093         int doy = total + d;
1094         assertEquals(a.getDayOfYear(), doy);
1095     }
1096 
1097     @Test(dataProvider="sampleTimes")
1098     public void test_get_times(int h, int m, int s, int ns) {
1099         LocalDateTime a = LocalDateTime.of(TEST_2007_07_15_12_30_40_987654321.toLocalDate(), LocalTime.of(h, m, s, ns));
1100         assertEquals(a.getHour(), h);
1101         assertEquals(a.getMinute(), m);
1102         assertEquals(a.getSecond(), s);
1103         assertEquals(a.getNano(), ns);
1104     }
1105 
1106     //-----------------------------------------------------------------------
1107     // getDayOfWeek()
1108     //-----------------------------------------------------------------------
1109     @Test
1110     public void test_getDayOfWeek() {
1111         DayOfWeek dow = DayOfWeek.MONDAY;
1112         for (Month month : Month.values()) {
1113             int length = month.length(false);
1114             for (int i = 1; i <= length; i++) {
1115                 LocalDateTime d = LocalDateTime.of(LocalDate.of(2007, month, i),
1116                         TEST_2007_07_15_12_30_40_987654321.toLocalTime());
1117                 assertSame(d.getDayOfWeek(), dow);
1118                 dow = dow.plus(1);
1119             }
1120         }
1121     }
1122 
1123     //-----------------------------------------------------------------------
1124     // adjustInto(Temporal)
1125     //-----------------------------------------------------------------------
1126     @DataProvider(name="adjustInto")
1127     Object[][] data_adjustInto() {
1128         return new Object[][]{
1129                 {LocalDateTime.of(2012, 3, 4, 23, 5), LocalDateTime.of(2012, 3, 4, 1, 1, 1, 100), LocalDateTime.of(2012, 3, 4, 23, 5, 0, 0), null},
1130                 {LocalDateTime.of(2012, Month.MARCH, 4, 0, 0), LocalDateTime.of(2012, 3, 4, 1, 1, 1, 100), LocalDateTime.of(2012, 3, 4, 0, 0), null},
1131                 {LocalDateTime.of(2012, 3, 4, 23, 5), LocalDateTime.MAX, LocalDateTime.of(2012, 3, 4, 23, 5), null},
1132                 {LocalDateTime.of(2012, 3, 4, 23, 5), LocalDateTime.MIN, LocalDateTime.of(2012, 3, 4, 23, 5), null},
1133                 {LocalDateTime.MAX, LocalDateTime.of(2012, 3, 4, 23, 5), LocalDateTime.MAX, null},
1134                 {LocalDateTime.MIN, LocalDateTime.of(2012, 3, 4, 23, 5), LocalDateTime.MIN, null},
1135 
1136                 {LocalDateTime.of(2012, 3, 4, 23, 5), OffsetDateTime.of(2210, 2, 2, 0, 0, 0, 0, ZoneOffset.UTC), OffsetDateTime.of(2012, 3, 4, 23, 5, 0, 0, ZoneOffset.UTC), null},
1137                 {LocalDateTime.of(2012, 3, 4, 23, 5), OffsetDateTime.of(2210, 2, 2, 0, 0, 0, 0, OFFSET_PONE), OffsetDateTime.of(2012, 3, 4, 23, 5, 0, 0, OFFSET_PONE), null},
1138                 {LocalDateTime.of(2012, 3, 4, 23, 5), ZonedDateTime.of(2210, 2, 2, 0, 0, 0, 0, ZONE_PARIS), ZonedDateTime.of(2012, 3, 4, 23, 5, 0, 0, ZONE_PARIS), null},
1139 
1140                 {LocalDateTime.of(2012, 3, 4, 23, 5), LocalDate.of(2210, 2, 2), null, DateTimeException.class},
1141                 {LocalDateTime.of(2012, 3, 4, 23, 5), LocalTime.of(22, 3, 0), null, DateTimeException.class},
1142                 {LocalDateTime.of(2012, 3, 4, 23, 5), OffsetTime.of(22, 3, 0, 0, ZoneOffset.UTC), null, DateTimeException.class},
1143                 {LocalDateTime.of(2012, 3, 4, 23, 5), null, null, NullPointerException.class},
1144 
1145         };
1146     }
1147 
1148     @Test(dataProvider="adjustInto")
1149     public void test_adjustInto(LocalDateTime test, Temporal temporal, Temporal expected, Class<?> expectedEx) {
1150         if (expectedEx == null) {
1151             Temporal result = test.adjustInto(temporal);
1152             assertEquals(result, expected);
1153         } else {
1154             try {
1155                 Temporal result = test.adjustInto(temporal);
1156                 fail();
1157             } catch (Exception ex) {
1158                 assertTrue(expectedEx.isInstance(ex));
1159             }
1160         }
1161     }
1162 
1163     //-----------------------------------------------------------------------
1164     // with()
1165     //-----------------------------------------------------------------------
1166     @Test
1167     public void test_with_adjustment() {
1168         final LocalDateTime sample = LocalDateTime.of(2012, 3, 4, 23, 5);
1169         TemporalAdjuster adjuster = new TemporalAdjuster() {
1170             @Override
1171             public Temporal adjustInto(Temporal dateTime) {
1172                 return sample;
1173             }
1174         };
1175         assertEquals(TEST_2007_07_15_12_30_40_987654321.with(adjuster), sample);
1176     }
1177 
1178     @Test(expectedExceptions=NullPointerException.class)
1179     public void test_with_adjustment_null() {
1180         TEST_2007_07_15_12_30_40_987654321.with((TemporalAdjuster) null);
1181     }
1182 
1183     //-----------------------------------------------------------------------
1184     // withYear()
1185     //-----------------------------------------------------------------------
1186     @Test
1187     public void test_withYear_int_normal() {
1188         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.withYear(2008);
1189         check(t, 2008, 7, 15, 12, 30, 40, 987654321);
1190     }
1191 
1192     @Test(expectedExceptions=DateTimeException.class)
1193     public void test_withYear_int_invalid() {
1194         TEST_2007_07_15_12_30_40_987654321.withYear(Year.MIN_VALUE - 1);
1195     }
1196 
1197     @Test
1198     public void test_withYear_int_adjustDay() {
1199         LocalDateTime t = LocalDateTime.of(2008, 2, 29, 12, 30).withYear(2007);
1200         LocalDateTime expected = LocalDateTime.of(2007, 2, 28, 12, 30);
1201         assertEquals(t, expected);
1202     }
1203 
1204     //-----------------------------------------------------------------------
1205     // withMonth()
1206     //-----------------------------------------------------------------------
1207     @Test
1208     public void test_withMonth_int_normal() {
1209         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.withMonth(1);
1210         check(t, 2007, 1, 15, 12, 30, 40, 987654321);
1211     }
1212 
1213     @Test(expectedExceptions=DateTimeException.class)
1214     public void test_withMonth_int_invalid() {
1215         TEST_2007_07_15_12_30_40_987654321.withMonth(13);
1216     }
1217 
1218     @Test
1219     public void test_withMonth_int_adjustDay() {
1220         LocalDateTime t = LocalDateTime.of(2007, 12, 31, 12, 30).withMonth(11);
1221         LocalDateTime expected = LocalDateTime.of(2007, 11, 30, 12, 30);
1222         assertEquals(t, expected);
1223     }
1224 
1225     //-----------------------------------------------------------------------
1226     // withDayOfMonth()
1227     //-----------------------------------------------------------------------
1228     @Test
1229     public void test_withDayOfMonth_normal() {
1230         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.withDayOfMonth(1);
1231         check(t, 2007, 7, 1, 12, 30, 40, 987654321);
1232     }
1233 
1234     @Test(expectedExceptions=DateTimeException.class)
1235     public void test_withDayOfMonth_invalid() {
1236         LocalDateTime.of(2007, 11, 30, 12, 30).withDayOfMonth(32);
1237     }
1238 
1239     @Test(expectedExceptions=DateTimeException.class)
1240     public void test_withDayOfMonth_invalidCombination() {
1241         LocalDateTime.of(2007, 11, 30, 12, 30).withDayOfMonth(31);
1242     }
1243 
1244     //-----------------------------------------------------------------------
1245     // withDayOfYear(int)
1246     //-----------------------------------------------------------------------
1247     @Test
1248     public void test_withDayOfYear_normal() {
1249         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.withDayOfYear(33);
1250         assertEquals(t, LocalDateTime.of(2007, 2, 2, 12, 30, 40, 987654321));
1251     }
1252 
1253     @Test(expectedExceptions=DateTimeException.class)
1254     public void test_withDayOfYear_illegal() {
1255         TEST_2007_07_15_12_30_40_987654321.withDayOfYear(367);
1256     }
1257 
1258     @Test(expectedExceptions=DateTimeException.class)
1259     public void test_withDayOfYear_invalid() {
1260         TEST_2007_07_15_12_30_40_987654321.withDayOfYear(366);
1261     }
1262 
1263     //-----------------------------------------------------------------------
1264     // withHour()
1265     //-----------------------------------------------------------------------
1266     @Test
1267     public void test_withHour_normal() {
1268         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321;
1269         for (int i = 0; i < 24; i++) {
1270             t = t.withHour(i);
1271             assertEquals(t.getHour(), i);
1272         }
1273     }
1274 
1275     @Test(expectedExceptions=DateTimeException.class)
1276     public void test_withHour_hourTooLow() {
1277         TEST_2007_07_15_12_30_40_987654321.withHour(-1);
1278     }
1279 
1280     @Test(expectedExceptions=DateTimeException.class)
1281     public void test_withHour_hourTooHigh() {
1282         TEST_2007_07_15_12_30_40_987654321.withHour(24);
1283     }
1284 
1285     //-----------------------------------------------------------------------
1286     // withMinute()
1287     //-----------------------------------------------------------------------
1288     @Test
1289     public void test_withMinute_normal() {
1290         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321;
1291         for (int i = 0; i < 60; i++) {
1292             t = t.withMinute(i);
1293             assertEquals(t.getMinute(), i);
1294         }
1295     }
1296 
1297     @Test(expectedExceptions=DateTimeException.class)
1298     public void test_withMinute_minuteTooLow() {
1299         TEST_2007_07_15_12_30_40_987654321.withMinute(-1);
1300     }
1301 
1302     @Test(expectedExceptions=DateTimeException.class)
1303     public void test_withMinute_minuteTooHigh() {
1304         TEST_2007_07_15_12_30_40_987654321.withMinute(60);
1305     }
1306 
1307     //-----------------------------------------------------------------------
1308     // withSecond()
1309     //-----------------------------------------------------------------------
1310     @Test
1311     public void test_withSecond_normal() {
1312         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321;
1313         for (int i = 0; i < 60; i++) {
1314             t = t.withSecond(i);
1315             assertEquals(t.getSecond(), i);
1316         }
1317     }
1318 
1319     @Test(expectedExceptions=DateTimeException.class)
1320     public void test_withSecond_secondTooLow() {
1321         TEST_2007_07_15_12_30_40_987654321.withSecond(-1);
1322     }
1323 
1324     @Test(expectedExceptions=DateTimeException.class)
1325     public void test_withSecond_secondTooHigh() {
1326         TEST_2007_07_15_12_30_40_987654321.withSecond(60);
1327     }
1328 
1329     //-----------------------------------------------------------------------
1330     // withNano()
1331     //-----------------------------------------------------------------------
1332     @Test
1333     public void test_withNanoOfSecond_normal() {
1334         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321;
1335         t = t.withNano(1);
1336         assertEquals(t.getNano(), 1);
1337         t = t.withNano(10);
1338         assertEquals(t.getNano(), 10);
1339         t = t.withNano(100);
1340         assertEquals(t.getNano(), 100);
1341         t = t.withNano(999999999);
1342         assertEquals(t.getNano(), 999999999);
1343     }
1344 
1345     @Test(expectedExceptions=DateTimeException.class)
1346     public void test_withNanoOfSecond_nanoTooLow() {
1347         TEST_2007_07_15_12_30_40_987654321.withNano(-1);
1348     }
1349 
1350     @Test(expectedExceptions=DateTimeException.class)
1351     public void test_withNanoOfSecond_nanoTooHigh() {
1352         TEST_2007_07_15_12_30_40_987654321.withNano(1000000000);
1353     }
1354 
1355     //-----------------------------------------------------------------------
1356     // truncatedTo(TemporalUnit)
1357     //-----------------------------------------------------------------------
1358     @Test
1359     public void test_truncatedTo_normal() {
1360         assertEquals(TEST_2007_07_15_12_30_40_987654321.truncatedTo(NANOS), TEST_2007_07_15_12_30_40_987654321);
1361         assertEquals(TEST_2007_07_15_12_30_40_987654321.truncatedTo(SECONDS), TEST_2007_07_15_12_30_40_987654321.withNano(0));
1362         assertEquals(TEST_2007_07_15_12_30_40_987654321.truncatedTo(DAYS), TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT));
1363     }
1364 
1365     @Test(expectedExceptions=NullPointerException.class)
1366     public void test_truncatedTo_null() {
1367         TEST_2007_07_15_12_30_40_987654321.truncatedTo(null);
1368     }
1369 
1370     //-----------------------------------------------------------------------
1371     // plus(TemporalAmount)
1372     //-----------------------------------------------------------------------
1373     @Test
1374     public void test_plus_TemporalAmount_positiveMonths() {
1375         MockSimplePeriod period = MockSimplePeriod.of(7, MONTHS);
1376         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plus(period);
1377         assertEquals(t, LocalDateTime.of(2008, 2, 15, 12, 30, 40, 987654321));
1378     }
1379 
1380     @Test
1381     public void test_plus_TemporalAmount_negativeDays() {
1382         MockSimplePeriod period = MockSimplePeriod.of(-25, DAYS);
1383         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plus(period);
1384         assertEquals(t, LocalDateTime.of(2007, 6, 20, 12, 30, 40, 987654321));
1385     }
1386 
1387     @Test(expectedExceptions=DateTimeException.class)
1388     public void test_plus_TemporalAmount_invalidTooLarge() {
1389         MockSimplePeriod period = MockSimplePeriod.of(1, YEARS);
1390         LocalDateTime.of(Year.MAX_VALUE, 1, 1, 0, 0).plus(period);
1391     }
1392 
1393     @Test(expectedExceptions=DateTimeException.class)
1394     public void test_plus_TemporalAmount_invalidTooSmall() {
1395         MockSimplePeriod period = MockSimplePeriod.of(-1, YEARS);
1396         LocalDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0).plus(period);
1397     }
1398 
1399     @Test(expectedExceptions=NullPointerException.class)
1400     public void test_plus_TemporalAmount_null() {
1401         TEST_2007_07_15_12_30_40_987654321.plus((TemporalAmount) null);
1402     }
1403 
1404     //-----------------------------------------------------------------------
1405     // plus(long,TemporalUnit)
1406     //-----------------------------------------------------------------------
1407     @Test
1408     public void test_plus_longTemporalUnit_positiveMonths() {
1409         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plus(7, ChronoUnit.MONTHS);
1410         assertEquals(t, LocalDateTime.of(2008, 2, 15, 12, 30, 40, 987654321));
1411     }
1412 
1413     @Test
1414     public void test_plus_longTemporalUnit_negativeDays() {
1415         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plus(-25, ChronoUnit.DAYS);
1416         assertEquals(t, LocalDateTime.of(2007, 6, 20, 12, 30, 40, 987654321));
1417     }
1418 
1419     @Test(expectedExceptions=NullPointerException.class)
1420     public void test_plus_longTemporalUnit_null() {
1421         TEST_2007_07_15_12_30_40_987654321.plus(1, (TemporalUnit) null);
1422     }
1423 
1424     @Test(expectedExceptions=DateTimeException.class)
1425     public void test_plus_longTemporalUnit_invalidTooLarge() {
1426         LocalDateTime.of(Year.MAX_VALUE, 1, 1, 0, 0).plus(1, ChronoUnit.YEARS);
1427     }
1428 
1429     @Test(expectedExceptions=DateTimeException.class)
1430     public void test_plus_longTemporalUnit_invalidTooSmall() {
1431         LocalDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0).plus(-1, ChronoUnit.YEARS);
1432     }
1433 
1434     //-----------------------------------------------------------------------
1435     // plusYears()
1436     //-----------------------------------------------------------------------
1437     @Test
1438     public void test_plusYears_int_normal() {
1439         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusYears(1);
1440         check(t, 2008, 7, 15, 12, 30, 40, 987654321);
1441     }
1442 
1443     @Test
1444     public void test_plusYears_int_negative() {
1445         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusYears(-1);
1446         check(t, 2006, 7, 15, 12, 30, 40, 987654321);
1447     }
1448 
1449     @Test
1450     public void test_plusYears_int_adjustDay() {
1451         LocalDateTime t = createDateMidnight(2008, 2, 29).plusYears(1);
1452         check(t, 2009, 2, 28, 0, 0, 0, 0);
1453     }
1454 
1455     @Test(expectedExceptions=DateTimeException.class)
1456     public void test_plusYears_int_invalidTooLarge() {
1457         createDateMidnight(Year.MAX_VALUE, 1, 1).plusYears(1);
1458     }
1459 
1460     @Test(expectedExceptions=DateTimeException.class)
1461     public void test_plusYears_int_invalidTooSmall() {
1462         LocalDate.of(Year.MIN_VALUE, 1, 1).plusYears(-1);
1463     }
1464 
1465     //-----------------------------------------------------------------------
1466     // plusMonths()
1467     //-----------------------------------------------------------------------
1468     @Test
1469     public void test_plusMonths_int_normal() {
1470         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusMonths(1);
1471         check(t, 2007, 8, 15, 12, 30, 40, 987654321);
1472     }
1473 
1474     @Test
1475     public void test_plusMonths_int_overYears() {
1476         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusMonths(25);
1477         check(t, 2009, 8, 15, 12, 30, 40, 987654321);
1478     }
1479 
1480     @Test
1481     public void test_plusMonths_int_negative() {
1482         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusMonths(-1);
1483         check(t, 2007, 6, 15, 12, 30, 40, 987654321);
1484     }
1485 
1486     @Test
1487     public void test_plusMonths_int_negativeAcrossYear() {
1488         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusMonths(-7);
1489         check(t, 2006, 12, 15, 12, 30, 40, 987654321);
1490     }
1491 
1492     @Test
1493     public void test_plusMonths_int_negativeOverYears() {
1494         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusMonths(-31);
1495         check(t, 2004, 12, 15, 12, 30, 40, 987654321);
1496     }
1497 
1498     @Test
1499     public void test_plusMonths_int_adjustDayFromLeapYear() {
1500         LocalDateTime t = createDateMidnight(2008, 2, 29).plusMonths(12);
1501         check(t, 2009, 2, 28, 0, 0, 0, 0);
1502     }
1503 
1504     @Test
1505     public void test_plusMonths_int_adjustDayFromMonthLength() {
1506         LocalDateTime t = createDateMidnight(2007, 3, 31).plusMonths(1);
1507         check(t, 2007, 4, 30, 0, 0, 0, 0);
1508     }
1509 
1510     @Test(expectedExceptions=DateTimeException.class)
1511     public void test_plusMonths_int_invalidTooLarge() {
1512         createDateMidnight(Year.MAX_VALUE, 12, 1).plusMonths(1);
1513     }
1514 
1515     @Test(expectedExceptions=DateTimeException.class)
1516     public void test_plusMonths_int_invalidTooSmall() {
1517         createDateMidnight(Year.MIN_VALUE, 1, 1).plusMonths(-1);
1518     }
1519 
1520     //-----------------------------------------------------------------------
1521     // plusWeeks()
1522     //-----------------------------------------------------------------------
1523     @DataProvider(name="samplePlusWeeksSymmetry")
1524     Object[][] provider_samplePlusWeeksSymmetry() {
1525         return new Object[][] {
1526             {createDateMidnight(-1, 1, 1)},
1527             {createDateMidnight(-1, 2, 28)},
1528             {createDateMidnight(-1, 3, 1)},
1529             {createDateMidnight(-1, 12, 31)},
1530             {createDateMidnight(0, 1, 1)},
1531             {createDateMidnight(0, 2, 28)},
1532             {createDateMidnight(0, 2, 29)},
1533             {createDateMidnight(0, 3, 1)},
1534             {createDateMidnight(0, 12, 31)},
1535             {createDateMidnight(2007, 1, 1)},
1536             {createDateMidnight(2007, 2, 28)},
1537             {createDateMidnight(2007, 3, 1)},
1538             {createDateMidnight(2007, 12, 31)},
1539             {createDateMidnight(2008, 1, 1)},
1540             {createDateMidnight(2008, 2, 28)},
1541             {createDateMidnight(2008, 2, 29)},
1542             {createDateMidnight(2008, 3, 1)},
1543             {createDateMidnight(2008, 12, 31)},
1544             {createDateMidnight(2099, 1, 1)},
1545             {createDateMidnight(2099, 2, 28)},
1546             {createDateMidnight(2099, 3, 1)},
1547             {createDateMidnight(2099, 12, 31)},
1548             {createDateMidnight(2100, 1, 1)},
1549             {createDateMidnight(2100, 2, 28)},
1550             {createDateMidnight(2100, 3, 1)},
1551             {createDateMidnight(2100, 12, 31)},
1552         };
1553     }
1554 
1555     @Test(dataProvider="samplePlusWeeksSymmetry")
1556     public void test_plusWeeks_symmetry(LocalDateTime reference) {
1557         for (int weeks = 0; weeks < 365 * 8; weeks++) {
1558             LocalDateTime t = reference.plusWeeks(weeks).plusWeeks(-weeks);
1559             assertEquals(t, reference);
1560 
1561             t = reference.plusWeeks(-weeks).plusWeeks(weeks);
1562             assertEquals(t, reference);
1563         }
1564     }
1565 
1566     @Test
1567     public void test_plusWeeks_normal() {
1568         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusWeeks(1);
1569         check(t, 2007, 7, 22, 12, 30, 40, 987654321);
1570     }
1571 
1572     @Test
1573     public void test_plusWeeks_overMonths() {
1574         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusWeeks(9);
1575         check(t, 2007, 9, 16, 12, 30, 40, 987654321);
1576     }
1577 
1578     @Test
1579     public void test_plusWeeks_overYears() {
1580         LocalDateTime t = LocalDateTime.of(2006, 7, 16, 12, 30, 40, 987654321).plusWeeks(52);
1581         assertEquals(t, TEST_2007_07_15_12_30_40_987654321);
1582     }
1583 
1584     @Test
1585     public void test_plusWeeks_overLeapYears() {
1586         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusYears(-1).plusWeeks(104);
1587         check(t, 2008, 7, 12, 12, 30, 40, 987654321);
1588     }
1589 
1590     @Test
1591     public void test_plusWeeks_negative() {
1592         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusWeeks(-1);
1593         check(t, 2007, 7, 8, 12, 30, 40, 987654321);
1594     }
1595 
1596     @Test
1597     public void test_plusWeeks_negativeAcrossYear() {
1598         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusWeeks(-28);
1599         check(t, 2006, 12, 31, 12, 30, 40, 987654321);
1600     }
1601 
1602     @Test
1603     public void test_plusWeeks_negativeOverYears() {
1604         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusWeeks(-104);
1605         check(t, 2005, 7, 17, 12, 30, 40, 987654321);
1606     }
1607 
1608     @Test
1609     public void test_plusWeeks_maximum() {
1610         LocalDateTime t = createDateMidnight(Year.MAX_VALUE, 12, 24).plusWeeks(1);
1611         check(t, Year.MAX_VALUE, 12, 31, 0, 0, 0, 0);
1612     }
1613 
1614     @Test
1615     public void test_plusWeeks_minimum() {
1616         LocalDateTime t = createDateMidnight(Year.MIN_VALUE, 1, 8).plusWeeks(-1);
1617         check(t, Year.MIN_VALUE, 1, 1, 0, 0, 0, 0);
1618     }
1619 
1620     @Test(expectedExceptions=DateTimeException.class)
1621     public void test_plusWeeks_invalidTooLarge() {
1622         createDateMidnight(Year.MAX_VALUE, 12, 25).plusWeeks(1);
1623     }
1624 
1625     @Test(expectedExceptions=DateTimeException.class)
1626     public void test_plusWeeks_invalidTooSmall() {
1627         createDateMidnight(Year.MIN_VALUE, 1, 7).plusWeeks(-1);
1628     }
1629 
1630     //-----------------------------------------------------------------------
1631     // plusDays()
1632     //-----------------------------------------------------------------------
1633     @DataProvider(name="samplePlusDaysSymmetry")
1634     Object[][] provider_samplePlusDaysSymmetry() {
1635         return new Object[][] {
1636             {createDateMidnight(-1, 1, 1)},
1637             {createDateMidnight(-1, 2, 28)},
1638             {createDateMidnight(-1, 3, 1)},
1639             {createDateMidnight(-1, 12, 31)},
1640             {createDateMidnight(0, 1, 1)},
1641             {createDateMidnight(0, 2, 28)},
1642             {createDateMidnight(0, 2, 29)},
1643             {createDateMidnight(0, 3, 1)},
1644             {createDateMidnight(0, 12, 31)},
1645             {createDateMidnight(2007, 1, 1)},
1646             {createDateMidnight(2007, 2, 28)},
1647             {createDateMidnight(2007, 3, 1)},
1648             {createDateMidnight(2007, 12, 31)},
1649             {createDateMidnight(2008, 1, 1)},
1650             {createDateMidnight(2008, 2, 28)},
1651             {createDateMidnight(2008, 2, 29)},
1652             {createDateMidnight(2008, 3, 1)},
1653             {createDateMidnight(2008, 12, 31)},
1654             {createDateMidnight(2099, 1, 1)},
1655             {createDateMidnight(2099, 2, 28)},
1656             {createDateMidnight(2099, 3, 1)},
1657             {createDateMidnight(2099, 12, 31)},
1658             {createDateMidnight(2100, 1, 1)},
1659             {createDateMidnight(2100, 2, 28)},
1660             {createDateMidnight(2100, 3, 1)},
1661             {createDateMidnight(2100, 12, 31)},
1662         };
1663     }
1664 
1665     @Test(dataProvider="samplePlusDaysSymmetry")
1666     public void test_plusDays_symmetry(LocalDateTime reference) {
1667         for (int days = 0; days < 365 * 8; days++) {
1668             LocalDateTime t = reference.plusDays(days).plusDays(-days);
1669             assertEquals(t, reference);
1670 
1671             t = reference.plusDays(-days).plusDays(days);
1672             assertEquals(t, reference);
1673         }
1674     }
1675 
1676     @Test
1677     public void test_plusDays_normal() {
1678         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusDays(1);
1679         check(t, 2007, 7, 16, 12, 30, 40, 987654321);
1680     }
1681 
1682     @Test
1683     public void test_plusDays_overMonths() {
1684         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusDays(62);
1685         check(t, 2007, 9, 15, 12, 30, 40, 987654321);
1686     }
1687 
1688     @Test
1689     public void test_plusDays_overYears() {
1690         LocalDateTime t = LocalDateTime.of(2006, 7, 14, 12, 30, 40, 987654321).plusDays(366);
1691         assertEquals(t, TEST_2007_07_15_12_30_40_987654321);
1692     }
1693 
1694     @Test
1695     public void test_plusDays_overLeapYears() {
1696         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusYears(-1).plusDays(365 + 366);
1697         check(t, 2008, 7, 15, 12, 30, 40, 987654321);
1698     }
1699 
1700     @Test
1701     public void test_plusDays_negative() {
1702         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusDays(-1);
1703         check(t, 2007, 7, 14, 12, 30, 40, 987654321);
1704     }
1705 
1706     @Test
1707     public void test_plusDays_negativeAcrossYear() {
1708         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusDays(-196);
1709         check(t, 2006, 12, 31, 12, 30, 40, 987654321);
1710     }
1711 
1712     @Test
1713     public void test_plusDays_negativeOverYears() {
1714         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusDays(-730);
1715         check(t, 2005, 7, 15, 12, 30, 40, 987654321);
1716     }
1717 
1718     @Test
1719     public void test_plusDays_maximum() {
1720         LocalDateTime t = createDateMidnight(Year.MAX_VALUE, 12, 30).plusDays(1);
1721         check(t, Year.MAX_VALUE, 12, 31, 0, 0, 0, 0);
1722     }
1723 
1724     @Test
1725     public void test_plusDays_minimum() {
1726         LocalDateTime t = createDateMidnight(Year.MIN_VALUE, 1, 2).plusDays(-1);
1727         check(t, Year.MIN_VALUE, 1, 1, 0, 0, 0, 0);
1728     }
1729 
1730     @Test(expectedExceptions=DateTimeException.class)
1731     public void test_plusDays_invalidTooLarge() {
1732         createDateMidnight(Year.MAX_VALUE, 12, 31).plusDays(1);
1733     }
1734 
1735     @Test(expectedExceptions=DateTimeException.class)
1736     public void test_plusDays_invalidTooSmall() {
1737         createDateMidnight(Year.MIN_VALUE, 1, 1).plusDays(-1);
1738     }
1739 
1740     @Test(expectedExceptions=ArithmeticException.class)
1741     public void test_plusDays_overflowTooLarge() {
1742         createDateMidnight(Year.MAX_VALUE, 12, 31).plusDays(Long.MAX_VALUE);
1743     }
1744 
1745     @Test(expectedExceptions=ArithmeticException.class)
1746     public void test_plusDays_overflowTooSmall() {
1747         createDateMidnight(Year.MIN_VALUE, 1, 1).plusDays(Long.MIN_VALUE);
1748     }
1749 
1750     //-----------------------------------------------------------------------
1751     // plusHours()
1752     //-----------------------------------------------------------------------
1753     @Test
1754     public void test_plusHours_one() {
1755         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
1756         LocalDate d = t.toLocalDate();
1757 
1758         for (int i = 0; i < 50; i++) {
1759             t = t.plusHours(1);
1760 
1761             if ((i + 1) % 24 == 0) {
1762                 d = d.plusDays(1);
1763             }
1764 
1765             assertEquals(t.toLocalDate(), d);
1766             assertEquals(t.getHour(), (i + 1) % 24);
1767         }
1768     }
1769 
1770     @Test
1771     public void test_plusHours_fromZero() {
1772         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
1773         LocalDate d = base.toLocalDate().minusDays(3);
1774         LocalTime t = LocalTime.of(21, 0);
1775 
1776         for (int i = -50; i < 50; i++) {
1777             LocalDateTime dt = base.plusHours(i);
1778             t = t.plusHours(1);
1779 
1780             if (t.getHour() == 0) {
1781                 d = d.plusDays(1);
1782             }
1783 
1784             assertEquals(dt.toLocalDate(), d);
1785             assertEquals(dt.toLocalTime(), t);
1786         }
1787     }
1788 
1789     @Test
1790     public void test_plusHours_fromOne() {
1791         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(1, 0));
1792         LocalDate d = base.toLocalDate().minusDays(3);
1793         LocalTime t = LocalTime.of(22, 0);
1794 
1795         for (int i = -50; i < 50; i++) {
1796             LocalDateTime dt = base.plusHours(i);
1797 
1798             t = t.plusHours(1);
1799 
1800             if (t.getHour() == 0) {
1801                 d = d.plusDays(1);
1802             }
1803 
1804             assertEquals(dt.toLocalDate(), d);
1805             assertEquals(dt.toLocalTime(), t);
1806         }
1807     }
1808 
1809     //-----------------------------------------------------------------------
1810     // plusMinutes()
1811     //-----------------------------------------------------------------------
1812     @Test
1813     public void test_plusMinutes_one() {
1814         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
1815         LocalDate d = t.toLocalDate();
1816 
1817         int hour = 0;
1818         int min = 0;
1819 
1820         for (int i = 0; i < 70; i++) {
1821             t = t.plusMinutes(1);
1822             min++;
1823             if (min == 60) {
1824                 hour++;
1825                 min = 0;
1826             }
1827 
1828             assertEquals(t.toLocalDate(), d);
1829             assertEquals(t.getHour(), hour);
1830             assertEquals(t.getMinute(), min);
1831         }
1832     }
1833 
1834     @Test
1835     public void test_plusMinutes_fromZero() {
1836         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
1837         LocalDate d = base.toLocalDate().minusDays(1);
1838         LocalTime t = LocalTime.of(22, 49);
1839 
1840         for (int i = -70; i < 70; i++) {
1841             LocalDateTime dt = base.plusMinutes(i);
1842             t = t.plusMinutes(1);
1843 
1844             if (t.equals(LocalTime.MIDNIGHT)) {
1845                 d = d.plusDays(1);
1846             }
1847 
1848             assertEquals(dt.toLocalDate(), d, String.valueOf(i));
1849             assertEquals(dt.toLocalTime(), t, String.valueOf(i));
1850         }
1851     }
1852 
1853     @Test
1854     public void test_plusMinutes_noChange_oneDay() {
1855         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusMinutes(24 * 60);
1856         assertEquals(t.toLocalDate(), TEST_2007_07_15_12_30_40_987654321.toLocalDate().plusDays(1));
1857     }
1858 
1859     //-----------------------------------------------------------------------
1860     // plusSeconds()
1861     //-----------------------------------------------------------------------
1862     @Test
1863     public void test_plusSeconds_one() {
1864         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
1865         LocalDate d = t.toLocalDate();
1866 
1867         int hour = 0;
1868         int min = 0;
1869         int sec = 0;
1870 
1871         for (int i = 0; i < 3700; i++) {
1872             t = t.plusSeconds(1);
1873             sec++;
1874             if (sec == 60) {
1875                 min++;
1876                 sec = 0;
1877             }
1878             if (min == 60) {
1879                 hour++;
1880                 min = 0;
1881             }
1882 
1883             assertEquals(t.toLocalDate(), d);
1884             assertEquals(t.getHour(), hour);
1885             assertEquals(t.getMinute(), min);
1886             assertEquals(t.getSecond(), sec);
1887         }
1888     }
1889 
1890     @DataProvider(name="plusSeconds_fromZero")
1891     Iterator<Object[]> plusSeconds_fromZero() {
1892         return new Iterator<Object[]>() {
1893             int delta = 30;
1894 
1895             int i = -3660;
1896             LocalDate date = TEST_2007_07_15_12_30_40_987654321.toLocalDate().minusDays(1);
1897             int hour = 22;
1898             int min = 59;
1899             int sec = 0;
1900 
1901             public boolean hasNext() {
1902                 return i <= 3660;
1903             }
1904 
1905             public Object[] next() {
1906                 final Object[] ret = new Object[] {i, date, hour, min, sec};
1907                 i += delta;
1908                 sec += delta;
1909 
1910                 if (sec >= 60) {
1911                     min++;
1912                     sec -= 60;
1913 
1914                     if (min == 60) {
1915                         hour++;
1916                         min = 0;
1917 
1918                         if (hour == 24) {
1919                             hour = 0;
1920                         }
1921                     }
1922                 }
1923 
1924                 if (i == 0) {
1925                     date = date.plusDays(1);
1926                 }
1927 
1928                 return ret;
1929             }
1930 
1931             public void remove() {
1932                 throw new UnsupportedOperationException();
1933             }
1934         };
1935     }
1936 
1937     @Test(dataProvider="plusSeconds_fromZero")
1938     public void test_plusSeconds_fromZero(int seconds, LocalDate date, int hour, int min, int sec) {
1939         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
1940         LocalDateTime t = base.plusSeconds(seconds);
1941 
1942         assertEquals(date, t.toLocalDate());
1943         assertEquals(hour, t.getHour());
1944         assertEquals(min, t.getMinute());
1945         assertEquals(sec, t.getSecond());
1946     }
1947 
1948     @Test
1949     public void test_plusSeconds_noChange_oneDay() {
1950         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusSeconds(24 * 60 * 60);
1951         assertEquals(t.toLocalDate(), TEST_2007_07_15_12_30_40_987654321.toLocalDate().plusDays(1));
1952     }
1953 
1954     //-----------------------------------------------------------------------
1955     // plusNanos()
1956     //-----------------------------------------------------------------------
1957     @Test
1958     public void test_plusNanos_halfABillion() {
1959         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
1960         LocalDate d = t.toLocalDate();
1961 
1962         int hour = 0;
1963         int min = 0;
1964         int sec = 0;
1965         int nanos = 0;
1966 
1967         for (long i = 0; i < 3700 * 1000000000L; i+= 500000000) {
1968             t = t.plusNanos(500000000);
1969             nanos += 500000000;
1970             if (nanos == 1000000000) {
1971                 sec++;
1972                 nanos = 0;
1973             }
1974             if (sec == 60) {
1975                 min++;
1976                 sec = 0;
1977             }
1978             if (min == 60) {
1979                 hour++;
1980                 min = 0;
1981             }
1982 
1983             assertEquals(t.toLocalDate(), d, String.valueOf(i));
1984             assertEquals(t.getHour(), hour);
1985             assertEquals(t.getMinute(), min);
1986             assertEquals(t.getSecond(), sec);
1987             assertEquals(t.getNano(), nanos);
1988         }
1989     }
1990 
1991     @DataProvider(name="plusNanos_fromZero")
1992     Iterator<Object[]> plusNanos_fromZero() {
1993         return new Iterator<Object[]>() {
1994             long delta = 7500000000L;
1995 
1996             long i = -3660 * 1000000000L;
1997             LocalDate date = TEST_2007_07_15_12_30_40_987654321.toLocalDate().minusDays(1);
1998             int hour = 22;
1999             int min = 59;
2000             int sec = 0;
2001             long nanos = 0;
2002 
2003             public boolean hasNext() {
2004                 return i <= 3660 * 1000000000L;
2005             }
2006 
2007             public Object[] next() {
2008                 final Object[] ret = new Object[] {i, date, hour, min, sec, (int)nanos};
2009                 i += delta;
2010                 nanos += delta;
2011 
2012                 if (nanos >= 1000000000L) {
2013                     sec += nanos / 1000000000L;
2014                     nanos %= 1000000000L;
2015 
2016                     if (sec >= 60) {
2017                         min++;
2018                         sec %= 60;
2019 
2020                         if (min == 60) {
2021                             hour++;
2022                             min = 0;
2023 
2024                             if (hour == 24) {
2025                                 hour = 0;
2026                                 date = date.plusDays(1);
2027                             }
2028                         }
2029                     }
2030                 }
2031 
2032                 return ret;
2033             }
2034 
2035             public void remove() {
2036                 throw new UnsupportedOperationException();
2037             }
2038         };
2039     }
2040 
2041     @Test(dataProvider="plusNanos_fromZero")
2042     public void test_plusNanos_fromZero(long nanoseconds, LocalDate date, int hour, int min, int sec, int nanos) {
2043         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
2044         LocalDateTime t = base.plusNanos(nanoseconds);
2045 
2046         assertEquals(date, t.toLocalDate());
2047         assertEquals(hour, t.getHour());
2048         assertEquals(min, t.getMinute());
2049         assertEquals(sec, t.getSecond());
2050         assertEquals(nanos, t.getNano());
2051     }
2052 
2053     @Test
2054     public void test_plusNanos_noChange_oneDay() {
2055         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusNanos(24 * 60 * 60 * 1000000000L);
2056         assertEquals(t.toLocalDate(), TEST_2007_07_15_12_30_40_987654321.toLocalDate().plusDays(1));
2057     }
2058 
2059     //-----------------------------------------------------------------------
2060     // minus(TemporalAmount)
2061     //-----------------------------------------------------------------------
2062     @Test
2063     public void test_minus_TemporalAmount_positiveMonths() {
2064         MockSimplePeriod period = MockSimplePeriod.of(7, MONTHS);
2065         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minus(period);
2066         assertEquals(t, LocalDateTime.of(2006, 12, 15, 12, 30, 40, 987654321));
2067     }
2068 
2069     @Test
2070     public void test_minus_TemporalAmount_negativeDays() {
2071         MockSimplePeriod period = MockSimplePeriod.of(-25, DAYS);
2072         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minus(period);
2073         assertEquals(t, LocalDateTime.of(2007, 8, 9, 12, 30, 40, 987654321));
2074     }
2075 
2076     @Test(expectedExceptions=DateTimeException.class)
2077     public void test_minus_TemporalAmount_invalidTooLarge() {
2078         MockSimplePeriod period = MockSimplePeriod.of(-1, YEARS);
2079         LocalDateTime.of(Year.MAX_VALUE, 1, 1, 0, 0).minus(period);
2080     }
2081 
2082     @Test(expectedExceptions=DateTimeException.class)
2083     public void test_minus_TemporalAmount_invalidTooSmall() {
2084         MockSimplePeriod period = MockSimplePeriod.of(1, YEARS);
2085         LocalDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0).minus(period);
2086     }
2087 
2088     @Test(expectedExceptions=NullPointerException.class)
2089     public void test_minus_TemporalAmount_null() {
2090         TEST_2007_07_15_12_30_40_987654321.minus((TemporalAmount) null);
2091     }
2092 
2093     //-----------------------------------------------------------------------
2094     // minus(long,TemporalUnit)
2095     //-----------------------------------------------------------------------
2096     @Test
2097     public void test_minus_longTemporalUnit_positiveMonths() {
2098         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minus(7, ChronoUnit.MONTHS);
2099         assertEquals(t, LocalDateTime.of(2006, 12, 15, 12, 30, 40, 987654321));
2100     }
2101 
2102     @Test
2103     public void test_minus_longTemporalUnit_negativeDays() {
2104         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minus(-25, ChronoUnit.DAYS);
2105         assertEquals(t, LocalDateTime.of(2007, 8, 9, 12, 30, 40, 987654321));
2106     }
2107 
2108     @Test(expectedExceptions=NullPointerException.class)
2109     public void test_minus_longTemporalUnit_null() {
2110         TEST_2007_07_15_12_30_40_987654321.minus(1, (TemporalUnit) null);
2111     }
2112 
2113     @Test(expectedExceptions=DateTimeException.class)
2114     public void test_minus_longTemporalUnit_invalidTooLarge() {
2115         LocalDateTime.of(Year.MAX_VALUE, 1, 1, 0, 0).minus(-1, ChronoUnit.YEARS);
2116     }
2117 
2118     @Test(expectedExceptions=DateTimeException.class)
2119     public void test_minus_longTemporalUnit_invalidTooSmall() {
2120         LocalDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0).minus(1, ChronoUnit.YEARS);
2121     }
2122 
2123     //-----------------------------------------------------------------------
2124     // minusYears()
2125     //-----------------------------------------------------------------------
2126     @Test
2127     public void test_minusYears_int_normal() {
2128         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusYears(1);
2129         check(t, 2006, 7, 15, 12, 30, 40, 987654321);
2130     }
2131 
2132     @Test
2133     public void test_minusYears_int_negative() {
2134         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusYears(-1);
2135         check(t, 2008, 7, 15, 12, 30, 40, 987654321);
2136     }
2137 
2138     @Test
2139     public void test_minusYears_int_adjustDay() {
2140         LocalDateTime t = createDateMidnight(2008, 2, 29).minusYears(1);
2141         check(t, 2007, 2, 28, 0, 0, 0, 0);
2142     }
2143 
2144     @Test(expectedExceptions=DateTimeException.class)
2145     public void test_minusYears_int_invalidTooLarge() {
2146         createDateMidnight(Year.MAX_VALUE, 1, 1).minusYears(-1);
2147     }
2148 
2149     @Test(expectedExceptions=DateTimeException.class)
2150     public void test_minusYears_int_invalidTooSmall() {
2151         createDateMidnight(Year.MIN_VALUE, 1, 1).minusYears(1);
2152     }
2153 
2154     //-----------------------------------------------------------------------
2155     // minusMonths()
2156     //-----------------------------------------------------------------------
2157     @Test
2158     public void test_minusMonths_int_normal() {
2159         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusMonths(1);
2160         check(t, 2007, 6, 15, 12, 30, 40, 987654321);
2161     }
2162 
2163     @Test
2164     public void test_minusMonths_int_overYears() {
2165         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusMonths(25);
2166         check(t, 2005, 6, 15, 12, 30, 40, 987654321);
2167     }
2168 
2169     @Test
2170     public void test_minusMonths_int_negative() {
2171         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusMonths(-1);
2172         check(t, 2007, 8, 15, 12, 30, 40, 987654321);
2173     }
2174 
2175     @Test
2176     public void test_minusMonths_int_negativeAcrossYear() {
2177         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusMonths(-7);
2178         check(t, 2008, 2, 15, 12, 30, 40, 987654321);
2179     }
2180 
2181     @Test
2182     public void test_minusMonths_int_negativeOverYears() {
2183         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusMonths(-31);
2184         check(t, 2010, 2, 15, 12, 30, 40, 987654321);
2185     }
2186 
2187     @Test
2188     public void test_minusMonths_int_adjustDayFromLeapYear() {
2189         LocalDateTime t = createDateMidnight(2008, 2, 29).minusMonths(12);
2190         check(t, 2007, 2, 28, 0, 0, 0, 0);
2191     }
2192 
2193     @Test
2194     public void test_minusMonths_int_adjustDayFromMonthLength() {
2195         LocalDateTime t = createDateMidnight(2007, 3, 31).minusMonths(1);
2196         check(t, 2007, 2, 28, 0, 0, 0, 0);
2197     }
2198 
2199     @Test(expectedExceptions=DateTimeException.class)
2200     public void test_minusMonths_int_invalidTooLarge() {
2201         createDateMidnight(Year.MAX_VALUE, 12, 1).minusMonths(-1);
2202     }
2203 
2204     @Test(expectedExceptions=DateTimeException.class)
2205     public void test_minusMonths_int_invalidTooSmall() {
2206         createDateMidnight(Year.MIN_VALUE, 1, 1).minusMonths(1);
2207     }
2208 
2209     //-----------------------------------------------------------------------
2210     // minusWeeks()
2211     //-----------------------------------------------------------------------
2212     @DataProvider(name="sampleMinusWeeksSymmetry")
2213     Object[][] provider_sampleMinusWeeksSymmetry() {
2214         return new Object[][] {
2215             {createDateMidnight(-1, 1, 1)},
2216             {createDateMidnight(-1, 2, 28)},
2217             {createDateMidnight(-1, 3, 1)},
2218             {createDateMidnight(-1, 12, 31)},
2219             {createDateMidnight(0, 1, 1)},
2220             {createDateMidnight(0, 2, 28)},
2221             {createDateMidnight(0, 2, 29)},
2222             {createDateMidnight(0, 3, 1)},
2223             {createDateMidnight(0, 12, 31)},
2224             {createDateMidnight(2007, 1, 1)},
2225             {createDateMidnight(2007, 2, 28)},
2226             {createDateMidnight(2007, 3, 1)},
2227             {createDateMidnight(2007, 12, 31)},
2228             {createDateMidnight(2008, 1, 1)},
2229             {createDateMidnight(2008, 2, 28)},
2230             {createDateMidnight(2008, 2, 29)},
2231             {createDateMidnight(2008, 3, 1)},
2232             {createDateMidnight(2008, 12, 31)},
2233             {createDateMidnight(2099, 1, 1)},
2234             {createDateMidnight(2099, 2, 28)},
2235             {createDateMidnight(2099, 3, 1)},
2236             {createDateMidnight(2099, 12, 31)},
2237             {createDateMidnight(2100, 1, 1)},
2238             {createDateMidnight(2100, 2, 28)},
2239             {createDateMidnight(2100, 3, 1)},
2240             {createDateMidnight(2100, 12, 31)},
2241         };
2242     }
2243 
2244     @Test(dataProvider="sampleMinusWeeksSymmetry")
2245     public void test_minusWeeks_symmetry(LocalDateTime reference) {
2246         for (int weeks = 0; weeks < 365 * 8; weeks++) {
2247             LocalDateTime t = reference.minusWeeks(weeks).minusWeeks(-weeks);
2248             assertEquals(t, reference);
2249 
2250             t = reference.minusWeeks(-weeks).minusWeeks(weeks);
2251             assertEquals(t, reference);
2252         }
2253     }
2254 
2255     @Test
2256     public void test_minusWeeks_normal() {
2257         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusWeeks(1);
2258         check(t, 2007, 7, 8, 12, 30, 40, 987654321);
2259     }
2260 
2261     @Test
2262     public void test_minusWeeks_overMonths() {
2263         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusWeeks(9);
2264         check(t, 2007, 5, 13, 12, 30, 40, 987654321);
2265     }
2266 
2267     @Test
2268     public void test_minusWeeks_overYears() {
2269         LocalDateTime t = LocalDateTime.of(2008, 7, 13, 12, 30, 40, 987654321).minusWeeks(52);
2270         assertEquals(t, TEST_2007_07_15_12_30_40_987654321);
2271     }
2272 
2273     @Test
2274     public void test_minusWeeks_overLeapYears() {
2275         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusYears(-1).minusWeeks(104);
2276         check(t, 2006, 7, 18, 12, 30, 40, 987654321);
2277     }
2278 
2279     @Test
2280     public void test_minusWeeks_negative() {
2281         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusWeeks(-1);
2282         check(t, 2007, 7, 22, 12, 30, 40, 987654321);
2283     }
2284 
2285     @Test
2286     public void test_minusWeeks_negativeAcrossYear() {
2287         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusWeeks(-28);
2288         check(t, 2008, 1, 27, 12, 30, 40, 987654321);
2289     }
2290 
2291     @Test
2292     public void test_minusWeeks_negativeOverYears() {
2293         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusWeeks(-104);
2294         check(t, 2009, 7, 12, 12, 30, 40, 987654321);
2295     }
2296 
2297     @Test
2298     public void test_minusWeeks_maximum() {
2299         LocalDateTime t = createDateMidnight(Year.MAX_VALUE, 12, 24).minusWeeks(-1);
2300         check(t, Year.MAX_VALUE, 12, 31, 0, 0, 0, 0);
2301     }
2302 
2303     @Test
2304     public void test_minusWeeks_minimum() {
2305         LocalDateTime t = createDateMidnight(Year.MIN_VALUE, 1, 8).minusWeeks(1);
2306         check(t, Year.MIN_VALUE, 1, 1, 0, 0, 0, 0);
2307     }
2308 
2309     @Test(expectedExceptions=DateTimeException.class)
2310     public void test_minusWeeks_invalidTooLarge() {
2311         createDateMidnight(Year.MAX_VALUE, 12, 25).minusWeeks(-1);
2312     }
2313 
2314     @Test(expectedExceptions=DateTimeException.class)
2315     public void test_minusWeeks_invalidTooSmall() {
2316         createDateMidnight(Year.MIN_VALUE, 1, 7).minusWeeks(1);
2317     }
2318 
2319     //-----------------------------------------------------------------------
2320     // minusDays()
2321     //-----------------------------------------------------------------------
2322     @DataProvider(name="sampleMinusDaysSymmetry")
2323     Object[][] provider_sampleMinusDaysSymmetry() {
2324         return new Object[][] {
2325             {createDateMidnight(-1, 1, 1)},
2326             {createDateMidnight(-1, 2, 28)},
2327             {createDateMidnight(-1, 3, 1)},
2328             {createDateMidnight(-1, 12, 31)},
2329             {createDateMidnight(0, 1, 1)},
2330             {createDateMidnight(0, 2, 28)},
2331             {createDateMidnight(0, 2, 29)},
2332             {createDateMidnight(0, 3, 1)},
2333             {createDateMidnight(0, 12, 31)},
2334             {createDateMidnight(2007, 1, 1)},
2335             {createDateMidnight(2007, 2, 28)},
2336             {createDateMidnight(2007, 3, 1)},
2337             {createDateMidnight(2007, 12, 31)},
2338             {createDateMidnight(2008, 1, 1)},
2339             {createDateMidnight(2008, 2, 28)},
2340             {createDateMidnight(2008, 2, 29)},
2341             {createDateMidnight(2008, 3, 1)},
2342             {createDateMidnight(2008, 12, 31)},
2343             {createDateMidnight(2099, 1, 1)},
2344             {createDateMidnight(2099, 2, 28)},
2345             {createDateMidnight(2099, 3, 1)},
2346             {createDateMidnight(2099, 12, 31)},
2347             {createDateMidnight(2100, 1, 1)},
2348             {createDateMidnight(2100, 2, 28)},
2349             {createDateMidnight(2100, 3, 1)},
2350             {createDateMidnight(2100, 12, 31)},
2351         };
2352     }
2353 
2354     @Test(dataProvider="sampleMinusDaysSymmetry")
2355     public void test_minusDays_symmetry(LocalDateTime reference) {
2356         for (int days = 0; days < 365 * 8; days++) {
2357             LocalDateTime t = reference.minusDays(days).minusDays(-days);
2358             assertEquals(t, reference);
2359 
2360             t = reference.minusDays(-days).minusDays(days);
2361             assertEquals(t, reference);
2362         }
2363     }
2364 
2365     @Test
2366     public void test_minusDays_normal() {
2367         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusDays(1);
2368         check(t, 2007, 7, 14, 12, 30, 40, 987654321);
2369     }
2370 
2371     @Test
2372     public void test_minusDays_overMonths() {
2373         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusDays(62);
2374         check(t, 2007, 5, 14, 12, 30, 40, 987654321);
2375     }
2376 
2377     @Test
2378     public void test_minusDays_overYears() {
2379         LocalDateTime t = LocalDateTime.of(2008, 7, 16, 12, 30, 40, 987654321).minusDays(367);
2380         assertEquals(t, TEST_2007_07_15_12_30_40_987654321);
2381     }
2382 
2383     @Test
2384     public void test_minusDays_overLeapYears() {
2385         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.plusYears(2).minusDays(365 + 366);
2386         assertEquals(t, TEST_2007_07_15_12_30_40_987654321);
2387     }
2388 
2389     @Test
2390     public void test_minusDays_negative() {
2391         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusDays(-1);
2392         check(t, 2007, 7, 16, 12, 30, 40, 987654321);
2393     }
2394 
2395     @Test
2396     public void test_minusDays_negativeAcrossYear() {
2397         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusDays(-169);
2398         check(t, 2007, 12, 31, 12, 30, 40, 987654321);
2399     }
2400 
2401     @Test
2402     public void test_minusDays_negativeOverYears() {
2403         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusDays(-731);
2404         check(t, 2009, 7, 15, 12, 30, 40, 987654321);
2405     }
2406 
2407     @Test
2408     public void test_minusDays_maximum() {
2409         LocalDateTime t = createDateMidnight(Year.MAX_VALUE, 12, 30).minusDays(-1);
2410         check(t, Year.MAX_VALUE, 12, 31, 0, 0, 0, 0);
2411     }
2412 
2413     @Test
2414     public void test_minusDays_minimum() {
2415         LocalDateTime t = createDateMidnight(Year.MIN_VALUE, 1, 2).minusDays(1);
2416         check(t, Year.MIN_VALUE, 1, 1, 0, 0, 0, 0);
2417     }
2418 
2419     @Test(expectedExceptions=DateTimeException.class)
2420     public void test_minusDays_invalidTooLarge() {
2421         createDateMidnight(Year.MAX_VALUE, 12, 31).minusDays(-1);
2422     }
2423 
2424     @Test(expectedExceptions=DateTimeException.class)
2425     public void test_minusDays_invalidTooSmall() {
2426         createDateMidnight(Year.MIN_VALUE, 1, 1).minusDays(1);
2427     }
2428 
2429     @Test(expectedExceptions=ArithmeticException.class)
2430     public void test_minusDays_overflowTooLarge() {
2431         createDateMidnight(Year.MAX_VALUE, 12, 31).minusDays(Long.MIN_VALUE);
2432     }
2433 
2434     @Test(expectedExceptions=ArithmeticException.class)
2435     public void test_minusDays_overflowTooSmall() {
2436         createDateMidnight(Year.MIN_VALUE, 1, 1).minusDays(Long.MAX_VALUE);
2437     }
2438 
2439     //-----------------------------------------------------------------------
2440     // minusHours()
2441     //-----------------------------------------------------------------------
2442     @Test
2443     public void test_minusHours_one() {
2444         LocalDateTime t =TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
2445         LocalDate d = t.toLocalDate();
2446 
2447         for (int i = 0; i < 50; i++) {
2448             t = t.minusHours(1);
2449 
2450             if (i % 24 == 0) {
2451                 d = d.minusDays(1);
2452             }
2453 
2454             assertEquals(t.toLocalDate(), d);
2455             assertEquals(t.getHour(), (((-i + 23) % 24) + 24) % 24);
2456         }
2457     }
2458 
2459     @Test
2460     public void test_minusHours_fromZero() {
2461         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
2462         LocalDate d = base.toLocalDate().plusDays(2);
2463         LocalTime t = LocalTime.of(3, 0);
2464 
2465         for (int i = -50; i < 50; i++) {
2466             LocalDateTime dt = base.minusHours(i);
2467             t = t.minusHours(1);
2468 
2469             if (t.getHour() == 23) {
2470                 d = d.minusDays(1);
2471             }
2472 
2473             assertEquals(dt.toLocalDate(), d, String.valueOf(i));
2474             assertEquals(dt.toLocalTime(), t);
2475         }
2476     }
2477 
2478     @Test
2479     public void test_minusHours_fromOne() {
2480         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.of(1, 0));
2481         LocalDate d = base.toLocalDate().plusDays(2);
2482         LocalTime t = LocalTime.of(4, 0);
2483 
2484         for (int i = -50; i < 50; i++) {
2485             LocalDateTime dt = base.minusHours(i);
2486 
2487             t = t.minusHours(1);
2488 
2489             if (t.getHour() == 23) {
2490                 d = d.minusDays(1);
2491             }
2492 
2493             assertEquals(dt.toLocalDate(), d, String.valueOf(i));
2494             assertEquals(dt.toLocalTime(), t);
2495         }
2496     }
2497 
2498     //-----------------------------------------------------------------------
2499     // minusMinutes()
2500     //-----------------------------------------------------------------------
2501     @Test
2502     public void test_minusMinutes_one() {
2503         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
2504         LocalDate d = t.toLocalDate().minusDays(1);
2505 
2506         int hour = 0;
2507         int min = 0;
2508 
2509         for (int i = 0; i < 70; i++) {
2510             t = t.minusMinutes(1);
2511             min--;
2512             if (min == -1) {
2513                 hour--;
2514                 min = 59;
2515 
2516                 if (hour == -1) {
2517                     hour = 23;
2518                 }
2519             }
2520             assertEquals(t.toLocalDate(), d);
2521             assertEquals(t.getHour(), hour);
2522             assertEquals(t.getMinute(), min);
2523         }
2524     }
2525 
2526     @Test
2527     public void test_minusMinutes_fromZero() {
2528         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
2529         LocalDate d = base.toLocalDate().minusDays(1);
2530         LocalTime t = LocalTime.of(22, 49);
2531 
2532         for (int i = 70; i > -70; i--) {
2533             LocalDateTime dt = base.minusMinutes(i);
2534             t = t.plusMinutes(1);
2535 
2536             if (t.equals(LocalTime.MIDNIGHT)) {
2537                 d = d.plusDays(1);
2538             }
2539 
2540             assertEquals(dt.toLocalDate(), d);
2541             assertEquals(dt.toLocalTime(), t);
2542         }
2543     }
2544 
2545     @Test
2546     public void test_minusMinutes_noChange_oneDay() {
2547         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.minusMinutes(24 * 60);
2548         assertEquals(t.toLocalDate(), TEST_2007_07_15_12_30_40_987654321.toLocalDate().minusDays(1));
2549     }
2550 
2551     //-----------------------------------------------------------------------
2552     // minusSeconds()
2553     //-----------------------------------------------------------------------
2554     @Test
2555     public void test_minusSeconds_one() {
2556         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
2557         LocalDate d = t.toLocalDate().minusDays(1);
2558 
2559         int hour = 0;
2560         int min = 0;
2561         int sec = 0;
2562 
2563         for (int i = 0; i < 3700; i++) {
2564             t = t.minusSeconds(1);
2565             sec--;
2566             if (sec == -1) {
2567                 min--;
2568                 sec = 59;
2569 
2570                 if (min == -1) {
2571                     hour--;
2572                     min = 59;
2573 
2574                     if (hour == -1) {
2575                         hour = 23;
2576                     }
2577                 }
2578             }
2579 
2580             assertEquals(t.toLocalDate(), d);
2581             assertEquals(t.getHour(), hour);
2582             assertEquals(t.getMinute(), min);
2583             assertEquals(t.getSecond(), sec);
2584         }
2585     }
2586 
2587     @DataProvider(name="minusSeconds_fromZero")
2588     Iterator<Object[]> minusSeconds_fromZero() {
2589         return new Iterator<Object[]>() {
2590             int delta = 30;
2591 
2592             int i = 3660;
2593             LocalDate date = TEST_2007_07_15_12_30_40_987654321.toLocalDate().minusDays(1);
2594             int hour = 22;
2595             int min = 59;
2596             int sec = 0;
2597 
2598             public boolean hasNext() {
2599                 return i >= -3660;
2600             }
2601 
2602             public Object[] next() {
2603                 final Object[] ret = new Object[] {i, date, hour, min, sec};
2604                 i -= delta;
2605                 sec += delta;
2606 
2607                 if (sec >= 60) {
2608                     min++;
2609                     sec -= 60;
2610 
2611                     if (min == 60) {
2612                         hour++;
2613                         min = 0;
2614 
2615                         if (hour == 24) {
2616                             hour = 0;
2617                         }
2618                     }
2619                 }
2620 
2621                 if (i == 0) {
2622                     date = date.plusDays(1);
2623                 }
2624 
2625                 return ret;
2626             }
2627 
2628             public void remove() {
2629                 throw new UnsupportedOperationException();
2630             }
2631         };
2632     }
2633 
2634     @Test(dataProvider="minusSeconds_fromZero")
2635     public void test_minusSeconds_fromZero(int seconds, LocalDate date, int hour, int min, int sec) {
2636         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
2637         LocalDateTime t = base.minusSeconds(seconds);
2638 
2639         assertEquals(date, t.toLocalDate());
2640         assertEquals(hour, t.getHour());
2641         assertEquals(min, t.getMinute());
2642         assertEquals(sec, t.getSecond());
2643     }
2644 
2645     //-----------------------------------------------------------------------
2646     // minusNanos()
2647     //-----------------------------------------------------------------------
2648     @Test
2649     public void test_minusNanos_halfABillion() {
2650         LocalDateTime t = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
2651         LocalDate d = t.toLocalDate().minusDays(1);
2652 
2653         int hour = 0;
2654         int min = 0;
2655         int sec = 0;
2656         int nanos = 0;
2657 
2658         for (long i = 0; i < 3700 * 1000000000L; i+= 500000000) {
2659             t = t.minusNanos(500000000);
2660             nanos -= 500000000;
2661 
2662             if (nanos < 0) {
2663                 sec--;
2664                 nanos += 1000000000;
2665 
2666                 if (sec == -1) {
2667                     min--;
2668                     sec += 60;
2669 
2670                     if (min == -1) {
2671                         hour--;
2672                         min += 60;
2673 
2674                         if (hour == -1) {
2675                             hour += 24;
2676                         }
2677                     }
2678                 }
2679             }
2680 
2681             assertEquals(t.toLocalDate(), d);
2682             assertEquals(t.getHour(), hour);
2683             assertEquals(t.getMinute(), min);
2684             assertEquals(t.getSecond(), sec);
2685             assertEquals(t.getNano(), nanos);
2686         }
2687     }
2688 
2689     @DataProvider(name="minusNanos_fromZero")
2690     Iterator<Object[]> minusNanos_fromZero() {
2691         return new Iterator<Object[]>() {
2692             long delta = 7500000000L;
2693 
2694             long i = 3660 * 1000000000L;
2695             LocalDate date = TEST_2007_07_15_12_30_40_987654321.toLocalDate().minusDays(1);
2696             int hour = 22;
2697             int min = 59;
2698             int sec = 0;
2699             long nanos = 0;
2700 
2701             public boolean hasNext() {
2702                 return i >= -3660 * 1000000000L;
2703             }
2704 
2705             public Object[] next() {
2706                 final Object[] ret = new Object[] {i, date, hour, min, sec, (int)nanos};
2707                 i -= delta;
2708                 nanos += delta;
2709 
2710                 if (nanos >= 1000000000L) {
2711                     sec += nanos / 1000000000L;
2712                     nanos %= 1000000000L;
2713 
2714                     if (sec >= 60) {
2715                         min++;
2716                         sec %= 60;
2717 
2718                         if (min == 60) {
2719                             hour++;
2720                             min = 0;
2721 
2722                             if (hour == 24) {
2723                                 hour = 0;
2724                                 date = date.plusDays(1);
2725                             }
2726                         }
2727                     }
2728                 }
2729 
2730                 return ret;
2731             }
2732 
2733             public void remove() {
2734                 throw new UnsupportedOperationException();
2735             }
2736         };
2737     }
2738 
2739     @Test(dataProvider="minusNanos_fromZero")
2740     public void test_minusNanos_fromZero(long nanoseconds, LocalDate date, int hour, int min, int sec, int nanos) {
2741         LocalDateTime base = TEST_2007_07_15_12_30_40_987654321.with(LocalTime.MIDNIGHT);
2742         LocalDateTime t = base.minusNanos(nanoseconds);
2743 
2744         assertEquals(date, t.toLocalDate());
2745         assertEquals(hour, t.getHour());
2746         assertEquals(min, t.getMinute());
2747         assertEquals(sec, t.getSecond());
2748         assertEquals(nanos, t.getNano());
2749     }
2750 
2751     //-----------------------------------------------------------------------
2752     // until(Temporal, TemporalUnit)
2753     //-----------------------------------------------------------------------
2754     @DataProvider(name="periodUntilUnit")
2755     Object[][] data_periodUntilUnit() {
2756         return new Object[][] {
2757                 // date only
2758                 {dtNoon(2000, 1, 1), dtNoon(2000, 1, 1), DAYS, 0},
2759                 {dtNoon(2000, 1, 1), dtNoon(2000, 1, 1), WEEKS, 0},
2760                 {dtNoon(2000, 1, 1), dtNoon(2000, 1, 1), MONTHS, 0},
2761                 {dtNoon(2000, 1, 1), dtNoon(2000, 1, 1), YEARS, 0},
2762                 {dtNoon(2000, 1, 1), dtNoon(2000, 1, 1), DECADES, 0},
2763                 {dtNoon(2000, 1, 1), dtNoon(2000, 1, 1), CENTURIES, 0},
2764                 {dtNoon(2000, 1, 1), dtNoon(2000, 1, 1), MILLENNIA, 0},
2765 
2766                 {dtNoon(2000, 1, 15), dtNoon(2000, 2, 14), DAYS, 30},
2767                 {dtNoon(2000, 1, 15), dtNoon(2000, 2, 15), DAYS, 31},
2768                 {dtNoon(2000, 1, 15), dtNoon(2000, 2, 16), DAYS, 32},
2769 
2770                 {dtNoon(2000, 1, 15), dtNoon(2000, 2, 17), WEEKS, 4},
2771                 {dtNoon(2000, 1, 15), dtNoon(2000, 2, 18), WEEKS, 4},
2772                 {dtNoon(2000, 1, 15), dtNoon(2000, 2, 19), WEEKS, 5},
2773                 {dtNoon(2000, 1, 15), dtNoon(2000, 2, 20), WEEKS, 5},
2774 
2775                 {dtNoon(2000, 1, 15), dtNoon(2000, 2, 14), MONTHS, 0},
2776                 {dtNoon(2000, 1, 15), dtNoon(2000, 2, 15), MONTHS, 1},
2777                 {dtNoon(2000, 1, 15), dtNoon(2000, 2, 16), MONTHS, 1},
2778                 {dtNoon(2000, 1, 15), dtNoon(2000, 3, 14), MONTHS, 1},
2779                 {dtNoon(2000, 1, 15), dtNoon(2000, 3, 15), MONTHS, 2},
2780                 {dtNoon(2000, 1, 15), dtNoon(2000, 3, 16), MONTHS, 2},
2781 
2782                 {dtNoon(2000, 1, 15), dtNoon(2001, 1, 14), YEARS, 0},
2783                 {dtNoon(2000, 1, 15), dtNoon(2001, 1, 15), YEARS, 1},
2784                 {dtNoon(2000, 1, 15), dtNoon(2001, 1, 16), YEARS, 1},
2785                 {dtNoon(2000, 1, 15), dtNoon(2004, 1, 14), YEARS, 3},
2786                 {dtNoon(2000, 1, 15), dtNoon(2004, 1, 15), YEARS, 4},
2787                 {dtNoon(2000, 1, 15), dtNoon(2004, 1, 16), YEARS, 4},
2788 
2789                 {dtNoon(2000, 1, 15), dtNoon(2010, 1, 14), DECADES, 0},
2790                 {dtNoon(2000, 1, 15), dtNoon(2010, 1, 15), DECADES, 1},
2791 
2792                 {dtNoon(2000, 1, 15), dtNoon(2100, 1, 14), CENTURIES, 0},
2793                 {dtNoon(2000, 1, 15), dtNoon(2100, 1, 15), CENTURIES, 1},
2794 
2795                 {dtNoon(2000, 1, 15), dtNoon(3000, 1, 14), MILLENNIA, 0},
2796                 {dtNoon(2000, 1, 15), dtNoon(3000, 1, 15), MILLENNIA, 1},
2797 
2798                 // time only
2799                 {dtEpoch(0, 0, 0, 0), dtEpoch(0, 0, 0, 0), NANOS, 0},
2800                 {dtEpoch(0, 0, 0, 0), dtEpoch(0, 0, 0, 0), MICROS, 0},
2801                 {dtEpoch(0, 0, 0, 0), dtEpoch(0, 0, 0, 0), MILLIS, 0},
2802                 {dtEpoch(0, 0, 0, 0), dtEpoch(0, 0, 0, 0), SECONDS, 0},
2803                 {dtEpoch(0, 0, 0, 0), dtEpoch(0, 0, 0, 0), MINUTES, 0},
2804                 {dtEpoch(0, 0, 0, 0), dtEpoch(0, 0, 0, 0), HOURS, 0},
2805                 {dtEpoch(0, 0, 0, 0), dtEpoch(0, 0, 0, 0), HALF_DAYS, 0},
2806 
2807                 {dtEpoch(0, 0, 0, 0), dtEpoch(2, 0, 0, 0), NANOS, 2 * 3600 * 1_000_000_000L},
2808                 {dtEpoch(0, 0, 0, 0), dtEpoch(2, 0, 0, 0), MICROS, 2 * 3600 * 1_000_000L},
2809                 {dtEpoch(0, 0, 0, 0), dtEpoch(2, 0, 0, 0), MILLIS, 2 * 3600 * 1_000L},
2810                 {dtEpoch(0, 0, 0, 0), dtEpoch(2, 0, 0, 0), SECONDS, 2 * 3600},
2811                 {dtEpoch(0, 0, 0, 0), dtEpoch(2, 0, 0, 0), MINUTES, 2 * 60},
2812                 {dtEpoch(0, 0, 0, 0), dtEpoch(2, 0, 0, 0), HOURS, 2},
2813                 {dtEpoch(0, 0, 0, 0), dtEpoch(2, 0, 0, 0), HALF_DAYS, 0},
2814 
2815                 {dtEpoch(0, 0, 0, 0), dtEpoch(14, 0, 0, 0), NANOS, 14 * 3600 * 1_000_000_000L},
2816                 {dtEpoch(0, 0, 0, 0), dtEpoch(14, 0, 0, 0), MICROS, 14 * 3600 * 1_000_000L},
2817                 {dtEpoch(0, 0, 0, 0), dtEpoch(14, 0, 0, 0), MILLIS, 14 * 3600 * 1_000L},
2818                 {dtEpoch(0, 0, 0, 0), dtEpoch(14, 0, 0, 0), SECONDS, 14 * 3600},
2819                 {dtEpoch(0, 0, 0, 0), dtEpoch(14, 0, 0, 0), MINUTES, 14 * 60},
2820                 {dtEpoch(0, 0, 0, 0), dtEpoch(14, 0, 0, 0), HOURS, 14},
2821                 {dtEpoch(0, 0, 0, 0), dtEpoch(14, 0, 0, 0), HALF_DAYS, 1},
2822 
2823                 {dtEpoch(0, 0, 0, 0), dtEpoch(2, 30, 40, 1500), NANOS, (2 * 3600 + 30 * 60 + 40) * 1_000_000_000L + 1500},
2824                 {dtEpoch(0, 0, 0, 0), dtEpoch(2, 30, 40, 1500), MICROS, (2 * 3600 + 30 * 60 + 40) * 1_000_000L + 1},
2825                 {dtEpoch(0, 0, 0, 0), dtEpoch(2, 30, 40, 1500), MILLIS, (2 * 3600 + 30 * 60 + 40) * 1_000L},
2826                 {dtEpoch(0, 0, 0, 0), dtEpoch(2, 30, 40, 1500), SECONDS, 2 * 3600 + 30 * 60 + 40},
2827                 {dtEpoch(0, 0, 0, 0), dtEpoch(2, 30, 40, 1500), MINUTES, 2 * 60 + 30},
2828                 {dtEpoch(0, 0, 0, 0), dtEpoch(2, 30, 40, 1500), HOURS, 2},
2829 
2830                 // combinations
2831                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 15, 12, 30, 40, 499), NANOS, -1},
2832                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 15, 12, 30, 40, 500), NANOS, 0},
2833                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 15, 12, 30, 40, 501), NANOS, 1},
2834 
2835                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 15, 12, 30, 39, 500), SECONDS, -1},
2836                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 15, 12, 30, 39, 501), SECONDS, 0},
2837                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 15, 12, 30, 40, 499), SECONDS, 0},
2838                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 15, 12, 30, 40, 500), SECONDS, 0},
2839                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 15, 12, 30, 40, 501), SECONDS, 0},
2840                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 15, 12, 30, 41, 499), SECONDS, 0},
2841                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 15, 12, 30, 41, 500), SECONDS, 1},
2842 
2843                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 40, 499), NANOS, -1 + 86400_000_000_000L},
2844                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 40, 500), NANOS, 0 + 86400_000_000_000L},
2845                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 40, 501), NANOS, 1 + 86400_000_000_000L},
2846 
2847                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 39, 499), SECONDS, -2 + 86400L},
2848                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 39, 500), SECONDS, -1 + 86400L},
2849                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 39, 501), SECONDS, -1 + 86400L},
2850                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 40, 499), SECONDS, -1 + 86400L},
2851                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 40, 500), SECONDS, 0 + 86400L},
2852                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 40, 501), SECONDS, 0 + 86400L},
2853                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 41, 499), SECONDS, 0 + 86400L},
2854                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 41, 500), SECONDS, 1 + 86400L},
2855 
2856                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 29, 40, 499), MINUTES, -2 + 24 * 60L},
2857                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 29, 40, 500), MINUTES, -1 + 24 * 60L},
2858                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 29, 40, 501), MINUTES, -1 + 24 * 60L},
2859                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 40, 499), MINUTES, -1 + 24 * 60L},
2860                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 40, 500), MINUTES, 0 + 24 * 60L},
2861                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 40, 501), MINUTES, 0 + 24 * 60L},
2862                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 31, 40, 499), MINUTES, 0 + 24 * 60L},
2863                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 31, 40, 500), MINUTES, 1 + 24 * 60L},
2864 
2865                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 11, 30, 40, 499), HOURS, -2 + 24L},
2866                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 11, 30, 40, 500), HOURS, -1 + 24L},
2867                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 11, 30, 40, 501), HOURS, -1 + 24L},
2868                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 40, 499), HOURS, -1 + 24L},
2869                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 40, 500), HOURS, 0 + 24L},
2870                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 40, 501), HOURS, 0 + 24L},
2871                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 13, 30, 40, 499), HOURS, 0 + 24L},
2872                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 13, 30, 40, 500), HOURS, 1 + 24L},
2873 
2874                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 13, 12, 30, 40, 499), DAYS, -2},
2875                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 13, 12, 30, 40, 500), DAYS, -2},
2876                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 13, 12, 30, 40, 501), DAYS, -1},
2877                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 14, 12, 30, 40, 499), DAYS, -1},
2878                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 14, 12, 30, 40, 500), DAYS, -1},
2879                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 14, 12, 30, 40, 501), DAYS, 0},
2880                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 15, 12, 30, 40, 499), DAYS, 0},
2881                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 15, 12, 30, 40, 500), DAYS, 0},
2882                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 15, 12, 30, 40, 501), DAYS, 0},
2883                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 40, 499), DAYS, 0},
2884                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 40, 500), DAYS, 1},
2885                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 16, 12, 30, 40, 501), DAYS, 1},
2886                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 17, 12, 30, 40, 499), DAYS, 1},
2887                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 17, 12, 30, 40, 500), DAYS, 2},
2888                 {dt(2000, 1, 15, 12, 30, 40, 500), dt(2000, 1, 17, 12, 30, 40, 501), DAYS, 2},
2889         };
2890     }
2891 
2892     @Test(dataProvider="periodUntilUnit")
2893     public void test_until_TemporalUnit(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) {
2894         long amount = dt1.until(dt2, unit);
2895         assertEquals(amount, expected);
2896     }
2897 
2898     @Test(dataProvider="periodUntilUnit")
2899     public void test_until_TemporalUnit_negated(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) {
2900         long amount = dt2.until(dt1, unit);
2901         assertEquals(amount, -expected);
2902     }
2903 
2904     @Test(dataProvider="periodUntilUnit")
2905     public void test_until_TemporalUnit_between(LocalDateTime dt1, LocalDateTime dt2, TemporalUnit unit, long expected) {
2906         long amount = unit.between(dt1, dt2);
2907         assertEquals(amount, expected);
2908     }
2909 
2910     @Test
2911     public void test_until_convertedType() {
2912         LocalDateTime start = LocalDateTime.of(2010, 6, 30, 2, 30);
2913         OffsetDateTime end = start.plusDays(2).atOffset(OFFSET_PONE);
2914         assertEquals(start.until(end, DAYS), 2);
2915     }
2916 
2917     @Test(expectedExceptions=DateTimeException.class)
2918     public void test_until_invalidType() {
2919         LocalDateTime start = LocalDateTime.of(2010, 6, 30, 2, 30);
2920         start.until(LocalTime.of(11, 30), DAYS);
2921     }
2922 
2923     @Test(expectedExceptions = NullPointerException.class)
2924     public void test_until_TemporalUnit_nullEnd() {
2925         TEST_2007_07_15_12_30_40_987654321.until(null, HOURS);
2926     }
2927 
2928     @Test(expectedExceptions = NullPointerException.class)
2929     public void test_until_TemporalUnit_nullUnit() {
2930         TEST_2007_07_15_12_30_40_987654321.until(TEST_2007_07_15_12_30_40_987654321, null);
2931     }
2932 
2933     //-----------------------------------------------------------------------
2934     // format(DateTimeFormatter)
2935     //-----------------------------------------------------------------------
2936     @Test
2937     public void test_format_formatter() {
2938         DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s");
2939         String t = LocalDateTime.of(2010, 12, 3, 11, 30, 45).format(f);
2940         assertEquals(t, "2010 12 3 11 30 45");
2941     }
2942 
2943     @Test(expectedExceptions=NullPointerException.class)
2944     public void test_format_formatter_null() {
2945         LocalDateTime.of(2010, 12, 3, 11, 30, 45).format(null);
2946     }
2947 
2948     //-----------------------------------------------------------------------
2949     // atOffset()
2950     //-----------------------------------------------------------------------
2951     @Test
2952     public void test_atOffset() {
2953         LocalDateTime t = LocalDateTime.of(2008, 6, 30, 11, 30);
2954         assertEquals(t.atOffset(OFFSET_PTWO), OffsetDateTime.of(LocalDateTime.of(2008, 6, 30, 11, 30), OFFSET_PTWO));
2955     }
2956 
2957     @Test(expectedExceptions=NullPointerException.class)
2958     public void test_atOffset_nullZoneOffset() {
2959         LocalDateTime t = LocalDateTime.of(2008, 6, 30, 11, 30);
2960         t.atOffset((ZoneOffset) null);
2961     }
2962 
2963     //-----------------------------------------------------------------------
2964     // atZone()
2965     //-----------------------------------------------------------------------
2966     @Test
2967     public void test_atZone() {
2968         LocalDateTime t = LocalDateTime.of(2008, 6, 30, 11, 30);
2969         assertEquals(t.atZone(ZONE_PARIS),
2970                 ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 11, 30), ZONE_PARIS));
2971     }
2972 
2973     @Test
2974     public void test_atZone_Offset() {
2975         LocalDateTime t = LocalDateTime.of(2008, 6, 30, 11, 30);
2976         assertEquals(t.atZone(OFFSET_PTWO), ZonedDateTime.of(LocalDateTime.of(2008, 6, 30, 11, 30), OFFSET_PTWO));
2977     }
2978 
2979     @Test
2980     public void test_atZone_dstGap() {
2981         LocalDateTime t = LocalDateTime.of(2007, 4, 1, 0, 0);
2982         assertEquals(t.atZone(ZONE_GAZA),
2983                 ZonedDateTime.of(LocalDateTime.of(2007, 4, 1, 1, 0), ZONE_GAZA));
2984     }
2985 
2986     @Test
2987     public void test_atZone_dstOverlap() {
2988         LocalDateTime t = LocalDateTime.of(2007, 10, 28, 2, 30);
2989         assertEquals(t.atZone(ZONE_PARIS),
2990                 ZonedDateTime.ofStrict(LocalDateTime.of(2007, 10, 28, 2, 30), OFFSET_PTWO, ZONE_PARIS));
2991     }
2992 
2993     @Test(expectedExceptions=NullPointerException.class)
2994     public void test_atZone_nullTimeZone() {
2995         LocalDateTime t = LocalDateTime.of(2008, 6, 30, 11, 30);
2996         t.atZone((ZoneId) null);
2997     }
2998 
2999     //-----------------------------------------------------------------------
3000     // toEpochSecond()
3001     //-----------------------------------------------------------------------
3002     @Test
3003     public void test_toEpochSecond_afterEpoch() {
3004         for (int i = -5; i < 5; i++) {
3005             ZoneOffset offset = ZoneOffset.ofHours(i);
3006             for (int j = 0; j < 100000; j++) {
3007                 LocalDateTime a = LocalDateTime.of(1970, 1, 1, 0, 0).plusSeconds(j);
3008                 assertEquals(a.toEpochSecond(offset), j - i * 3600);
3009             }
3010         }
3011     }
3012 
3013     @Test
3014     public void test_toEpochSecond_beforeEpoch() {
3015         for (int i = 0; i < 100000; i++) {
3016             LocalDateTime a = LocalDateTime.of(1970, 1, 1, 0, 0).minusSeconds(i);
3017             assertEquals(a.toEpochSecond(ZoneOffset.UTC), -i);
3018         }
3019     }
3020 
3021     //-----------------------------------------------------------------------
3022     // compareTo()
3023     //-----------------------------------------------------------------------
3024     @Test
3025     public void test_comparisons() {
3026         test_comparisons_LocalDateTime(
3027                 LocalDate.of(Year.MIN_VALUE, 1, 1),
3028                 LocalDate.of(Year.MIN_VALUE, 12, 31),
3029                 LocalDate.of(-1, 1, 1),
3030                 LocalDate.of(-1, 12, 31),
3031                 LocalDate.of(0, 1, 1),
3032                 LocalDate.of(0, 12, 31),
3033                 LocalDate.of(1, 1, 1),
3034                 LocalDate.of(1, 12, 31),
3035                 LocalDate.of(2008, 1, 1),
3036                 LocalDate.of(2008, 2, 29),
3037                 LocalDate.of(2008, 12, 31),
3038                 LocalDate.of(Year.MAX_VALUE, 1, 1),
3039                 LocalDate.of(Year.MAX_VALUE, 12, 31)
3040         );
3041     }
3042 
3043     void test_comparisons_LocalDateTime(LocalDate... localDates) {
3044         test_comparisons_LocalDateTime(
3045             localDates,
3046             LocalTime.MIDNIGHT,
3047             LocalTime.of(0, 0, 0, 999999999),
3048             LocalTime.of(0, 0, 59, 0),
3049             LocalTime.of(0, 0, 59, 999999999),
3050             LocalTime.of(0, 59, 0, 0),
3051             LocalTime.of(0, 59, 59, 999999999),
3052             LocalTime.NOON,
3053             LocalTime.of(12, 0, 0, 999999999),
3054             LocalTime.of(12, 0, 59, 0),
3055             LocalTime.of(12, 0, 59, 999999999),
3056             LocalTime.of(12, 59, 0, 0),
3057             LocalTime.of(12, 59, 59, 999999999),
3058             LocalTime.of(23, 0, 0, 0),
3059             LocalTime.of(23, 0, 0, 999999999),
3060             LocalTime.of(23, 0, 59, 0),
3061             LocalTime.of(23, 0, 59, 999999999),
3062             LocalTime.of(23, 59, 0, 0),
3063             LocalTime.of(23, 59, 59, 999999999)
3064         );
3065     }
3066 
3067     void test_comparisons_LocalDateTime(LocalDate[] localDates, LocalTime... localTimes) {
3068         LocalDateTime[] localDateTimes = new LocalDateTime[localDates.length * localTimes.length];
3069         int i = 0;
3070 
3071         for (LocalDate localDate : localDates) {
3072             for (LocalTime localTime : localTimes) {
3073                 localDateTimes[i++] = LocalDateTime.of(localDate, localTime);
3074             }
3075         }
3076 
3077         doTest_comparisons_LocalDateTime(localDateTimes);
3078     }
3079 
3080     void doTest_comparisons_LocalDateTime(LocalDateTime[] localDateTimes) {
3081         for (int i = 0; i < localDateTimes.length; i++) {
3082             LocalDateTime a = localDateTimes[i];
3083             for (int j = 0; j < localDateTimes.length; j++) {
3084                 LocalDateTime b = localDateTimes[j];
3085                 if (i < j) {
3086                     assertTrue(a.compareTo(b) < 0, a + " <=> " + b);
3087                     assertEquals(a.isBefore(b), true, a + " <=> " + b);
3088                     assertEquals(a.isAfter(b), false, a + " <=> " + b);
3089                     assertEquals(a.equals(b), false, a + " <=> " + b);
3090                 } else if (i > j) {
3091                     assertTrue(a.compareTo(b) > 0, a + " <=> " + b);
3092                     assertEquals(a.isBefore(b), false, a + " <=> " + b);
3093                     assertEquals(a.isAfter(b), true, a + " <=> " + b);
3094                     assertEquals(a.equals(b), false, a + " <=> " + b);
3095                 } else {
3096                     assertEquals(a.compareTo(b), 0, a + " <=> " + b);
3097                     assertEquals(a.isBefore(b), false, a + " <=> " + b);
3098                     assertEquals(a.isAfter(b), false, a + " <=> " + b);
3099                     assertEquals(a.equals(b), true, a + " <=> " + b);
3100                 }
3101             }
3102         }
3103     }
3104 
3105     @Test(expectedExceptions=NullPointerException.class)
3106     public void test_compareTo_ObjectNull() {
3107         TEST_2007_07_15_12_30_40_987654321.compareTo(null);
3108     }
3109 
3110     @Test(expectedExceptions=NullPointerException.class)
3111     public void test_isBefore_ObjectNull() {
3112         TEST_2007_07_15_12_30_40_987654321.isBefore(null);
3113     }
3114 
3115     @Test(expectedExceptions=NullPointerException.class)
3116     public void test_isAfter_ObjectNull() {
3117         TEST_2007_07_15_12_30_40_987654321.isAfter(null);
3118     }
3119 
3120     @Test(expectedExceptions=ClassCastException.class)
3121     @SuppressWarnings({"unchecked", "rawtypes"})
3122     public void compareToNonLocalDateTime() {
3123        Comparable c = TEST_2007_07_15_12_30_40_987654321;
3124        c.compareTo(new Object());
3125     }
3126 
3127     //-----------------------------------------------------------------------
3128     // equals()
3129     //-----------------------------------------------------------------------
3130     @DataProvider(name="sampleDateTimes")
3131     Iterator<Object[]> provider_sampleDateTimes() {
3132         return new Iterator<Object[]>() {
3133             Object[][] sampleDates = provider_sampleDates();
3134             Object[][] sampleTimes = provider_sampleTimes();
3135             int datesIndex = 0;
3136             int timesIndex = 0;
3137 
3138             public boolean hasNext() {
3139                 return datesIndex < sampleDates.length;
3140             }
3141 
3142             public Object[] next() {
3143                 Object[] sampleDate = sampleDates[datesIndex];
3144                 Object[] sampleTime = sampleTimes[timesIndex];
3145 
3146                 Object[] ret = new Object[sampleDate.length + sampleTime.length];
3147 
3148                 System.arraycopy(sampleDate, 0, ret, 0, sampleDate.length);
3149                 System.arraycopy(sampleTime, 0, ret, sampleDate.length, sampleTime.length);
3150 
3151                 if (++timesIndex == sampleTimes.length) {
3152                     datesIndex++;
3153                     timesIndex = 0;
3154                 }
3155 
3156                 return ret;
3157             }
3158 
3159             public void remove() {
3160                 throw new UnsupportedOperationException();
3161             }
3162         };
3163     }
3164 
3165     @Test(dataProvider="sampleDateTimes")
3166     public void test_equals_true(int y, int m, int d, int h, int mi, int s, int n) {
3167         LocalDateTime a = LocalDateTime.of(y, m, d, h, mi, s, n);
3168         LocalDateTime b = LocalDateTime.of(y, m, d, h, mi, s, n);
3169         assertTrue(a.equals(b));
3170     }
3171 
3172     @Test(dataProvider="sampleDateTimes")
3173     public void test_equals_false_year_differs(int y, int m, int d, int h, int mi, int s, int n) {
3174         LocalDateTime a = LocalDateTime.of(y, m, d, h, mi, s, n);
3175         LocalDateTime b = LocalDateTime.of(y + 1, m, d, h, mi, s, n);
3176         assertFalse(a.equals(b));
3177     }
3178 
3179     @Test(dataProvider="sampleDateTimes")
3180     public void test_equals_false_month_differs(int y, int m, int d, int h, int mi, int s, int n) {
3181         LocalDateTime a = LocalDateTime.of(y, m, d, h, mi, s, n);
3182         LocalDateTime b = LocalDateTime.of(y, m + 1, d, h, mi, s, n);
3183         assertFalse(a.equals(b));
3184     }
3185 
3186     @Test(dataProvider="sampleDateTimes")
3187     public void test_equals_false_day_differs(int y, int m, int d, int h, int mi, int s, int n) {
3188         LocalDateTime a = LocalDateTime.of(y, m, d, h, mi, s, n);
3189         LocalDateTime b = LocalDateTime.of(y, m, d + 1, h, mi, s, n);
3190         assertFalse(a.equals(b));
3191     }
3192 
3193     @Test(dataProvider="sampleDateTimes")
3194     public void test_equals_false_hour_differs(int y, int m, int d, int h, int mi, int s, int n) {
3195         LocalDateTime a = LocalDateTime.of(y, m, d, h, mi, s, n);
3196         LocalDateTime b = LocalDateTime.of(y, m, d, h + 1, mi, s, n);
3197         assertFalse(a.equals(b));
3198     }
3199 
3200     @Test(dataProvider="sampleDateTimes")
3201     public void test_equals_false_minute_differs(int y, int m, int d, int h, int mi, int s, int n) {
3202         LocalDateTime a = LocalDateTime.of(y, m, d, h, mi, s, n);
3203         LocalDateTime b = LocalDateTime.of(y, m, d, h, mi + 1, s, n);
3204         assertFalse(a.equals(b));
3205     }
3206 
3207     @Test(dataProvider="sampleDateTimes")
3208     public void test_equals_false_second_differs(int y, int m, int d, int h, int mi, int s, int n) {
3209         LocalDateTime a = LocalDateTime.of(y, m, d, h, mi, s, n);
3210         LocalDateTime b = LocalDateTime.of(y, m, d, h, mi, s + 1, n);
3211         assertFalse(a.equals(b));
3212     }
3213 
3214     @Test(dataProvider="sampleDateTimes")
3215     public void test_equals_false_nano_differs(int y, int m, int d, int h, int mi, int s, int n) {
3216         LocalDateTime a = LocalDateTime.of(y, m, d, h, mi, s, n);
3217         LocalDateTime b = LocalDateTime.of(y, m, d, h, mi, s, n + 1);
3218         assertFalse(a.equals(b));
3219     }
3220 
3221     @Test
3222     public void test_equals_itself_true() {
3223         assertEquals(TEST_2007_07_15_12_30_40_987654321.equals(TEST_2007_07_15_12_30_40_987654321), true);
3224     }
3225 
3226     @Test
3227     public void test_equals_string_false() {
3228         assertEquals(TEST_2007_07_15_12_30_40_987654321.equals("2007-07-15T12:30:40.987654321"), false);
3229     }
3230 
3231     @Test
3232     public void test_equals_null_false() {
3233         assertEquals(TEST_2007_07_15_12_30_40_987654321.equals(null), false);
3234     }
3235 
3236     //-----------------------------------------------------------------------
3237     // hashCode()
3238     //-----------------------------------------------------------------------
3239     @Test(dataProvider="sampleDateTimes")
3240     public void test_hashCode(int y, int m, int d, int h, int mi, int s, int n) {
3241         LocalDateTime a = LocalDateTime.of(y, m, d, h, mi, s, n);
3242         assertEquals(a.hashCode(), a.hashCode());
3243         LocalDateTime b = LocalDateTime.of(y, m, d, h, mi, s, n);
3244         assertEquals(a.hashCode(), b.hashCode());
3245     }
3246 
3247     //-----------------------------------------------------------------------
3248     // toString()
3249     //-----------------------------------------------------------------------
3250     @DataProvider(name="sampleToString")
3251     Object[][] provider_sampleToString() {
3252         return new Object[][] {
3253             {2008, 7, 5, 2, 1, 0, 0, "2008-07-05T02:01"},
3254             {2007, 12, 31, 23, 59, 1, 0, "2007-12-31T23:59:01"},
3255             {999, 12, 31, 23, 59, 59, 990000000, "0999-12-31T23:59:59.990"},
3256             {-1, 1, 2, 23, 59, 59, 999990000, "-0001-01-02T23:59:59.999990"},
3257             {-2008, 1, 2, 23, 59, 59, 999999990, "-2008-01-02T23:59:59.999999990"},
3258         };
3259     }
3260 
3261     @Test(dataProvider="sampleToString")
3262     public void test_toString(int y, int m, int d, int h, int mi, int s, int n, String expected) {
3263         LocalDateTime t = LocalDateTime.of(y, m, d, h, mi, s, n);
3264         String str = t.toString();
3265         assertEquals(str, expected);
3266     }
3267 
3268     private LocalDateTime dtNoon(int year, int month, int day) {
3269         return LocalDateTime.of(year, month, day, 12, 0);
3270     }
3271 
3272     private LocalDateTime dtEpoch(int hour, int min, int sec, int nano) {
3273         return LocalDateTime.of(1970, 1, 1, hour, min, sec, nano);
3274     }
3275 
3276     private LocalDateTime dt(int year, int month, int day, int hour, int min, int sec, int nano) {
3277         return LocalDateTime.of(year, month, day, hour, min, sec, nano);
3278     }
3279 
3280 }
3281