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