1 /*
   2  * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * This file is available under and governed by the GNU General Public
  26  * License version 2 only, as published by the Free Software Foundation.
  27  * However, the following notice accompanied the original version of this
  28  * file:
  29  *
  30  * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos
  31  *
  32  * All rights reserved.
  33  *
  34  * Redistribution and use in source and binary forms, with or without
  35  * modification, are permitted provided that the following conditions are met:
  36  *
  37  *  * Redistributions of source code must retain the above copyright notice,
  38  *    this list of conditions and the following disclaimer.
  39  *
  40  *  * Redistributions in binary form must reproduce the above copyright notice,
  41  *    this list of conditions and the following disclaimer in the documentation
  42  *    and/or other materials provided with the distribution.
  43  *
  44  *  * Neither the name of JSR-310 nor the names of its contributors
  45  *    may be used to endorse or promote products derived from this software
  46  *    without specific prior written permission.
  47  *
  48  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  49  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  50  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  51  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  52  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  53  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  54  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  55  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  56  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  57  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  58  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  59  */
  60 package tck.java.time;
  61 
  62 import static java.time.temporal.ChronoField.AMPM_OF_DAY;
  63 import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_AMPM;
  64 import static java.time.temporal.ChronoField.CLOCK_HOUR_OF_DAY;
  65 import static java.time.temporal.ChronoField.HOUR_OF_AMPM;
  66 import static java.time.temporal.ChronoField.HOUR_OF_DAY;
  67 import static java.time.temporal.ChronoField.MICRO_OF_DAY;
  68 import static java.time.temporal.ChronoField.MICRO_OF_SECOND;
  69 import static java.time.temporal.ChronoField.MILLI_OF_DAY;
  70 import static java.time.temporal.ChronoField.MILLI_OF_SECOND;
  71 import static java.time.temporal.ChronoField.MINUTE_OF_DAY;
  72 import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
  73 import static java.time.temporal.ChronoField.NANO_OF_DAY;
  74 import static java.time.temporal.ChronoField.NANO_OF_SECOND;
  75 import static java.time.temporal.ChronoField.SECOND_OF_DAY;
  76 import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
  77 import static java.time.temporal.ChronoUnit.DAYS;
  78 import static java.time.temporal.ChronoUnit.FOREVER;
  79 import static java.time.temporal.ChronoUnit.HALF_DAYS;
  80 import static java.time.temporal.ChronoUnit.HOURS;
  81 import static java.time.temporal.ChronoUnit.MICROS;
  82 import static java.time.temporal.ChronoUnit.MILLIS;
  83 import static java.time.temporal.ChronoUnit.MINUTES;
  84 import static java.time.temporal.ChronoUnit.MONTHS;
  85 import static java.time.temporal.ChronoUnit.NANOS;
  86 import static java.time.temporal.ChronoUnit.SECONDS;
  87 import static java.time.temporal.ChronoUnit.WEEKS;
  88 import static java.time.temporal.ChronoUnit.YEARS;
  89 import static org.testng.Assert.assertEquals;
  90 import static org.testng.Assert.assertNotNull;
  91 import static org.testng.Assert.assertSame;
  92 import static org.testng.Assert.assertTrue;
  93 import static org.testng.Assert.fail;
  94 
  95 import java.time.Clock;
  96 import java.time.DateTimeException;
  97 import java.time.Duration;
  98 import java.time.Instant;
  99 import java.time.LocalDate;
 100 import java.time.LocalDateTime;
 101 import java.time.LocalTime;
 102 import java.time.OffsetDateTime;
 103 import java.time.OffsetTime;
 104 import java.time.Period;
 105 import java.time.ZoneId;
 106 import java.time.ZoneOffset;
 107 import java.time.ZonedDateTime;
 108 import java.time.format.DateTimeFormatter;
 109 import java.time.format.DateTimeParseException;
 110 import java.time.temporal.ChronoField;
 111 import java.time.temporal.ChronoUnit;
 112 import java.time.temporal.JulianFields;
 113 import java.time.temporal.Temporal;
 114 import java.time.temporal.TemporalAccessor;
 115 import java.time.temporal.TemporalAdjuster;
 116 import java.time.temporal.TemporalAmount;
 117 import java.time.temporal.TemporalField;
 118 import java.time.temporal.TemporalQueries;
 119 import java.time.temporal.TemporalQuery;
 120 import java.time.temporal.TemporalUnit;
 121 import java.time.temporal.UnsupportedTemporalTypeException;
 122 import java.time.temporal.ValueRange;
 123 import java.util.ArrayList;
 124 import java.util.Arrays;
 125 import java.util.EnumSet;
 126 import java.util.Iterator;
 127 import java.util.List;
 128 
 129 import org.testng.annotations.BeforeMethod;
 130 import org.testng.annotations.DataProvider;
 131 import org.testng.annotations.Test;
 132 
 133 /**
 134  * Test LocalTime.
 135  */
 136 @Test
 137 public class TCKLocalTime extends AbstractDateTimeTest {
 138 
 139     private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2);
 140     private static final ZoneId ZONE_PARIS = ZoneId.of("Europe/Paris");
 141 
 142     private LocalTime TEST_12_30_40_987654321;
 143 
 144     private static final TemporalUnit[] INVALID_UNITS;
 145     static {
 146         EnumSet<ChronoUnit> set = EnumSet.range(DAYS, FOREVER);
 147         INVALID_UNITS = set.toArray(new TemporalUnit[set.size()]);
 148     }
 149 
 150     @BeforeMethod
 151     public void setUp() {
 152         TEST_12_30_40_987654321 = LocalTime.of(12, 30, 40, 987654321);
 153     }
 154 
 155     //-----------------------------------------------------------------------
 156     @Override
 157     protected List<TemporalAccessor> samples() {
 158         TemporalAccessor[] array = {TEST_12_30_40_987654321, LocalTime.MIN, LocalTime.MAX, LocalTime.MIDNIGHT, LocalTime.NOON};
 159         return Arrays.asList(array);
 160     }
 161 
 162     @Override
 163     protected List<TemporalField> validFields() {
 164         TemporalField[] array = {
 165             NANO_OF_SECOND,
 166             NANO_OF_DAY,
 167             MICRO_OF_SECOND,
 168             MICRO_OF_DAY,
 169             MILLI_OF_SECOND,
 170             MILLI_OF_DAY,
 171             SECOND_OF_MINUTE,
 172             SECOND_OF_DAY,
 173             MINUTE_OF_HOUR,
 174             MINUTE_OF_DAY,
 175             CLOCK_HOUR_OF_AMPM,
 176             HOUR_OF_AMPM,
 177             CLOCK_HOUR_OF_DAY,
 178             HOUR_OF_DAY,
 179             AMPM_OF_DAY,
 180         };
 181         return Arrays.asList(array);
 182     }
 183 
 184     @Override
 185     protected List<TemporalField> invalidFields() {
 186         List<TemporalField> list = new ArrayList<>(Arrays.<TemporalField>asList(ChronoField.values()));
 187         list.removeAll(validFields());
 188         list.add(JulianFields.JULIAN_DAY);
 189         list.add(JulianFields.MODIFIED_JULIAN_DAY);
 190         list.add(JulianFields.RATA_DIE);
 191         return list;
 192     }
 193 
 194     //-----------------------------------------------------------------------
 195 
 196     private void check(LocalTime test, int h, int m, int s, int n) {
 197         assertEquals(test.getHour(), h);
 198         assertEquals(test.getMinute(), m);
 199         assertEquals(test.getSecond(), s);
 200         assertEquals(test.getNano(), n);
 201         assertEquals(test, test);
 202         assertEquals(test.hashCode(), test.hashCode());
 203         assertEquals(LocalTime.of(h, m, s, n), test);
 204     }
 205 
 206     //-----------------------------------------------------------------------
 207     // constants
 208     //-----------------------------------------------------------------------
 209     @Test
 210     public void constant_MIDNIGHT() {
 211         check(LocalTime.MIDNIGHT, 0, 0, 0, 0);
 212     }
 213 
 214     @Test
 215     public void constant_MIDDAY() {
 216         check(LocalTime.NOON, 12, 0, 0, 0);
 217     }
 218 
 219     @Test
 220     public void constant_MIN() {
 221         check(LocalTime.MIN, 0, 0, 0, 0);
 222     }
 223 
 224     @Test
 225     public void constant_MAX() {
 226         check(LocalTime.MAX, 23, 59, 59, 999999999);
 227     }
 228 
 229     //-----------------------------------------------------------------------
 230     // now(ZoneId)
 231     //-----------------------------------------------------------------------
 232     @Test(expectedExceptions=NullPointerException.class)
 233     public void now_ZoneId_nullZoneId() {
 234         LocalTime.now((ZoneId) null);
 235     }
 236 
 237     @Test
 238     public void now_ZoneId() {
 239         ZoneId zone = ZoneId.of("UTC+01:02:03");
 240         LocalTime expected = LocalTime.now(Clock.system(zone));
 241         LocalTime test = LocalTime.now(zone);
 242         for (int i = 0; i < 100; i++) {
 243             if (expected.equals(test)) {
 244                 return;
 245             }
 246             expected = LocalTime.now(Clock.system(zone));
 247             test = LocalTime.now(zone);
 248         }
 249         assertEquals(test.truncatedTo(ChronoUnit.SECONDS),
 250                      expected.truncatedTo(ChronoUnit.SECONDS));
 251     }
 252 
 253     //-----------------------------------------------------------------------
 254     // now(Clock)
 255     //-----------------------------------------------------------------------
 256     @Test(expectedExceptions=NullPointerException.class)
 257     public void now_Clock_nullClock() {
 258         LocalTime.now((Clock) null);
 259     }
 260 
 261     @Test
 262     public void now_Clock_allSecsInDay() {
 263         for (int i = 0; i < (2 * 24 * 60 * 60); i++) {
 264             Instant instant = Instant.ofEpochSecond(i, 8);
 265             Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
 266             LocalTime test = LocalTime.now(clock);
 267             assertEquals(test.getHour(), (i / (60 * 60)) % 24);
 268             assertEquals(test.getMinute(), (i / 60) % 60);
 269             assertEquals(test.getSecond(), i % 60);
 270             assertEquals(test.getNano(), 8);
 271         }
 272     }
 273 
 274     @Test
 275     public void now_Clock_beforeEpoch() {
 276         for (int i =-1; i >= -(24 * 60 * 60); i--) {
 277             Instant instant = Instant.ofEpochSecond(i, 8);
 278             Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
 279             LocalTime test = LocalTime.now(clock);
 280             assertEquals(test.getHour(), ((i + 24 * 60 * 60) / (60 * 60)) % 24);
 281             assertEquals(test.getMinute(), ((i + 24 * 60 * 60) / 60) % 60);
 282             assertEquals(test.getSecond(), (i + 24 * 60 * 60) % 60);
 283             assertEquals(test.getNano(), 8);
 284         }
 285     }
 286 
 287     //-----------------------------------------------------------------------
 288     @Test
 289     public void now_Clock_max() {
 290         Clock clock = Clock.fixed(Instant.MAX, ZoneOffset.UTC);
 291         LocalTime test = LocalTime.now(clock);
 292         assertEquals(test.getHour(), 23);
 293         assertEquals(test.getMinute(), 59);
 294         assertEquals(test.getSecond(), 59);
 295         assertEquals(test.getNano(), 999_999_999);
 296     }
 297 
 298     @Test
 299     public void now_Clock_min() {
 300         Clock clock = Clock.fixed(Instant.MIN, ZoneOffset.UTC);
 301         LocalTime test = LocalTime.now(clock);
 302         assertEquals(test.getHour(), 0);
 303         assertEquals(test.getMinute(), 0);
 304         assertEquals(test.getSecond(), 0);
 305         assertEquals(test.getNano(), 0);
 306     }
 307 
 308     //-----------------------------------------------------------------------
 309     // of() factories
 310     //-----------------------------------------------------------------------
 311     @Test
 312     public void factory_time_2ints() {
 313         LocalTime test = LocalTime.of(12, 30);
 314         check(test, 12, 30, 0, 0);
 315     }
 316 
 317     @Test(expectedExceptions=DateTimeException.class)
 318     public void factory_time_2ints_hourTooLow() {
 319         LocalTime.of(-1, 0);
 320     }
 321 
 322     @Test(expectedExceptions=DateTimeException.class)
 323     public void factory_time_2ints_hourTooHigh() {
 324         LocalTime.of(24, 0);
 325     }
 326 
 327     @Test(expectedExceptions=DateTimeException.class)
 328     public void factory_time_2ints_minuteTooLow() {
 329         LocalTime.of(0, -1);
 330     }
 331 
 332     @Test(expectedExceptions=DateTimeException.class)
 333     public void factory_time_2ints_minuteTooHigh() {
 334         LocalTime.of(0, 60);
 335     }
 336 
 337     //-----------------------------------------------------------------------
 338     @Test
 339     public void factory_time_3ints() {
 340         LocalTime test = LocalTime.of(12, 30, 40);
 341         check(test, 12, 30, 40, 0);
 342     }
 343 
 344     @Test(expectedExceptions=DateTimeException.class)
 345     public void factory_time_3ints_hourTooLow() {
 346         LocalTime.of(-1, 0, 0);
 347     }
 348 
 349     @Test(expectedExceptions=DateTimeException.class)
 350     public void factory_time_3ints_hourTooHigh() {
 351         LocalTime.of(24, 0, 0);
 352     }
 353 
 354     @Test(expectedExceptions=DateTimeException.class)
 355     public void factory_time_3ints_minuteTooLow() {
 356         LocalTime.of(0, -1, 0);
 357     }
 358 
 359     @Test(expectedExceptions=DateTimeException.class)
 360     public void factory_time_3ints_minuteTooHigh() {
 361         LocalTime.of(0, 60, 0);
 362     }
 363 
 364     @Test(expectedExceptions=DateTimeException.class)
 365     public void factory_time_3ints_secondTooLow() {
 366         LocalTime.of(0, 0, -1);
 367     }
 368 
 369     @Test(expectedExceptions=DateTimeException.class)
 370     public void factory_time_3ints_secondTooHigh() {
 371         LocalTime.of(0, 0, 60);
 372     }
 373 
 374     //-----------------------------------------------------------------------
 375     @Test
 376     public void factory_time_4ints() {
 377         LocalTime test = LocalTime.of(12, 30, 40, 987654321);
 378         check(test, 12, 30, 40, 987654321);
 379         test = LocalTime.of(12, 0, 40, 987654321);
 380         check(test, 12, 0, 40, 987654321);
 381     }
 382 
 383     @Test(expectedExceptions=DateTimeException.class)
 384     public void factory_time_4ints_hourTooLow() {
 385         LocalTime.of(-1, 0, 0, 0);
 386     }
 387 
 388     @Test(expectedExceptions=DateTimeException.class)
 389     public void factory_time_4ints_hourTooHigh() {
 390         LocalTime.of(24, 0, 0, 0);
 391     }
 392 
 393     @Test(expectedExceptions=DateTimeException.class)
 394     public void factory_time_4ints_minuteTooLow() {
 395         LocalTime.of(0, -1, 0, 0);
 396     }
 397 
 398     @Test(expectedExceptions=DateTimeException.class)
 399     public void factory_time_4ints_minuteTooHigh() {
 400         LocalTime.of(0, 60, 0, 0);
 401     }
 402 
 403     @Test(expectedExceptions=DateTimeException.class)
 404     public void factory_time_4ints_secondTooLow() {
 405         LocalTime.of(0, 0, -1, 0);
 406     }
 407 
 408     @Test(expectedExceptions=DateTimeException.class)
 409     public void factory_time_4ints_secondTooHigh() {
 410         LocalTime.of(0, 0, 60, 0);
 411     }
 412 
 413     @Test(expectedExceptions=DateTimeException.class)
 414     public void factory_time_4ints_nanoTooLow() {
 415         LocalTime.of(0, 0, 0, -1);
 416     }
 417 
 418     @Test(expectedExceptions=DateTimeException.class)
 419     public void factory_time_4ints_nanoTooHigh() {
 420         LocalTime.of(0, 0, 0, 1000000000);
 421     }
 422 
 423     //-----------------------------------------------------------------------
 424     // ofSecondOfDay(long)
 425     //-----------------------------------------------------------------------
 426     @Test
 427     public void factory_ofSecondOfDay() {
 428         LocalTime localTime = LocalTime.ofSecondOfDay(2 * 60 * 60 + 17 * 60 + 23);
 429         check(localTime, 2, 17, 23, 0);
 430     }
 431 
 432     @Test(expectedExceptions=DateTimeException.class)
 433     public void factory_ofSecondOfDay_tooLow() {
 434         LocalTime.ofSecondOfDay(-1);
 435     }
 436 
 437     @Test(expectedExceptions=DateTimeException.class)
 438     public void factory_ofSecondOfDay_tooHigh() {
 439         LocalTime.ofSecondOfDay(24 * 60 * 60);
 440     }
 441 
 442     //-----------------------------------------------------------------------
 443     // ofNanoOfDay(long)
 444     //-----------------------------------------------------------------------
 445     @Test
 446     public void factory_ofNanoOfDay() {
 447         LocalTime localTime = LocalTime.ofNanoOfDay(60 * 60 * 1000000000L + 17);
 448         check(localTime, 1, 0, 0, 17);
 449     }
 450 
 451     @Test(expectedExceptions=DateTimeException.class)
 452     public void factory_ofNanoOfDay_tooLow() {
 453         LocalTime.ofNanoOfDay(-1);
 454     }
 455 
 456     @Test(expectedExceptions=DateTimeException.class)
 457     public void factory_ofNanoOfDay_tooHigh() {
 458         LocalTime.ofNanoOfDay(24 * 60 * 60 * 1000000000L);
 459     }
 460 
 461     //-----------------------------------------------------------------------
 462     // from()
 463     //-----------------------------------------------------------------------
 464     @Test
 465     public void factory_from_TemporalAccessor() {
 466         assertEquals(LocalTime.from(LocalTime.of(17, 30)), LocalTime.of(17, 30));
 467         assertEquals(LocalTime.from(LocalDateTime.of(2012, 5, 1, 17, 30)), LocalTime.of(17, 30));
 468     }
 469 
 470     @Test(expectedExceptions=DateTimeException.class)
 471     public void factory_from_TemporalAccessor_invalid_noDerive() {
 472         LocalTime.from(LocalDate.of(2007, 7, 15));
 473     }
 474 
 475     @Test(expectedExceptions=NullPointerException.class)
 476     public void factory_from_TemporalAccessor_null() {
 477         LocalTime.from((TemporalAccessor) null);
 478     }
 479 
 480     //-----------------------------------------------------------------------
 481     // parse()
 482     //-----------------------------------------------------------------------
 483     @Test(dataProvider = "sampleToString")
 484     public void factory_parse_validText(int h, int m, int s, int n, String parsable) {
 485         LocalTime t = LocalTime.parse(parsable);
 486         assertNotNull(t, parsable);
 487         assertEquals(t.getHour(), h);
 488         assertEquals(t.getMinute(), m);
 489         assertEquals(t.getSecond(), s);
 490         assertEquals(t.getNano(), n);
 491     }
 492 
 493     @DataProvider(name="sampleBadParse")
 494     Object[][] provider_sampleBadParse() {
 495         return new Object[][]{
 496                 {"00;00"},
 497                 {"12-00"},
 498                 {"-01:00"},
 499                 {"00:00:00-09"},
 500                 {"00:00:00,09"},
 501                 {"00:00:abs"},
 502                 {"11"},
 503                 {"11:30+01:00"},
 504                 {"11:30+01:00[Europe/Paris]"},
 505         };
 506     }
 507 
 508     @Test(dataProvider = "sampleBadParse", expectedExceptions={DateTimeParseException.class})
 509     public void factory_parse_invalidText(String unparsable) {
 510         LocalTime.parse(unparsable);
 511     }
 512 
 513     //-----------------------------------------------------------------------s
 514     @Test(expectedExceptions=DateTimeParseException.class)
 515     public void factory_parse_illegalHour() {
 516         LocalTime.parse("25:00");
 517     }
 518 
 519     @Test(expectedExceptions=DateTimeParseException.class)
 520     public void factory_parse_illegalMinute() {
 521         LocalTime.parse("12:60");
 522     }
 523 
 524     @Test(expectedExceptions=DateTimeParseException.class)
 525     public void factory_parse_illegalSecond() {
 526         LocalTime.parse("12:12:60");
 527     }
 528 
 529     //-----------------------------------------------------------------------s
 530     @Test(expectedExceptions = {NullPointerException.class})
 531     public void factory_parse_nullTest() {
 532         LocalTime.parse((String) null);
 533     }
 534 
 535     //-----------------------------------------------------------------------
 536     // parse(DateTimeFormatter)
 537     //-----------------------------------------------------------------------
 538     @Test
 539     public void factory_parse_formatter() {
 540         DateTimeFormatter f = DateTimeFormatter.ofPattern("H m s");
 541         LocalTime test = LocalTime.parse("14 30 40", f);
 542         assertEquals(test, LocalTime.of(14, 30, 40));
 543     }
 544 
 545     @Test(expectedExceptions=NullPointerException.class)
 546     public void factory_parse_formatter_nullText() {
 547         DateTimeFormatter f = DateTimeFormatter.ofPattern("H m s");
 548         LocalTime.parse((String) null, f);
 549     }
 550 
 551     @Test(expectedExceptions=NullPointerException.class)
 552     public void factory_parse_formatter_nullFormatter() {
 553         LocalTime.parse("ANY", null);
 554     }
 555 
 556     //-----------------------------------------------------------------------
 557     // isSupported(TemporalField)
 558     //-----------------------------------------------------------------------
 559     @Test
 560     public void test_isSupported_TemporalField() {
 561         assertEquals(TEST_12_30_40_987654321.isSupported((TemporalField) null), false);
 562         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.NANO_OF_SECOND), true);
 563         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.NANO_OF_DAY), true);
 564         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MICRO_OF_SECOND), true);
 565         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MICRO_OF_DAY), true);
 566         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MILLI_OF_SECOND), true);
 567         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MILLI_OF_DAY), true);
 568         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.SECOND_OF_MINUTE), true);
 569         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.SECOND_OF_DAY), true);
 570         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MINUTE_OF_HOUR), true);
 571         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MINUTE_OF_DAY), true);
 572         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.HOUR_OF_AMPM), true);
 573         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.CLOCK_HOUR_OF_AMPM), true);
 574         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.HOUR_OF_DAY), true);
 575         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.CLOCK_HOUR_OF_DAY), true);
 576         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.AMPM_OF_DAY), true);
 577         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.DAY_OF_WEEK), false);
 578         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), false);
 579         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), false);
 580         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.DAY_OF_MONTH), false);
 581         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.DAY_OF_YEAR), false);
 582         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.EPOCH_DAY), false);
 583         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ALIGNED_WEEK_OF_MONTH), false);
 584         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ALIGNED_WEEK_OF_YEAR), false);
 585         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.MONTH_OF_YEAR), false);
 586         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.PROLEPTIC_MONTH), false);
 587         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.YEAR), false);
 588         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.YEAR_OF_ERA), false);
 589         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.ERA), false);
 590         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.INSTANT_SECONDS), false);
 591         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoField.OFFSET_SECONDS), false);
 592     }
 593 
 594     //-----------------------------------------------------------------------
 595     // isSupported(TemporalUnit)
 596     //-----------------------------------------------------------------------
 597     @Test
 598     public void test_isSupported_TemporalUnit() {
 599         assertEquals(TEST_12_30_40_987654321.isSupported((TemporalUnit) null), false);
 600         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.NANOS), true);
 601         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MICROS), true);
 602         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MILLIS), true);
 603         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.SECONDS), true);
 604         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MINUTES), true);
 605         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.HOURS), true);
 606         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.HALF_DAYS), true);
 607         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.DAYS), false);
 608         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.WEEKS), false);
 609         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MONTHS), false);
 610         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.YEARS), false);
 611         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.DECADES), false);
 612         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.CENTURIES), false);
 613         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.MILLENNIA), false);
 614         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.ERAS), false);
 615         assertEquals(TEST_12_30_40_987654321.isSupported(ChronoUnit.FOREVER), false);
 616     }
 617 
 618     //-----------------------------------------------------------------------
 619     // get(TemporalField)
 620     //-----------------------------------------------------------------------
 621     @Test
 622     public void test_get_TemporalField() {
 623         LocalTime test = TEST_12_30_40_987654321;
 624         assertEquals(test.get(ChronoField.HOUR_OF_DAY), 12);
 625         assertEquals(test.get(ChronoField.MINUTE_OF_HOUR), 30);
 626         assertEquals(test.get(ChronoField.SECOND_OF_MINUTE), 40);
 627         assertEquals(test.get(ChronoField.NANO_OF_SECOND), 987654321);
 628 
 629         assertEquals(test.get(ChronoField.SECOND_OF_DAY), 12 * 3600 + 30 * 60 + 40);
 630         assertEquals(test.get(ChronoField.MINUTE_OF_DAY), 12 * 60 + 30);
 631         assertEquals(test.get(ChronoField.HOUR_OF_AMPM), 0);
 632         assertEquals(test.get(ChronoField.CLOCK_HOUR_OF_AMPM), 12);
 633         assertEquals(test.get(ChronoField.CLOCK_HOUR_OF_DAY), 12);
 634         assertEquals(test.get(ChronoField.AMPM_OF_DAY), 1);
 635     }
 636 
 637     @Test
 638     public void test_getLong_TemporalField() {
 639         LocalTime test = TEST_12_30_40_987654321;
 640         assertEquals(test.getLong(ChronoField.HOUR_OF_DAY), 12);
 641         assertEquals(test.getLong(ChronoField.MINUTE_OF_HOUR), 30);
 642         assertEquals(test.getLong(ChronoField.SECOND_OF_MINUTE), 40);
 643         assertEquals(test.getLong(ChronoField.NANO_OF_SECOND), 987654321);
 644 
 645         assertEquals(test.getLong(ChronoField.SECOND_OF_DAY), 12 * 3600 + 30 * 60 + 40);
 646         assertEquals(test.getLong(ChronoField.MINUTE_OF_DAY), 12 * 60 + 30);
 647         assertEquals(test.getLong(ChronoField.HOUR_OF_AMPM), 0);
 648         assertEquals(test.getLong(ChronoField.CLOCK_HOUR_OF_AMPM), 12);
 649         assertEquals(test.getLong(ChronoField.CLOCK_HOUR_OF_DAY), 12);
 650         assertEquals(test.getLong(ChronoField.AMPM_OF_DAY), 1);
 651     }
 652 
 653     //-----------------------------------------------------------------------
 654     // query(TemporalQuery)
 655     //-----------------------------------------------------------------------
 656     @DataProvider(name="query")
 657     Object[][] data_query() {
 658         return new Object[][] {
 659                 {TEST_12_30_40_987654321, TemporalQueries.chronology(), null},
 660                 {TEST_12_30_40_987654321, TemporalQueries.zoneId(), null},
 661                 {TEST_12_30_40_987654321, TemporalQueries.precision(), ChronoUnit.NANOS},
 662                 {TEST_12_30_40_987654321, TemporalQueries.zone(), null},
 663                 {TEST_12_30_40_987654321, TemporalQueries.offset(), null},
 664                 {TEST_12_30_40_987654321, TemporalQueries.localDate(), null},
 665                 {TEST_12_30_40_987654321, TemporalQueries.localTime(), TEST_12_30_40_987654321},
 666         };
 667     }
 668 
 669     @Test(dataProvider="query")
 670     public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
 671         assertEquals(temporal.query(query), expected);
 672     }
 673 
 674     @Test(dataProvider="query")
 675     public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
 676         assertEquals(query.queryFrom(temporal), expected);
 677     }
 678 
 679     @Test(expectedExceptions=NullPointerException.class)
 680     public void test_query_null() {
 681         TEST_12_30_40_987654321.query(null);
 682     }
 683 
 684     //-----------------------------------------------------------------------
 685     // get*()
 686     //-----------------------------------------------------------------------
 687     @DataProvider(name="sampleTimes")
 688     Object[][] provider_sampleTimes() {
 689         return new Object[][] {
 690             {0, 0, 0, 0},
 691             {0, 0, 0, 1},
 692             {0, 0, 1, 0},
 693             {0, 0, 1, 1},
 694             {0, 1, 0, 0},
 695             {0, 1, 0, 1},
 696             {0, 1, 1, 0},
 697             {0, 1, 1, 1},
 698             {1, 0, 0, 0},
 699             {1, 0, 0, 1},
 700             {1, 0, 1, 0},
 701             {1, 0, 1, 1},
 702             {1, 1, 0, 0},
 703             {1, 1, 0, 1},
 704             {1, 1, 1, 0},
 705             {1, 1, 1, 1},
 706         };
 707     }
 708 
 709     //-----------------------------------------------------------------------
 710     @Test(dataProvider="sampleTimes")
 711     public void test_get(int h, int m, int s, int ns) {
 712         LocalTime a = LocalTime.of(h, m, s, ns);
 713         assertEquals(a.getHour(), h);
 714         assertEquals(a.getMinute(), m);
 715         assertEquals(a.getSecond(), s);
 716         assertEquals(a.getNano(), ns);
 717     }
 718 
 719     //-----------------------------------------------------------------------
 720     // adjustInto(Temporal)
 721     //-----------------------------------------------------------------------
 722     @DataProvider(name="adjustInto")
 723     Object[][] data_adjustInto() {
 724         return new Object[][]{
 725                 {LocalTime.of(23, 5), LocalTime.of(4, 1, 1, 100), LocalTime.of(23, 5, 0, 0), null},
 726                 {LocalTime.of(23, 5, 20), LocalTime.of(4, 1, 1, 100), LocalTime.of(23, 5, 20, 0), null},
 727                 {LocalTime.of(23, 5, 20, 1000), LocalTime.of(4, 1, 1, 100), LocalTime.of(23, 5, 20, 1000), null},
 728                 {LocalTime.of(23, 5, 20, 1000), LocalTime.MAX, LocalTime.of(23, 5, 20, 1000), null},
 729                 {LocalTime.of(23, 5, 20, 1000), LocalTime.MIN, LocalTime.of(23, 5, 20, 1000), null},
 730                 {LocalTime.of(23, 5, 20, 1000), LocalTime.NOON, LocalTime.of(23, 5, 20, 1000), null},
 731                 {LocalTime.of(23, 5, 20, 1000), LocalTime.MIDNIGHT, LocalTime.of(23, 5, 20, 1000), null},
 732                 {LocalTime.MAX, LocalTime.of(23, 5, 20, 1000), LocalTime.of(23, 59, 59, 999999999), null},
 733                 {LocalTime.MIN, LocalTime.of(23, 5, 20, 1000), LocalTime.of(0, 0, 0), null},
 734                 {LocalTime.NOON, LocalTime.of(23, 5, 20, 1000), LocalTime.of(12, 0, 0), null},
 735                 {LocalTime.MIDNIGHT, LocalTime.of(23, 5, 20, 1000), LocalTime.of(0, 0, 0), null},
 736 
 737                 {LocalTime.of(23, 5), LocalDateTime.of(2210, 2, 2, 1, 1), LocalDateTime.of(2210, 2, 2, 23, 5), null},
 738                 {LocalTime.of(23, 5), OffsetTime.of(1, 1, 0, 0, OFFSET_PTWO), OffsetTime.of(23, 5, 0, 0, OFFSET_PTWO), null},
 739                 {LocalTime.of(23, 5), OffsetDateTime.of(2210, 2, 2, 1, 1, 0, 0, OFFSET_PTWO), OffsetDateTime.of(2210, 2, 2, 23, 5, 0, 0, OFFSET_PTWO), null},
 740                 {LocalTime.of(23, 5), ZonedDateTime.of(2210, 2, 2, 1, 1, 0, 0, ZONE_PARIS), ZonedDateTime.of(2210, 2, 2, 23, 5, 0, 0, ZONE_PARIS), null},
 741 
 742                 {LocalTime.of(23, 5), LocalDate.of(2210, 2, 2), null, DateTimeException.class},
 743                 {LocalTime.of(23, 5), null, null, NullPointerException.class},
 744 
 745         };
 746     }
 747 
 748     @Test(dataProvider="adjustInto")
 749     public void test_adjustInto(LocalTime test, Temporal temporal, Temporal expected, Class<?> expectedEx) {
 750         if (expectedEx == null) {
 751             Temporal result = test.adjustInto(temporal);
 752             assertEquals(result, expected);
 753         } else {
 754             try {
 755                 Temporal result = test.adjustInto(temporal);
 756                 fail();
 757             } catch (Exception ex) {
 758                 assertTrue(expectedEx.isInstance(ex));
 759             }
 760         }
 761     }
 762 
 763     //-----------------------------------------------------------------------
 764     // with(TemporalAdjuster)
 765     //-----------------------------------------------------------------------
 766     @Test
 767     public void test_with_adjustment() {
 768         final LocalTime sample = LocalTime.of(23, 5);
 769         TemporalAdjuster adjuster = new TemporalAdjuster() {
 770             @Override
 771             public Temporal adjustInto(Temporal dateTime) {
 772                 return sample;
 773             }
 774         };
 775         assertEquals(TEST_12_30_40_987654321.with(adjuster), sample);
 776     }
 777 
 778     @Test(expectedExceptions=NullPointerException.class)
 779     public void test_with_adjustment_null() {
 780         TEST_12_30_40_987654321.with((TemporalAdjuster) null);
 781     }
 782 
 783     //-----------------------------------------------------------------------
 784     // with(TemporalField, long)
 785     //-----------------------------------------------------------------------
 786     private long[] testPoints(long max) {
 787         long[] points = new long[9];
 788         points[0] = 0;
 789         points[1] = 1;
 790         points[2] = 2;
 791         points[3] = max / 7;
 792         points[4] = (max / 7) * 2;
 793         points[5] = (max / 2);
 794         points[6] = (max / 7) * 6;;
 795         points[7] = max - 2;
 796         points[8] = max - 1;
 797         return points;
 798     }
 799 
 800     // Returns a {@code LocalTime} with the specified nano-of-second.
 801     // The hour, minute and second will be unchanged.
 802     @Test
 803     public void test_with_longTemporalField_nanoOfSecond() {
 804         for (long i : testPoints(1_000_000_000L)) {
 805             LocalTime test = TEST_12_30_40_987654321.with(NANO_OF_SECOND, i);
 806             assertEquals(test.get(NANO_OF_SECOND),  i);
 807             assertEquals(test.get(HOUR_OF_DAY), TEST_12_30_40_987654321.get(HOUR_OF_DAY));
 808             assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
 809             assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
 810         }
 811     }
 812 
 813     // Returns a {@code LocalTime} with the specified nano-of-day.
 814     // This completely replaces the time and is equivalent to {@link #ofNanoOfDay(long)}.
 815     @Test
 816     public void test_with_longTemporalField_nanoOfDay() {
 817         for (long i : testPoints(86_400_000_000_000L)) {
 818             LocalTime test = TEST_12_30_40_987654321.with(NANO_OF_DAY, i);
 819             assertEquals(test, LocalTime.ofNanoOfDay(i));
 820         }
 821     }
 822 
 823     // Returns a {@code LocalTime} with the nano-of-second replaced by the specified
 824     // micro-of-second multiplied by 1,000.
 825     // The hour, minute and second will be unchanged.
 826     @Test
 827     public void test_with_longTemporalField_microOfSecond() {
 828         for (long i : testPoints(1_000_000L)) {
 829             LocalTime test = TEST_12_30_40_987654321.with(MICRO_OF_SECOND, i);
 830             assertEquals(test.get(NANO_OF_SECOND),  i * 1_000);
 831             assertEquals(test.get(HOUR_OF_DAY), TEST_12_30_40_987654321.get(HOUR_OF_DAY));
 832             assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
 833             assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
 834         }
 835     }
 836 
 837     // Returns a {@code LocalTime} with the specified micro-of-day.
 838     // This completely replaces the time and is equivalent to using {@link #ofNanoOfDay(long)}
 839     // with the micro-of-day multiplied by 1,000.
 840     @Test
 841     public void test_with_longTemporalField_microOfDay() {
 842         for (long i : testPoints(86_400_000_000L)) {
 843             LocalTime test = TEST_12_30_40_987654321.with(MICRO_OF_DAY, i);
 844             assertEquals(test, LocalTime.ofNanoOfDay(i * 1000));
 845         }
 846     }
 847 
 848     // Returns a {@code LocalTime} with the nano-of-second replaced by the specified
 849     // milli-of-second multiplied by 1,000,000.
 850     // The hour, minute and second will be unchanged.
 851     @Test
 852     public void test_with_longTemporalField_milliOfSecond() {
 853         for (long i : testPoints(1_000L)) {
 854             LocalTime test = TEST_12_30_40_987654321.with(MILLI_OF_SECOND, i);
 855             assertEquals(test.get(NANO_OF_SECOND),  i * 1_000_000);
 856             assertEquals(test.get(HOUR_OF_DAY), TEST_12_30_40_987654321.get(HOUR_OF_DAY));
 857             assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
 858             assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
 859         }
 860     }
 861 
 862     // Returns a {@code LocalTime} with the specified milli-of-day.
 863     // This completely replaces the time and is equivalent to using {@link #ofNanoOfDay(long)}
 864     // with the milli-of-day multiplied by 1,000,000.
 865     @Test
 866     public void test_with_longTemporalField_milliOfDay() {
 867         for (long i : testPoints(86_400_000L)) {
 868             LocalTime test = TEST_12_30_40_987654321.with(MILLI_OF_DAY, i);
 869             assertEquals(test, LocalTime.ofNanoOfDay(i * 1_000_000));
 870         }
 871     }
 872 
 873     // Returns a {@code LocalTime} with the specified second-of-minute.
 874     // The hour, minute and nano-of-second will be unchanged.
 875     @Test
 876     public void test_with_longTemporalField_secondOfMinute() {
 877         for (long i : testPoints(60L)) {
 878             LocalTime test = TEST_12_30_40_987654321.with(SECOND_OF_MINUTE, i);
 879             assertEquals(test.get(SECOND_OF_MINUTE), i);
 880             assertEquals(test.get(HOUR_OF_DAY), TEST_12_30_40_987654321.get(HOUR_OF_DAY));
 881             assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
 882             assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
 883         }
 884     }
 885 
 886     // Returns a {@code LocalTime} with the specified second-of-day.
 887     // The nano-of-second will be unchanged.
 888     @Test
 889     public void test_with_longTemporalField_secondOfDay() {
 890         for (long i : testPoints(24 * 60 * 60)) {
 891             LocalTime test = TEST_12_30_40_987654321.with(SECOND_OF_DAY, i);
 892             assertEquals(test.get(SECOND_OF_DAY), i);
 893             assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
 894         }
 895     }
 896 
 897     // Returns a {@code LocalTime} with the specified minute-of-hour.
 898     // The hour, second-of-minute and nano-of-second will be unchanged.
 899     @Test
 900     public void test_with_longTemporalField_minuteOfHour() {
 901         for (long i : testPoints(60)) {
 902             LocalTime test = TEST_12_30_40_987654321.with(MINUTE_OF_HOUR, i);
 903             assertEquals(test.get(MINUTE_OF_HOUR), i);
 904             assertEquals(test.get(HOUR_OF_DAY), TEST_12_30_40_987654321.get(HOUR_OF_DAY));
 905             assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
 906             assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
 907         }
 908     }
 909 
 910     // Returns a {@code LocalTime} with the specified minute-of-day.
 911     // The second-of-minute and nano-of-second will be unchanged.
 912     @Test
 913     public void test_with_longTemporalField_minuteOfDay() {
 914         for (long i : testPoints(24 * 60)) {
 915             LocalTime test = TEST_12_30_40_987654321.with(MINUTE_OF_DAY, i);
 916             assertEquals(test.get(MINUTE_OF_DAY), i);
 917             assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
 918             assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
 919         }
 920     }
 921 
 922     // Returns a {@code LocalTime} with the specified hour-of-am-pm.
 923     // The AM/PM, minute-of-hour, second-of-minute and nano-of-second will be unchanged.
 924     @Test
 925     public void test_with_longTemporalField_hourOfAmPm() {
 926         for (int i = 0; i < 12; i++) {
 927             LocalTime test = TEST_12_30_40_987654321.with(HOUR_OF_AMPM, i);
 928             assertEquals(test.get(HOUR_OF_AMPM), i);
 929             assertEquals(test.get(AMPM_OF_DAY), TEST_12_30_40_987654321.get(AMPM_OF_DAY));
 930             assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
 931             assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
 932             assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
 933         }
 934     }
 935 
 936     // Returns a {@code LocalTime} with the specified clock-hour-of-am-pm.
 937     // The AM/PM, minute-of-hour, second-of-minute and nano-of-second will be unchanged.
 938     @Test
 939     public void test_with_longTemporalField_clockHourOfAmPm() {
 940         for (int i = 1; i <= 12; i++) {
 941             LocalTime test = TEST_12_30_40_987654321.with(CLOCK_HOUR_OF_AMPM, i);
 942             assertEquals(test.get(CLOCK_HOUR_OF_AMPM), i);
 943             assertEquals(test.get(AMPM_OF_DAY), TEST_12_30_40_987654321.get(AMPM_OF_DAY));
 944             assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
 945             assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
 946             assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
 947         }
 948     }
 949 
 950     // Returns a {@code LocalTime} with the specified hour-of-day.
 951     // The minute-of-hour, second-of-minute and nano-of-second will be unchanged.
 952     @Test
 953     public void test_with_longTemporalField_hourOfDay() {
 954         for (int i = 0; i < 24; i++) {
 955             LocalTime test = TEST_12_30_40_987654321.with(HOUR_OF_DAY, i);
 956             assertEquals(test.get(HOUR_OF_DAY), i);
 957             assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
 958             assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
 959             assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
 960         }
 961     }
 962 
 963     // Returns a {@code LocalTime} with the specified clock-hour-of-day.
 964     // The minute-of-hour, second-of-minute and nano-of-second will be unchanged.
 965     @Test
 966     public void test_with_longTemporalField_clockHourOfDay() {
 967         for (int i = 1; i <= 24; i++) {
 968             LocalTime test = TEST_12_30_40_987654321.with(CLOCK_HOUR_OF_DAY, i);
 969             assertEquals(test.get(CLOCK_HOUR_OF_DAY), i);
 970             assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
 971             assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
 972             assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
 973         }
 974     }
 975 
 976     // Returns a {@code LocalTime} with the specified AM/PM.
 977     // The hour-of-am-pm, minute-of-hour, second-of-minute and nano-of-second will be unchanged.
 978     @Test
 979     public void test_with_longTemporalField_amPmOfDay() {
 980         for (int i = 0; i <= 1; i++) {
 981             LocalTime test = TEST_12_30_40_987654321.with(AMPM_OF_DAY, i);
 982             assertEquals(test.get(AMPM_OF_DAY), i);
 983             assertEquals(test.get(HOUR_OF_AMPM), TEST_12_30_40_987654321.get(HOUR_OF_AMPM));
 984             assertEquals(test.get(MINUTE_OF_HOUR), TEST_12_30_40_987654321.get(MINUTE_OF_HOUR));
 985             assertEquals(test.get(SECOND_OF_MINUTE), TEST_12_30_40_987654321.get(SECOND_OF_MINUTE));
 986             assertEquals(test.get(NANO_OF_SECOND), TEST_12_30_40_987654321.get(NANO_OF_SECOND));
 987         }
 988     }
 989 
 990     // The supported fields behave as follows...
 991     // In all cases, if the new value is outside the valid range of values for the field
 992     // then a {@code DateTimeException} will be thrown.
 993     @DataProvider(name = "withTemporalField_outOfRange")
 994     Object[][] data_withTemporalField_outOfRange() {
 995         return new Object[][] {
 996                 {NANO_OF_SECOND, time(0, 0, 0, 0), NANO_OF_SECOND.range().getMinimum() - 1},
 997                 {NANO_OF_SECOND, time(0, 0, 0, 0), NANO_OF_SECOND.range().getMaximum() + 1},
 998 
 999                 {NANO_OF_DAY, time(0, 0, 0, 0), NANO_OF_DAY.range().getMinimum() - 1},
1000                 {NANO_OF_DAY, time(0, 0, 0, 0), NANO_OF_DAY.range().getMaximum() + 1},
1001 
1002                 {MICRO_OF_SECOND, time(0, 0, 0, 0), MICRO_OF_SECOND.range().getMinimum() - 1},
1003                 {MICRO_OF_SECOND, time(0, 0, 0, 0), MICRO_OF_SECOND.range().getMaximum() + 1},
1004 
1005                 {MICRO_OF_DAY, time(0, 0, 0, 0), MICRO_OF_DAY.range().getMinimum() - 1},
1006                 {MICRO_OF_DAY, time(0, 0, 0, 0), MICRO_OF_DAY.range().getMaximum() + 1},
1007 
1008                 {MILLI_OF_SECOND, time(0, 0, 0, 0), MILLI_OF_SECOND.range().getMinimum() - 1},
1009                 {MILLI_OF_SECOND, time(0, 0, 0, 0), MILLI_OF_SECOND.range().getMaximum() + 1},
1010 
1011                 {MILLI_OF_DAY, time(0, 0, 0, 0), MILLI_OF_DAY.range().getMinimum() - 1},
1012                 {MILLI_OF_DAY, time(0, 0, 0, 0), MILLI_OF_DAY.range().getMaximum() + 1},
1013 
1014                 {SECOND_OF_MINUTE, time(0, 0, 0, 0), SECOND_OF_MINUTE.range().getMinimum() - 1},
1015                 {SECOND_OF_MINUTE, time(0, 0, 0, 0), SECOND_OF_MINUTE.range().getMaximum() + 1},
1016 
1017                 {SECOND_OF_DAY, time(0, 0, 0, 0), SECOND_OF_DAY.range().getMinimum() - 1},
1018                 {SECOND_OF_DAY, time(0, 0, 0, 0), SECOND_OF_DAY.range().getMaximum() + 1},
1019 
1020                 {MINUTE_OF_HOUR, time(0, 0, 0, 0), MINUTE_OF_HOUR.range().getMinimum() - 1},
1021                 {MINUTE_OF_HOUR, time(0, 0, 0, 0), MINUTE_OF_HOUR.range().getMaximum() + 1},
1022 
1023                 {MINUTE_OF_DAY, time(0, 0, 0, 0), MINUTE_OF_DAY.range().getMinimum() - 1},
1024                 {MINUTE_OF_DAY, time(0, 0, 0, 0), MINUTE_OF_DAY.range().getMaximum() + 1},
1025 
1026                 {HOUR_OF_AMPM, time(0, 0, 0, 0), HOUR_OF_AMPM.range().getMinimum() - 1},
1027                 {HOUR_OF_AMPM, time(0, 0, 0, 0), HOUR_OF_AMPM.range().getMaximum() + 1},
1028 
1029                 {CLOCK_HOUR_OF_AMPM, time(0, 0, 0, 0), CLOCK_HOUR_OF_AMPM.range().getMinimum() - 1},
1030                 {CLOCK_HOUR_OF_AMPM, time(0, 0, 0, 0), CLOCK_HOUR_OF_AMPM.range().getMaximum() + 1},
1031 
1032                 {HOUR_OF_DAY, time(0, 0, 0, 0), HOUR_OF_DAY.range().getMinimum() - 1},
1033                 {HOUR_OF_DAY, time(0, 0, 0, 0), HOUR_OF_DAY.range().getMaximum() + 1},
1034 
1035                 {CLOCK_HOUR_OF_DAY, time(0, 0, 0, 0), CLOCK_HOUR_OF_DAY.range().getMinimum() - 1},
1036                 {CLOCK_HOUR_OF_DAY, time(0, 0, 0, 0), CLOCK_HOUR_OF_DAY.range().getMaximum() + 1},
1037 
1038                 {AMPM_OF_DAY, time(0, 0, 0, 0), AMPM_OF_DAY.range().getMinimum() - 1},
1039                 {AMPM_OF_DAY, time(0, 0, 0, 0), AMPM_OF_DAY.range().getMaximum() + 1},
1040         };
1041     }
1042 
1043     @Test(dataProvider = "withTemporalField_outOfRange")
1044     public void test_with_longTemporalField_invalid(TemporalField field, LocalTime base, long newValue) {
1045         try {
1046             base.with(field, newValue);
1047             fail("Field should not be allowed " + field);
1048         } catch (DateTimeException ex) {
1049             // expected
1050         }
1051     }
1052 
1053     // All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
1054     @Test(expectedExceptions=UnsupportedTemporalTypeException.class)
1055     public void test_with_longTemporalField_otherChronoField() {
1056         TEST_12_30_40_987654321.with(ChronoField.DAY_OF_MONTH, 1);
1057     }
1058 
1059     // If the field is not a {@code ChronoField}, then the result of this method
1060     // is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
1061     // passing {@code this} as the argument.
1062     @Test
1063     public void test_with_longTemporalField_notChronoField() {
1064         final LocalTime result = LocalTime.of(12, 30);
1065         final LocalTime base = LocalTime.of(15, 45);
1066         TemporalField field = new TemporalField() {
1067             public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
1068                 throw new UnsupportedOperationException();
1069             }
1070             public ValueRange range() {
1071                 return null;
1072             }
1073             public boolean isTimeBased() {
1074                 throw new UnsupportedOperationException();
1075             }
1076             public boolean isSupportedBy(TemporalAccessor temporal) {
1077                 throw new UnsupportedOperationException();
1078             }
1079             public boolean isDateBased() {
1080                 throw new UnsupportedOperationException();
1081             }
1082             public TemporalUnit getRangeUnit() {
1083                 throw new UnsupportedOperationException();
1084             }
1085             public long getFrom(TemporalAccessor temporal) {
1086                 throw new UnsupportedOperationException();
1087             }
1088             public TemporalUnit getBaseUnit() {
1089                 throw new UnsupportedOperationException();
1090             }
1091             public <R extends Temporal> R adjustInto(R temporal, long newValue) {
1092                 assertEquals(temporal, base);
1093                 assertEquals(newValue, 12L);
1094                 @SuppressWarnings("unchecked")
1095                 R r = (R) result;
1096                 return r;
1097             }
1098         };
1099         LocalTime test = base.with(field, 12L);
1100         assertSame(test, result);
1101     }
1102 
1103     @Test(expectedExceptions=NullPointerException.class)
1104     public void test_with_longTemporalField_null() {
1105         TEST_12_30_40_987654321.with((TemporalField) null, 1);
1106     }
1107 
1108     //-----------------------------------------------------------------------
1109     // withHour()
1110     //-----------------------------------------------------------------------
1111     @Test
1112     public void test_withHour_normal() {
1113         LocalTime t = TEST_12_30_40_987654321;
1114         for (int i = 0; i < 24; i++) {
1115             t = t.withHour(i);
1116             assertEquals(t.getHour(), i);
1117         }
1118     }
1119 
1120     @Test
1121     public void test_withHour_noChange_equal() {
1122         LocalTime t = TEST_12_30_40_987654321.withHour(12);
1123         assertEquals(t, TEST_12_30_40_987654321);
1124     }
1125 
1126     @Test
1127     public void test_withHour_toMidnight_equal() {
1128         LocalTime t = LocalTime.of(1, 0).withHour(0);
1129         assertEquals(t, LocalTime.MIDNIGHT);
1130     }
1131 
1132     @Test
1133     public void test_withHour_toMidday_equal() {
1134         LocalTime t = LocalTime.of(1, 0).withHour(12);
1135         assertEquals(t, LocalTime.NOON);
1136     }
1137 
1138     @Test(expectedExceptions=DateTimeException.class)
1139     public void test_withHour_hourTooLow() {
1140         TEST_12_30_40_987654321.withHour(-1);
1141     }
1142 
1143     @Test(expectedExceptions=DateTimeException.class)
1144     public void test_withHour_hourTooHigh() {
1145         TEST_12_30_40_987654321.withHour(24);
1146     }
1147 
1148     //-----------------------------------------------------------------------
1149     // withMinute()
1150     //-----------------------------------------------------------------------
1151     @Test
1152     public void test_withMinute_normal() {
1153         LocalTime t = TEST_12_30_40_987654321;
1154         for (int i = 0; i < 60; i++) {
1155             t = t.withMinute(i);
1156             assertEquals(t.getMinute(), i);
1157         }
1158     }
1159 
1160     @Test
1161     public void test_withMinute_noChange_equal() {
1162         LocalTime t = TEST_12_30_40_987654321.withMinute(30);
1163         assertEquals(t, TEST_12_30_40_987654321);
1164     }
1165 
1166     @Test
1167     public void test_withMinute_toMidnight_equal() {
1168         LocalTime t = LocalTime.of(0, 1).withMinute(0);
1169         assertEquals(t, LocalTime.MIDNIGHT);
1170     }
1171 
1172     @Test
1173     public void test_withMinute_toMidday_equals() {
1174         LocalTime t = LocalTime.of(12, 1).withMinute(0);
1175         assertEquals(t, LocalTime.NOON);
1176     }
1177 
1178     @Test(expectedExceptions=DateTimeException.class)
1179     public void test_withMinute_minuteTooLow() {
1180         TEST_12_30_40_987654321.withMinute(-1);
1181     }
1182 
1183     @Test(expectedExceptions=DateTimeException.class)
1184     public void test_withMinute_minuteTooHigh() {
1185         TEST_12_30_40_987654321.withMinute(60);
1186     }
1187 
1188     //-----------------------------------------------------------------------
1189     // withSecond()
1190     //-----------------------------------------------------------------------
1191     @Test
1192     public void test_withSecond_normal() {
1193         LocalTime t = TEST_12_30_40_987654321;
1194         for (int i = 0; i < 60; i++) {
1195             t = t.withSecond(i);
1196             assertEquals(t.getSecond(), i);
1197         }
1198     }
1199 
1200     @Test
1201     public void test_withSecond_noChange_equal() {
1202         LocalTime t = TEST_12_30_40_987654321.withSecond(40);
1203         assertEquals(t, TEST_12_30_40_987654321);
1204     }
1205 
1206     @Test
1207     public void test_withSecond_toMidnight_equal() {
1208         LocalTime t = LocalTime.of(0, 0, 1).withSecond(0);
1209         assertEquals(t, LocalTime.MIDNIGHT);
1210     }
1211 
1212     @Test
1213     public void test_withSecond_toMidday_equal() {
1214         LocalTime t = LocalTime.of(12, 0, 1).withSecond(0);
1215         assertEquals(t, LocalTime.NOON);
1216     }
1217 
1218     @Test(expectedExceptions=DateTimeException.class)
1219     public void test_withSecond_secondTooLow() {
1220         TEST_12_30_40_987654321.withSecond(-1);
1221     }
1222 
1223     @Test(expectedExceptions=DateTimeException.class)
1224     public void test_withSecond_secondTooHigh() {
1225         TEST_12_30_40_987654321.withSecond(60);
1226     }
1227 
1228     //-----------------------------------------------------------------------
1229     // withNano()
1230     //-----------------------------------------------------------------------
1231     @Test
1232     public void test_withNanoOfSecond_normal() {
1233         LocalTime t = TEST_12_30_40_987654321;
1234         t = t.withNano(1);
1235         assertEquals(t.getNano(), 1);
1236         t = t.withNano(10);
1237         assertEquals(t.getNano(), 10);
1238         t = t.withNano(100);
1239         assertEquals(t.getNano(), 100);
1240         t = t.withNano(999999999);
1241         assertEquals(t.getNano(), 999999999);
1242     }
1243 
1244     @Test
1245     public void test_withNanoOfSecond_noChange_equal() {
1246         LocalTime t = TEST_12_30_40_987654321.withNano(987654321);
1247         assertEquals(t, TEST_12_30_40_987654321);
1248     }
1249 
1250     @Test
1251     public void test_withNanoOfSecond_toMidnight_equal() {
1252         LocalTime t = LocalTime.of(0, 0, 0, 1).withNano(0);
1253         assertEquals(t, LocalTime.MIDNIGHT);
1254     }
1255 
1256     @Test
1257     public void test_withNanoOfSecond_toMidday_equal() {
1258         LocalTime t = LocalTime.of(12, 0, 0, 1).withNano(0);
1259         assertEquals(t, LocalTime.NOON);
1260     }
1261 
1262     @Test(expectedExceptions=DateTimeException.class)
1263     public void test_withNanoOfSecond_nanoTooLow() {
1264         TEST_12_30_40_987654321.withNano(-1);
1265     }
1266 
1267     @Test(expectedExceptions=DateTimeException.class)
1268     public void test_withNanoOfSecond_nanoTooHigh() {
1269         TEST_12_30_40_987654321.withNano(1000000000);
1270     }
1271 
1272     //-----------------------------------------------------------------------
1273     // truncated(TemporalUnit)
1274     //-----------------------------------------------------------------------
1275     TemporalUnit NINETY_MINS = new TemporalUnit() {
1276         @Override
1277         public Duration getDuration() {
1278             return Duration.ofMinutes(90);
1279         }
1280         @Override
1281         public boolean isDurationEstimated() {
1282             return false;
1283         }
1284         @Override
1285         public boolean isDateBased() {
1286             return false;
1287         }
1288         @Override
1289         public boolean isTimeBased() {
1290             return true;
1291         }
1292         @Override
1293         public boolean isSupportedBy(Temporal temporal) {
1294             return false;
1295         }
1296         @Override
1297         public <R extends Temporal> R addTo(R temporal, long amount) {
1298             throw new UnsupportedOperationException();
1299         }
1300         @Override
1301         public long between(Temporal temporal1, Temporal temporal2) {
1302             throw new UnsupportedOperationException();
1303         }
1304         @Override
1305         public String toString() {
1306             return "NinetyMins";
1307         }
1308     };
1309 
1310     TemporalUnit NINETY_FIVE_MINS = new TemporalUnit() {
1311         @Override
1312         public Duration getDuration() {
1313             return Duration.ofMinutes(95);
1314         }
1315         @Override
1316         public boolean isDurationEstimated() {
1317             return false;
1318         }
1319         @Override
1320         public boolean isDateBased() {
1321             return false;
1322         }
1323         @Override
1324         public boolean isTimeBased() {
1325             return false;
1326         }
1327         @Override
1328         public boolean isSupportedBy(Temporal temporal) {
1329             return false;
1330         }
1331         @Override
1332         public <R extends Temporal> R addTo(R temporal, long amount) {
1333             throw new UnsupportedOperationException();
1334         }
1335         @Override
1336         public long between(Temporal temporal1, Temporal temporal2) {
1337             throw new UnsupportedOperationException();
1338         }
1339         @Override
1340         public String toString() {
1341             return "NinetyFiveMins";
1342         }
1343     };
1344 
1345     @DataProvider(name="truncatedToValid")
1346     Object[][] data_truncatedToValid() {
1347         return new Object[][] {
1348             {LocalTime.of(1, 2, 3, 123_456_789), NANOS, LocalTime.of(1, 2, 3, 123_456_789)},
1349             {LocalTime.of(1, 2, 3, 123_456_789), MICROS, LocalTime.of(1, 2, 3, 123_456_000)},
1350             {LocalTime.of(1, 2, 3, 123_456_789), MILLIS, LocalTime.of(1, 2, 3, 1230_00_000)},
1351             {LocalTime.of(1, 2, 3, 123_456_789), SECONDS, LocalTime.of(1, 2, 3)},
1352             {LocalTime.of(1, 2, 3, 123_456_789), MINUTES, LocalTime.of(1, 2)},
1353             {LocalTime.of(1, 2, 3, 123_456_789), HOURS, LocalTime.of(1, 0)},
1354             {LocalTime.of(1, 2, 3, 123_456_789), DAYS, LocalTime.MIDNIGHT},
1355 
1356             {LocalTime.of(1, 1, 1, 123_456_789), NINETY_MINS, LocalTime.of(0, 0)},
1357             {LocalTime.of(2, 1, 1, 123_456_789), NINETY_MINS, LocalTime.of(1, 30)},
1358             {LocalTime.of(3, 1, 1, 123_456_789), NINETY_MINS, LocalTime.of(3, 0)},
1359         };
1360     }
1361 
1362     @Test(dataProvider="truncatedToValid")
1363     public void test_truncatedTo_valid(LocalTime input, TemporalUnit unit, LocalTime expected) {
1364         assertEquals(input.truncatedTo(unit), expected);
1365     }
1366 
1367     @DataProvider(name="truncatedToInvalid")
1368     Object[][] data_truncatedToInvalid() {
1369         return new Object[][] {
1370             {LocalTime.of(1, 2, 3, 123_456_789), NINETY_FIVE_MINS},
1371             {LocalTime.of(1, 2, 3, 123_456_789), WEEKS},
1372             {LocalTime.of(1, 2, 3, 123_456_789), MONTHS},
1373             {LocalTime.of(1, 2, 3, 123_456_789), YEARS},
1374         };
1375     }
1376 
1377     @Test(dataProvider="truncatedToInvalid", expectedExceptions=DateTimeException.class)
1378     public void test_truncatedTo_invalid(LocalTime input, TemporalUnit unit) {
1379         input.truncatedTo(unit);
1380     }
1381 
1382     @Test(expectedExceptions=NullPointerException.class)
1383     public void test_truncatedTo_null() {
1384         TEST_12_30_40_987654321.truncatedTo(null);
1385     }
1386 
1387     //-----------------------------------------------------------------------
1388     // plus(TemporalAmount)
1389     //-----------------------------------------------------------------------
1390     @Test
1391     public void test_plus_TemporalAmount_positiveHours() {
1392         TemporalAmount period = MockSimplePeriod.of(7, ChronoUnit.HOURS);
1393         LocalTime t = TEST_12_30_40_987654321.plus(period);
1394         assertEquals(t, LocalTime.of(19, 30, 40, 987654321));
1395     }
1396 
1397     @Test
1398     public void test_plus_TemporalAmount_negativeMinutes() {
1399         TemporalAmount period = MockSimplePeriod.of(-25, ChronoUnit.MINUTES);
1400         LocalTime t = TEST_12_30_40_987654321.plus(period);
1401         assertEquals(t, LocalTime.of(12, 5, 40, 987654321));
1402     }
1403 
1404     @Test
1405     public void test_plus_TemporalAmount_zero() {
1406         TemporalAmount period = Period.ZERO;
1407         LocalTime t = TEST_12_30_40_987654321.plus(period);
1408         assertEquals(t, TEST_12_30_40_987654321);
1409     }
1410 
1411     @Test
1412     public void test_plus_TemporalAmount_wrap() {
1413         TemporalAmount p = MockSimplePeriod.of(1, HOURS);
1414         LocalTime t = LocalTime.of(23, 30).plus(p);
1415         assertEquals(t, LocalTime.of(0, 30));
1416     }
1417 
1418     @Test(expectedExceptions=DateTimeException.class)
1419     public void test_plus_TemporalAmount_dateNotAllowed() {
1420         TemporalAmount period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
1421         TEST_12_30_40_987654321.plus(period);
1422     }
1423 
1424     @Test(expectedExceptions=NullPointerException.class)
1425     public void test_plus_TemporalAmount_null() {
1426         TEST_12_30_40_987654321.plus((TemporalAmount) null);
1427     }
1428 
1429     //-----------------------------------------------------------------------
1430     // plus(long,TemporalUnit)
1431     //-----------------------------------------------------------------------
1432     @Test
1433     public void test_plus_longTemporalUnit_positiveHours() {
1434         LocalTime t = TEST_12_30_40_987654321.plus(7, ChronoUnit.HOURS);
1435         assertEquals(t, LocalTime.of(19, 30, 40, 987654321));
1436     }
1437 
1438     @Test
1439     public void test_plus_longTemporalUnit_negativeMinutes() {
1440         LocalTime t = TEST_12_30_40_987654321.plus(-25, ChronoUnit.MINUTES);
1441         assertEquals(t, LocalTime.of(12, 5, 40, 987654321));
1442     }
1443 
1444     @Test
1445     public void test_plus_longTemporalUnit_zero() {
1446         LocalTime t = TEST_12_30_40_987654321.plus(0, ChronoUnit.MINUTES);
1447         assertEquals(t, TEST_12_30_40_987654321);
1448     }
1449 
1450     @Test
1451     public void test_plus_longTemporalUnit_invalidUnit() {
1452         for (TemporalUnit unit : INVALID_UNITS) {
1453             try {
1454                 TEST_12_30_40_987654321.plus(1, unit);
1455                 fail("Unit should not be allowed " + unit);
1456             } catch (DateTimeException ex) {
1457                 // expected
1458             }
1459         }
1460     }
1461 
1462     @Test(expectedExceptions=NullPointerException.class)
1463     public void test_plus_longTemporalUnit_null() {
1464         TEST_12_30_40_987654321.plus(1, (TemporalUnit) null);
1465     }
1466 
1467     //-----------------------------------------------------------------------
1468     // plusHours()
1469     //-----------------------------------------------------------------------
1470     @Test
1471     public void test_plusHours_one() {
1472         LocalTime t = LocalTime.MIDNIGHT;
1473         for (int i = 0; i < 50; i++) {
1474             t = t.plusHours(1);
1475             assertEquals(t.getHour(), (i + 1) % 24);
1476         }
1477     }
1478 
1479     @Test
1480     public void test_plusHours_fromZero() {
1481         LocalTime base = LocalTime.MIDNIGHT;
1482         for (int i = -50; i < 50; i++) {
1483             LocalTime t = base.plusHours(i);
1484             assertEquals(t.getHour(), (i + 72) % 24);
1485         }
1486     }
1487 
1488     @Test
1489     public void test_plusHours_fromOne() {
1490         LocalTime base = LocalTime.of(1, 0);
1491         for (int i = -50; i < 50; i++) {
1492             LocalTime t = base.plusHours(i);
1493             assertEquals(t.getHour(), (1 + i + 72) % 24);
1494         }
1495     }
1496 
1497     @Test
1498     public void test_plusHours_noChange_equal() {
1499         LocalTime t = TEST_12_30_40_987654321.plusHours(0);
1500         assertEquals(t, TEST_12_30_40_987654321);
1501     }
1502 
1503     @Test
1504     public void test_plusHours_toMidnight_equal() {
1505         LocalTime t = LocalTime.of(23, 0).plusHours(1);
1506         assertEquals(t, LocalTime.MIDNIGHT);
1507     }
1508 
1509     @Test
1510     public void test_plusHours_toMidday_equal() {
1511         LocalTime t = LocalTime.of(11, 0).plusHours(1);
1512         assertEquals(t, LocalTime.NOON);
1513     }
1514 
1515     @Test
1516     public void test_plusHours_big() {
1517         LocalTime t = LocalTime.of(2, 30).plusHours(Long.MAX_VALUE);
1518         int hours = (int) (Long.MAX_VALUE % 24L);
1519         assertEquals(t, LocalTime.of(2, 30).plusHours(hours));
1520     }
1521 
1522     //-----------------------------------------------------------------------
1523     // plusMinutes()
1524     //-----------------------------------------------------------------------
1525     @Test
1526     public void test_plusMinutes_one() {
1527         LocalTime t = LocalTime.MIDNIGHT;
1528         int hour = 0;
1529         int min = 0;
1530         for (int i = 0; i < 70; i++) {
1531             t = t.plusMinutes(1);
1532             min++;
1533             if (min == 60) {
1534                 hour++;
1535                 min = 0;
1536             }
1537             assertEquals(t.getHour(), hour);
1538             assertEquals(t.getMinute(), min);
1539         }
1540     }
1541 
1542     @Test
1543     public void test_plusMinutes_fromZero() {
1544         LocalTime base = LocalTime.MIDNIGHT;
1545         int hour;
1546         int min;
1547         for (int i = -70; i < 70; i++) {
1548             LocalTime t = base.plusMinutes(i);
1549             if (i < -60) {
1550                 hour = 22;
1551                 min = i + 120;
1552             } else if (i < 0) {
1553                 hour = 23;
1554                 min = i + 60;
1555             } else if (i >= 60) {
1556                 hour = 1;
1557                 min = i - 60;
1558             } else {
1559                 hour = 0;
1560                 min = i;
1561             }
1562             assertEquals(t.getHour(), hour);
1563             assertEquals(t.getMinute(), min);
1564         }
1565     }
1566 
1567     @Test
1568     public void test_plusMinutes_noChange_equal() {
1569         LocalTime t = TEST_12_30_40_987654321.plusMinutes(0);
1570         assertEquals(t, TEST_12_30_40_987654321);
1571     }
1572 
1573     @Test
1574     public void test_plusMinutes_noChange_oneDay_equal() {
1575         LocalTime t = TEST_12_30_40_987654321.plusMinutes(24 * 60);
1576         assertEquals(t, TEST_12_30_40_987654321);
1577     }
1578 
1579     @Test
1580     public void test_plusMinutes_toMidnight_equal() {
1581         LocalTime t = LocalTime.of(23, 59).plusMinutes(1);
1582         assertEquals(t, LocalTime.MIDNIGHT);
1583     }
1584 
1585     @Test
1586     public void test_plusMinutes_toMidday_equal() {
1587         LocalTime t = LocalTime.of(11, 59).plusMinutes(1);
1588         assertEquals(t, LocalTime.NOON);
1589     }
1590 
1591     @Test
1592     public void test_plusMinutes_big() {
1593         LocalTime t = LocalTime.of(2, 30).plusMinutes(Long.MAX_VALUE);
1594         int mins = (int) (Long.MAX_VALUE % (24L * 60L));
1595         assertEquals(t, LocalTime.of(2, 30).plusMinutes(mins));
1596     }
1597 
1598     //-----------------------------------------------------------------------
1599     // plusSeconds()
1600     //-----------------------------------------------------------------------
1601     @Test
1602     public void test_plusSeconds_one() {
1603         LocalTime t = LocalTime.MIDNIGHT;
1604         int hour = 0;
1605         int min = 0;
1606         int sec = 0;
1607         for (int i = 0; i < 3700; i++) {
1608             t = t.plusSeconds(1);
1609             sec++;
1610             if (sec == 60) {
1611                 min++;
1612                 sec = 0;
1613             }
1614             if (min == 60) {
1615                 hour++;
1616                 min = 0;
1617             }
1618             assertEquals(t.getHour(), hour);
1619             assertEquals(t.getMinute(), min);
1620             assertEquals(t.getSecond(), sec);
1621         }
1622     }
1623 
1624     @DataProvider(name="plusSeconds_fromZero")
1625     Iterator<Object[]> plusSeconds_fromZero() {
1626         return new Iterator<Object[]>() {
1627             int delta = 30;
1628             int i = -3660;
1629             int hour = 22;
1630             int min = 59;
1631             int sec = 0;
1632 
1633             public boolean hasNext() {
1634                 return i <= 3660;
1635             }
1636 
1637             public Object[] next() {
1638                 final Object[] ret = new Object[] {i, hour, min, sec};
1639                 i += delta;
1640                 sec += delta;
1641 
1642                 if (sec >= 60) {
1643                     min++;
1644                     sec -= 60;
1645 
1646                     if (min == 60) {
1647                         hour++;
1648                         min = 0;
1649 
1650                         if (hour == 24) {
1651                             hour = 0;
1652                         }
1653                     }
1654                 }
1655 
1656                 return ret;
1657             }
1658 
1659             public void remove() {
1660                 throw new UnsupportedOperationException();
1661             }
1662         };
1663     }
1664 
1665     @Test(dataProvider="plusSeconds_fromZero")
1666     public void test_plusSeconds_fromZero(int seconds, int hour, int min, int sec) {
1667         LocalTime base = LocalTime.MIDNIGHT;
1668         LocalTime t = base.plusSeconds(seconds);
1669 
1670         assertEquals(hour, t.getHour());
1671         assertEquals(min, t.getMinute());
1672         assertEquals(sec, t.getSecond());
1673     }
1674 
1675     @Test
1676     public void test_plusSeconds_noChange_equal() {
1677         LocalTime t = TEST_12_30_40_987654321.plusSeconds(0);
1678         assertEquals(t, TEST_12_30_40_987654321);
1679     }
1680 
1681     @Test
1682     public void test_plusSeconds_noChange_oneDay_equal() {
1683         LocalTime t = TEST_12_30_40_987654321.plusSeconds(24 * 60 * 60);
1684         assertEquals(t, TEST_12_30_40_987654321);
1685     }
1686 
1687     @Test
1688     public void test_plusSeconds_toMidnight_equal() {
1689         LocalTime t = LocalTime.of(23, 59, 59).plusSeconds(1);
1690         assertEquals(t, LocalTime.MIDNIGHT);
1691     }
1692 
1693     @Test
1694     public void test_plusSeconds_toMidday_equal() {
1695         LocalTime t = LocalTime.of(11, 59, 59).plusSeconds(1);
1696         assertEquals(t, LocalTime.NOON);
1697     }
1698 
1699     //-----------------------------------------------------------------------
1700     // plusNanos()
1701     //-----------------------------------------------------------------------
1702     @Test
1703     public void test_plusNanos_halfABillion() {
1704         LocalTime t = LocalTime.MIDNIGHT;
1705         int hour = 0;
1706         int min = 0;
1707         int sec = 0;
1708         int nanos = 0;
1709         for (long i = 0; i < 3700 * 1000000000L; i+= 500000000) {
1710             t = t.plusNanos(500000000);
1711             nanos += 500000000;
1712             if (nanos == 1000000000) {
1713                 sec++;
1714                 nanos = 0;
1715             }
1716             if (sec == 60) {
1717                 min++;
1718                 sec = 0;
1719             }
1720             if (min == 60) {
1721                 hour++;
1722                 min = 0;
1723             }
1724             assertEquals(t.getHour(), hour);
1725             assertEquals(t.getMinute(), min);
1726             assertEquals(t.getSecond(), sec);
1727             assertEquals(t.getNano(), nanos);
1728         }
1729     }
1730 
1731     @DataProvider(name="plusNanos_fromZero")
1732     Iterator<Object[]> plusNanos_fromZero() {
1733         return new Iterator<Object[]>() {
1734             long delta = 7500000000L;
1735             long i = -3660 * 1000000000L;
1736             int hour = 22;
1737             int min = 59;
1738             int sec = 0;
1739             long nanos = 0;
1740 
1741             public boolean hasNext() {
1742                 return i <= 3660 * 1000000000L;
1743             }
1744 
1745             public Object[] next() {
1746                 final Object[] ret = new Object[] {i, hour, min, sec, (int)nanos};
1747                 i += delta;
1748                 nanos += delta;
1749 
1750                 if (nanos >= 1000000000L) {
1751                     sec += nanos / 1000000000L;
1752                     nanos %= 1000000000L;
1753 
1754                     if (sec >= 60) {
1755                         min++;
1756                         sec %= 60;
1757 
1758                         if (min == 60) {
1759                             hour++;
1760                             min = 0;
1761 
1762                             if (hour == 24) {
1763                                 hour = 0;
1764                             }
1765                         }
1766                     }
1767                 }
1768 
1769                 return ret;
1770             }
1771 
1772             public void remove() {
1773                 throw new UnsupportedOperationException();
1774             }
1775         };
1776     }
1777 
1778     @Test(dataProvider="plusNanos_fromZero")
1779     public void test_plusNanos_fromZero(long nanoseconds, int hour, int min, int sec, int nanos) {
1780         LocalTime base = LocalTime.MIDNIGHT;
1781         LocalTime t = base.plusNanos(nanoseconds);
1782 
1783         assertEquals(hour, t.getHour());
1784         assertEquals(min, t.getMinute());
1785         assertEquals(sec, t.getSecond());
1786         assertEquals(nanos, t.getNano());
1787     }
1788 
1789     @Test
1790     public void test_plusNanos_noChange_equal() {
1791         LocalTime t = TEST_12_30_40_987654321.plusNanos(0);
1792         assertEquals(t, TEST_12_30_40_987654321);
1793     }
1794 
1795     @Test
1796     public void test_plusNanos_noChange_oneDay_equal() {
1797         LocalTime t = TEST_12_30_40_987654321.plusNanos(24 * 60 * 60 * 1000000000L);
1798         assertEquals(t, TEST_12_30_40_987654321);
1799     }
1800 
1801     @Test
1802     public void test_plusNanos_toMidnight_equal() {
1803         LocalTime t = LocalTime.of(23, 59, 59, 999999999).plusNanos(1);
1804         assertEquals(t, LocalTime.MIDNIGHT);
1805     }
1806 
1807     @Test
1808     public void test_plusNanos_toMidday_equal() {
1809         LocalTime t = LocalTime.of(11, 59, 59, 999999999).plusNanos(1);
1810         assertEquals(t, LocalTime.NOON);
1811     }
1812 
1813     //-----------------------------------------------------------------------
1814     // minus(TemporalAmount)
1815     //-----------------------------------------------------------------------
1816     @Test
1817     public void test_minus_TemporalAmount_positiveHours() {
1818         TemporalAmount period = MockSimplePeriod.of(7, ChronoUnit.HOURS);
1819         LocalTime t = TEST_12_30_40_987654321.minus(period);
1820         assertEquals(t, LocalTime.of(5, 30, 40, 987654321));
1821     }
1822 
1823     @Test
1824     public void test_minus_TemporalAmount_negativeMinutes() {
1825         TemporalAmount period = MockSimplePeriod.of(-25, ChronoUnit.MINUTES);
1826         LocalTime t = TEST_12_30_40_987654321.minus(period);
1827         assertEquals(t, LocalTime.of(12, 55, 40, 987654321));
1828     }
1829 
1830     @Test
1831     public void test_minus_TemporalAmount_zero() {
1832         TemporalAmount period = Period.ZERO;
1833         LocalTime t = TEST_12_30_40_987654321.minus(period);
1834         assertEquals(t, TEST_12_30_40_987654321);
1835     }
1836 
1837     @Test
1838     public void test_minus_TemporalAmount_wrap() {
1839         TemporalAmount p = MockSimplePeriod.of(1, HOURS);
1840         LocalTime t = LocalTime.of(0, 30).minus(p);
1841         assertEquals(t, LocalTime.of(23, 30));
1842     }
1843 
1844     @Test(expectedExceptions=DateTimeException.class)
1845     public void test_minus_TemporalAmount_dateNotAllowed() {
1846         TemporalAmount period = MockSimplePeriod.of(7, ChronoUnit.MONTHS);
1847         TEST_12_30_40_987654321.minus(period);
1848     }
1849 
1850     @Test(expectedExceptions=NullPointerException.class)
1851     public void test_minus_TemporalAmount_null() {
1852         TEST_12_30_40_987654321.minus((TemporalAmount) null);
1853     }
1854 
1855     //-----------------------------------------------------------------------
1856     // minus(long,TemporalUnit)
1857     //-----------------------------------------------------------------------
1858     @Test
1859     public void test_minus_longTemporalUnit_positiveHours() {
1860         LocalTime t = TEST_12_30_40_987654321.minus(7, ChronoUnit.HOURS);
1861         assertEquals(t, LocalTime.of(5, 30, 40, 987654321));
1862     }
1863 
1864     @Test
1865     public void test_minus_longTemporalUnit_negativeMinutes() {
1866         LocalTime t = TEST_12_30_40_987654321.minus(-25, ChronoUnit.MINUTES);
1867         assertEquals(t, LocalTime.of(12, 55, 40, 987654321));
1868     }
1869 
1870     @Test
1871     public void test_minus_longTemporalUnit_zero() {
1872         LocalTime t = TEST_12_30_40_987654321.minus(0, ChronoUnit.MINUTES);
1873         assertEquals(t, TEST_12_30_40_987654321);
1874     }
1875 
1876     @Test
1877     public void test_minus_longTemporalUnit_invalidUnit() {
1878         for (TemporalUnit unit : INVALID_UNITS) {
1879             try {
1880                 TEST_12_30_40_987654321.minus(1, unit);
1881                 fail("Unit should not be allowed " + unit);
1882             } catch (DateTimeException ex) {
1883                 // expected
1884             }
1885         }
1886     }
1887 
1888     @Test(expectedExceptions=NullPointerException.class)
1889     public void test_minus_longTemporalUnit_null() {
1890         TEST_12_30_40_987654321.minus(1, (TemporalUnit) null);
1891     }
1892 
1893     //-----------------------------------------------------------------------
1894     // minusHours()
1895     //-----------------------------------------------------------------------
1896     @Test
1897     public void test_minusHours_one() {
1898         LocalTime t = LocalTime.MIDNIGHT;
1899         for (int i = 0; i < 50; i++) {
1900             t = t.minusHours(1);
1901             assertEquals(t.getHour(), (((-i + 23) % 24) + 24) % 24, String.valueOf(i));
1902         }
1903     }
1904 
1905     @Test
1906     public void test_minusHours_fromZero() {
1907         LocalTime base = LocalTime.MIDNIGHT;
1908         for (int i = -50; i < 50; i++) {
1909             LocalTime t = base.minusHours(i);
1910             assertEquals(t.getHour(), ((-i % 24) + 24) % 24);
1911         }
1912     }
1913 
1914     @Test
1915     public void test_minusHours_fromOne() {
1916         LocalTime base = LocalTime.of(1, 0);
1917         for (int i = -50; i < 50; i++) {
1918             LocalTime t = base.minusHours(i);
1919             assertEquals(t.getHour(), (1 + (-i % 24) + 24) % 24);
1920         }
1921     }
1922 
1923     @Test
1924     public void test_minusHours_noChange_equal() {
1925         LocalTime t = TEST_12_30_40_987654321.minusHours(0);
1926         assertEquals(t, TEST_12_30_40_987654321);
1927     }
1928 
1929     @Test
1930     public void test_minusHours_toMidnight_equal() {
1931         LocalTime t = LocalTime.of(1, 0).minusHours(1);
1932         assertEquals(t, LocalTime.MIDNIGHT);
1933     }
1934 
1935     @Test
1936     public void test_minusHours_toMidday_equal() {
1937         LocalTime t = LocalTime.of(13, 0).minusHours(1);
1938         assertEquals(t, LocalTime.NOON);
1939     }
1940 
1941     @Test
1942     public void test_minusHours_big() {
1943         LocalTime t = LocalTime.of(2, 30).minusHours(Long.MAX_VALUE);
1944         int hours = (int) (Long.MAX_VALUE % 24L);
1945         assertEquals(t, LocalTime.of(2, 30).minusHours(hours));
1946     }
1947 
1948     //-----------------------------------------------------------------------
1949     // minusMinutes()
1950     //-----------------------------------------------------------------------
1951     @Test
1952     public void test_minusMinutes_one() {
1953         LocalTime t = LocalTime.MIDNIGHT;
1954         int hour = 0;
1955         int min = 0;
1956         for (int i = 0; i < 70; i++) {
1957             t = t.minusMinutes(1);
1958             min--;
1959             if (min == -1) {
1960                 hour--;
1961                 min = 59;
1962 
1963                 if (hour == -1) {
1964                     hour = 23;
1965                 }
1966             }
1967             assertEquals(t.getHour(), hour);
1968             assertEquals(t.getMinute(), min);
1969         }
1970     }
1971 
1972     @Test
1973     public void test_minusMinutes_fromZero() {
1974         LocalTime base = LocalTime.MIDNIGHT;
1975         int hour = 22;
1976         int min = 49;
1977         for (int i = 70; i > -70; i--) {
1978             LocalTime t = base.minusMinutes(i);
1979             min++;
1980 
1981             if (min == 60) {
1982                 hour++;
1983                 min = 0;
1984 
1985                 if (hour == 24) {
1986                     hour = 0;
1987                 }
1988             }
1989 
1990             assertEquals(t.getHour(), hour);
1991             assertEquals(t.getMinute(), min);
1992         }
1993     }
1994 
1995     @Test
1996     public void test_minusMinutes_noChange_equal() {
1997         LocalTime t = TEST_12_30_40_987654321.minusMinutes(0);
1998         assertEquals(t, TEST_12_30_40_987654321);
1999     }
2000 
2001     @Test
2002     public void test_minusMinutes_noChange_oneDay_equal() {
2003         LocalTime t = TEST_12_30_40_987654321.minusMinutes(24 * 60);
2004         assertEquals(t, TEST_12_30_40_987654321);
2005     }
2006 
2007     @Test
2008     public void test_minusMinutes_toMidnight_equal() {
2009         LocalTime t = LocalTime.of(0, 1).minusMinutes(1);
2010         assertEquals(t, LocalTime.MIDNIGHT);
2011     }
2012 
2013     @Test
2014     public void test_minusMinutes_toMidday_equals() {
2015         LocalTime t = LocalTime.of(12, 1).minusMinutes(1);
2016         assertEquals(t, LocalTime.NOON);
2017     }
2018 
2019     @Test
2020     public void test_minusMinutes_big() {
2021         LocalTime t = LocalTime.of(2, 30).minusMinutes(Long.MAX_VALUE);
2022         int mins = (int) (Long.MAX_VALUE % (24L * 60L));
2023         assertEquals(t, LocalTime.of(2, 30).minusMinutes(mins));
2024     }
2025 
2026     //-----------------------------------------------------------------------
2027     // minusSeconds()
2028     //-----------------------------------------------------------------------
2029     @Test
2030     public void test_minusSeconds_one() {
2031         LocalTime t = LocalTime.MIDNIGHT;
2032         int hour = 0;
2033         int min = 0;
2034         int sec = 0;
2035         for (int i = 0; i < 3700; i++) {
2036             t = t.minusSeconds(1);
2037             sec--;
2038             if (sec == -1) {
2039                 min--;
2040                 sec = 59;
2041 
2042                 if (min == -1) {
2043                     hour--;
2044                     min = 59;
2045 
2046                     if (hour == -1) {
2047                         hour = 23;
2048                     }
2049                 }
2050             }
2051             assertEquals(t.getHour(), hour);
2052             assertEquals(t.getMinute(), min);
2053             assertEquals(t.getSecond(), sec);
2054         }
2055     }
2056 
2057     @DataProvider(name="minusSeconds_fromZero")
2058     Iterator<Object[]> minusSeconds_fromZero() {
2059         return new Iterator<Object[]>() {
2060             int delta = 30;
2061             int i = 3660;
2062             int hour = 22;
2063             int min = 59;
2064             int sec = 0;
2065 
2066             public boolean hasNext() {
2067                 return i >= -3660;
2068             }
2069 
2070             public Object[] next() {
2071                 final Object[] ret = new Object[] {i, hour, min, sec};
2072                 i -= delta;
2073                 sec += delta;
2074 
2075                 if (sec >= 60) {
2076                     min++;
2077                     sec -= 60;
2078 
2079                     if (min == 60) {
2080                         hour++;
2081                         min = 0;
2082 
2083                         if (hour == 24) {
2084                             hour = 0;
2085                         }
2086                     }
2087                 }
2088 
2089                 return ret;
2090             }
2091 
2092             public void remove() {
2093                 throw new UnsupportedOperationException();
2094             }
2095         };
2096     }
2097 
2098     @Test(dataProvider="minusSeconds_fromZero")
2099     public void test_minusSeconds_fromZero(int seconds, int hour, int min, int sec) {
2100         LocalTime base = LocalTime.MIDNIGHT;
2101         LocalTime t = base.minusSeconds(seconds);
2102 
2103         assertEquals(t.getHour(), hour);
2104         assertEquals(t.getMinute(), min);
2105         assertEquals(t.getSecond(), sec);
2106     }
2107 
2108     @Test
2109     public void test_minusSeconds_noChange_equal() {
2110         LocalTime t = TEST_12_30_40_987654321.minusSeconds(0);
2111         assertEquals(t, TEST_12_30_40_987654321);
2112     }
2113 
2114     @Test
2115     public void test_minusSeconds_noChange_oneDay_equal() {
2116         LocalTime t = TEST_12_30_40_987654321.minusSeconds(24 * 60 * 60);
2117         assertEquals(t, TEST_12_30_40_987654321);
2118     }
2119 
2120     @Test
2121     public void test_minusSeconds_toMidnight_equal() {
2122         LocalTime t = LocalTime.of(0, 0, 1).minusSeconds(1);
2123         assertEquals(t, LocalTime.MIDNIGHT);
2124     }
2125 
2126     @Test
2127     public void test_minusSeconds_toMidday_equal() {
2128         LocalTime t = LocalTime.of(12, 0, 1).minusSeconds(1);
2129         assertEquals(t, LocalTime.NOON);
2130     }
2131 
2132     @Test
2133     public void test_minusSeconds_big() {
2134         LocalTime t = LocalTime.of(2, 30).minusSeconds(Long.MAX_VALUE);
2135         int secs = (int) (Long.MAX_VALUE % (24L * 60L * 60L));
2136         assertEquals(t, LocalTime.of(2, 30).minusSeconds(secs));
2137     }
2138 
2139     //-----------------------------------------------------------------------
2140     // minusNanos()
2141     //-----------------------------------------------------------------------
2142     @Test
2143     public void test_minusNanos_halfABillion() {
2144         LocalTime t = LocalTime.MIDNIGHT;
2145         int hour = 0;
2146         int min = 0;
2147         int sec = 0;
2148         int nanos = 0;
2149         for (long i = 0; i < 3700 * 1000000000L; i+= 500000000) {
2150             t = t.minusNanos(500000000);
2151             nanos -= 500000000;
2152 
2153             if (nanos < 0) {
2154                 sec--;
2155                 nanos += 1000000000;
2156 
2157                 if (sec == -1) {
2158                     min--;
2159                     sec += 60;
2160 
2161                     if (min == -1) {
2162                         hour--;
2163                         min += 60;
2164 
2165                         if (hour == -1) {
2166                             hour += 24;
2167                         }
2168                     }
2169                 }
2170             }
2171 
2172             assertEquals(t.getHour(), hour);
2173             assertEquals(t.getMinute(), min);
2174             assertEquals(t.getSecond(), sec);
2175             assertEquals(t.getNano(), nanos);
2176         }
2177     }
2178 
2179     @DataProvider(name="minusNanos_fromZero")
2180     Iterator<Object[]> minusNanos_fromZero() {
2181         return new Iterator<Object[]>() {
2182             long delta = 7500000000L;
2183             long i = 3660 * 1000000000L;
2184             int hour = 22;
2185             int min = 59;
2186             int sec = 0;
2187             long nanos = 0;
2188 
2189             public boolean hasNext() {
2190                 return i >= -3660 * 1000000000L;
2191             }
2192 
2193             public Object[] next() {
2194                 final Object[] ret = new Object[] {i, hour, min, sec, (int)nanos};
2195                 i -= delta;
2196                 nanos += delta;
2197 
2198                 if (nanos >= 1000000000L) {
2199                     sec += nanos / 1000000000L;
2200                     nanos %= 1000000000L;
2201 
2202                     if (sec >= 60) {
2203                         min++;
2204                         sec %= 60;
2205 
2206                         if (min == 60) {
2207                             hour++;
2208                             min = 0;
2209 
2210                             if (hour == 24) {
2211                                 hour = 0;
2212                             }
2213                         }
2214                     }
2215                 }
2216 
2217                 return ret;
2218             }
2219 
2220             public void remove() {
2221                 throw new UnsupportedOperationException();
2222             }
2223         };
2224     }
2225 
2226     @Test(dataProvider="minusNanos_fromZero")
2227     public void test_minusNanos_fromZero(long nanoseconds, int hour, int min, int sec, int nanos) {
2228         LocalTime base = LocalTime.MIDNIGHT;
2229         LocalTime t = base.minusNanos(nanoseconds);
2230 
2231         assertEquals(hour, t.getHour());
2232         assertEquals(min, t.getMinute());
2233         assertEquals(sec, t.getSecond());
2234         assertEquals(nanos, t.getNano());
2235     }
2236 
2237     @Test
2238     public void test_minusNanos_noChange_equal() {
2239         LocalTime t = TEST_12_30_40_987654321.minusNanos(0);
2240         assertEquals(t, TEST_12_30_40_987654321);
2241     }
2242 
2243     @Test
2244     public void test_minusNanos_noChange_oneDay_equal() {
2245         LocalTime t = TEST_12_30_40_987654321.minusNanos(24 * 60 * 60 * 1000000000L);
2246         assertEquals(t, TEST_12_30_40_987654321);
2247     }
2248 
2249     @Test
2250     public void test_minusNanos_toMidnight_equal() {
2251         LocalTime t = LocalTime.of(0, 0, 0, 1).minusNanos(1);
2252         assertEquals(t, LocalTime.MIDNIGHT);
2253     }
2254 
2255     @Test
2256     public void test_minusNanos_toMidday_equal() {
2257         LocalTime t = LocalTime.of(12, 0, 0, 1).minusNanos(1);
2258         assertEquals(t, LocalTime.NOON);
2259     }
2260 
2261     //-----------------------------------------------------------------------
2262     // until(Temporal, TemporalUnit)
2263     //-----------------------------------------------------------------------
2264     @DataProvider(name="periodUntilUnit")
2265     Object[][] data_periodUntilUnit() {
2266         return new Object[][] {
2267                 {time(0, 0, 0, 0), time(0, 0, 0, 0), NANOS, 0},
2268                 {time(0, 0, 0, 0), time(0, 0, 0, 0), MICROS, 0},
2269                 {time(0, 0, 0, 0), time(0, 0, 0, 0), MILLIS, 0},
2270                 {time(0, 0, 0, 0), time(0, 0, 0, 0), SECONDS, 0},
2271                 {time(0, 0, 0, 0), time(0, 0, 0, 0), MINUTES, 0},
2272                 {time(0, 0, 0, 0), time(0, 0, 0, 0), HOURS, 0},
2273                 {time(0, 0, 0, 0), time(0, 0, 0, 0), HALF_DAYS, 0},
2274 
2275                 {time(0, 0, 0, 0), time(2, 0, 0, 0), NANOS, 2 * 3600 * 1_000_000_000L},
2276                 {time(0, 0, 0, 0), time(2, 0, 0, 0), MICROS, 2 * 3600 * 1_000_000L},
2277                 {time(0, 0, 0, 0), time(2, 0, 0, 0), MILLIS, 2 * 3600 * 1_000L},
2278                 {time(0, 0, 0, 0), time(2, 0, 0, 0), SECONDS, 2 * 3600},
2279                 {time(0, 0, 0, 0), time(2, 0, 0, 0), MINUTES, 2 * 60},
2280                 {time(0, 0, 0, 0), time(2, 0, 0, 0), HOURS, 2},
2281                 {time(0, 0, 0, 0), time(2, 0, 0, 0), HALF_DAYS, 0},
2282 
2283                 {time(0, 0, 0, 0), time(14, 0, 0, 0), NANOS, 14 * 3600 * 1_000_000_000L},
2284                 {time(0, 0, 0, 0), time(14, 0, 0, 0), MICROS, 14 * 3600 * 1_000_000L},
2285                 {time(0, 0, 0, 0), time(14, 0, 0, 0), MILLIS, 14 * 3600 * 1_000L},
2286                 {time(0, 0, 0, 0), time(14, 0, 0, 0), SECONDS, 14 * 3600},
2287                 {time(0, 0, 0, 0), time(14, 0, 0, 0), MINUTES, 14 * 60},
2288                 {time(0, 0, 0, 0), time(14, 0, 0, 0), HOURS, 14},
2289                 {time(0, 0, 0, 0), time(14, 0, 0, 0), HALF_DAYS, 1},
2290 
2291                 {time(0, 0, 0, 0), time(2, 30, 40, 1500), NANOS, (2 * 3600 + 30 * 60 + 40) * 1_000_000_000L + 1500},
2292                 {time(0, 0, 0, 0), time(2, 30, 40, 1500), MICROS, (2 * 3600 + 30 * 60 + 40) * 1_000_000L + 1},
2293                 {time(0, 0, 0, 0), time(2, 30, 40, 1500), MILLIS, (2 * 3600 + 30 * 60 + 40) * 1_000L},
2294                 {time(0, 0, 0, 0), time(2, 30, 40, 1500), SECONDS, 2 * 3600 + 30 * 60 + 40},
2295                 {time(0, 0, 0, 0), time(2, 30, 40, 1500), MINUTES, 2 * 60 + 30},
2296                 {time(0, 0, 0, 0), time(2, 30, 40, 1500), HOURS, 2},
2297         };
2298     }
2299 
2300     @Test(dataProvider="periodUntilUnit")
2301     public void test_until_TemporalUnit(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) {
2302         long amount = time1.until(time2, unit);
2303         assertEquals(amount, expected);
2304     }
2305 
2306     @Test(dataProvider="periodUntilUnit")
2307     public void test_until_TemporalUnit_negated(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) {
2308         long amount = time2.until(time1, unit);
2309         assertEquals(amount, -expected);
2310     }
2311 
2312     @Test(dataProvider="periodUntilUnit")
2313     public void test_until_TemporalUnit_between(LocalTime time1, LocalTime time2, TemporalUnit unit, long expected) {
2314         long amount = unit.between(time1, time2);
2315         assertEquals(amount, expected);
2316     }
2317 
2318     @Test
2319     public void test_until_convertedType() {
2320         LocalTime start = LocalTime.of(11, 30);
2321         LocalDateTime end = start.plusSeconds(2).atDate(LocalDate.of(2010, 6, 30));
2322         assertEquals(start.until(end, SECONDS), 2);
2323     }
2324 
2325     @Test(expectedExceptions=DateTimeException.class)
2326     public void test_until_invalidType() {
2327         LocalTime start = LocalTime.of(11, 30);
2328         start.until(LocalDate.of(2010, 6, 30), SECONDS);
2329     }
2330 
2331     @Test(expectedExceptions = UnsupportedTemporalTypeException.class)
2332     public void test_until_TemporalUnit_unsupportedUnit() {
2333         TEST_12_30_40_987654321.until(TEST_12_30_40_987654321, DAYS);
2334     }
2335 
2336     @Test(expectedExceptions = NullPointerException.class)
2337     public void test_until_TemporalUnit_nullEnd() {
2338         TEST_12_30_40_987654321.until(null, HOURS);
2339     }
2340 
2341     @Test(expectedExceptions = NullPointerException.class)
2342     public void test_until_TemporalUnit_nullUnit() {
2343         TEST_12_30_40_987654321.until(TEST_12_30_40_987654321, null);
2344     }
2345 
2346     //-----------------------------------------------------------------------
2347     // format(DateTimeFormatter)
2348     //-----------------------------------------------------------------------
2349     @Test
2350     public void test_format_formatter() {
2351         DateTimeFormatter f = DateTimeFormatter.ofPattern("H m s");
2352         String t = LocalTime.of(11, 30, 45).format(f);
2353         assertEquals(t, "11 30 45");
2354     }
2355 
2356     @Test(expectedExceptions=NullPointerException.class)
2357     public void test_format_formatter_null() {
2358         LocalTime.of(11, 30, 45).format(null);
2359     }
2360 
2361     //-----------------------------------------------------------------------
2362     // atDate()
2363     //-----------------------------------------------------------------------
2364     @Test
2365     public void test_atDate() {
2366         LocalTime t = LocalTime.of(11, 30);
2367         assertEquals(t.atDate(LocalDate.of(2012, 6, 30)), LocalDateTime.of(2012, 6, 30, 11, 30));
2368     }
2369 
2370     @Test(expectedExceptions=NullPointerException.class)
2371     public void test_atDate_nullDate() {
2372         TEST_12_30_40_987654321.atDate((LocalDate) null);
2373     }
2374 
2375     //-----------------------------------------------------------------------
2376     // atOffset()
2377     //-----------------------------------------------------------------------
2378     @Test
2379     public void test_atOffset() {
2380         LocalTime t = LocalTime.of(11, 30);
2381         assertEquals(t.atOffset(OFFSET_PTWO), OffsetTime.of(LocalTime.of(11, 30), OFFSET_PTWO));
2382     }
2383 
2384     @Test(expectedExceptions=NullPointerException.class)
2385     public void test_atOffset_nullZoneOffset() {
2386         LocalTime t = LocalTime.of(11, 30);
2387         t.atOffset((ZoneOffset) null);
2388     }
2389 
2390     //-----------------------------------------------------------------------
2391     // toSecondOfDay()
2392     //-----------------------------------------------------------------------
2393     @Test
2394     public void test_toSecondOfDay() {
2395         LocalTime t = LocalTime.of(0, 0);
2396         for (int i = 0; i < 24 * 60 * 60; i++) {
2397             assertEquals(t.toSecondOfDay(), i);
2398             t = t.plusSeconds(1);
2399         }
2400     }
2401 
2402     @Test
2403     public void test_toSecondOfDay_fromNanoOfDay_symmetry() {
2404         LocalTime t = LocalTime.of(0, 0);
2405         for (int i = 0; i < 24 * 60 * 60; i++) {
2406             assertEquals(LocalTime.ofSecondOfDay(t.toSecondOfDay()), t);
2407             t = t.plusSeconds(1);
2408         }
2409     }
2410 
2411     //-----------------------------------------------------------------------
2412     // toNanoOfDay()
2413     //-----------------------------------------------------------------------
2414     @Test
2415     public void test_toNanoOfDay() {
2416         LocalTime t = LocalTime.of(0, 0);
2417         for (int i = 0; i < 1000000; i++) {
2418             assertEquals(t.toNanoOfDay(), i);
2419             t = t.plusNanos(1);
2420         }
2421         t = LocalTime.of(0, 0);
2422         for (int i = 1; i <= 1000000; i++) {
2423             t = t.minusNanos(1);
2424             assertEquals(t.toNanoOfDay(), 24 * 60 * 60 * 1000000000L - i);
2425         }
2426     }
2427 
2428     @Test
2429     public void test_toNanoOfDay_fromNanoOfDay_symmetry() {
2430         LocalTime t = LocalTime.of(0, 0);
2431         for (int i = 0; i < 1000000; i++) {
2432             assertEquals(LocalTime.ofNanoOfDay(t.toNanoOfDay()), t);
2433             t = t.plusNanos(1);
2434         }
2435         t = LocalTime.of(0, 0);
2436         for (int i = 1; i <= 1000000; i++) {
2437             t = t.minusNanos(1);
2438             assertEquals(LocalTime.ofNanoOfDay(t.toNanoOfDay()), t);
2439         }
2440     }
2441 
2442     //-----------------------------------------------------------------------
2443     // compareTo()
2444     //-----------------------------------------------------------------------
2445     @Test
2446     public void test_comparisons() {
2447         doTest_comparisons_LocalTime(
2448             LocalTime.MIDNIGHT,
2449             LocalTime.of(0, 0, 0, 999999999),
2450             LocalTime.of(0, 0, 59, 0),
2451             LocalTime.of(0, 0, 59, 999999999),
2452             LocalTime.of(0, 59, 0, 0),
2453             LocalTime.of(0, 59, 0, 999999999),
2454             LocalTime.of(0, 59, 59, 0),
2455             LocalTime.of(0, 59, 59, 999999999),
2456             LocalTime.NOON,
2457             LocalTime.of(12, 0, 0, 999999999),
2458             LocalTime.of(12, 0, 59, 0),
2459             LocalTime.of(12, 0, 59, 999999999),
2460             LocalTime.of(12, 59, 0, 0),
2461             LocalTime.of(12, 59, 0, 999999999),
2462             LocalTime.of(12, 59, 59, 0),
2463             LocalTime.of(12, 59, 59, 999999999),
2464             LocalTime.of(23, 0, 0, 0),
2465             LocalTime.of(23, 0, 0, 999999999),
2466             LocalTime.of(23, 0, 59, 0),
2467             LocalTime.of(23, 0, 59, 999999999),
2468             LocalTime.of(23, 59, 0, 0),
2469             LocalTime.of(23, 59, 0, 999999999),
2470             LocalTime.of(23, 59, 59, 0),
2471             LocalTime.of(23, 59, 59, 999999999)
2472         );
2473     }
2474 
2475     void doTest_comparisons_LocalTime(LocalTime... localTimes) {
2476         for (int i = 0; i < localTimes.length; i++) {
2477             LocalTime a = localTimes[i];
2478             for (int j = 0; j < localTimes.length; j++) {
2479                 LocalTime b = localTimes[j];
2480                 if (i < j) {
2481                     assertTrue(a.compareTo(b) < 0, a + " <=> " + b);
2482                     assertEquals(a.isBefore(b), true, a + " <=> " + b);
2483                     assertEquals(a.isAfter(b), false, a + " <=> " + b);
2484                     assertEquals(a.equals(b), false, a + " <=> " + b);
2485                 } else if (i > j) {
2486                     assertTrue(a.compareTo(b) > 0, a + " <=> " + b);
2487                     assertEquals(a.isBefore(b), false, a + " <=> " + b);
2488                     assertEquals(a.isAfter(b), true, a + " <=> " + b);
2489                     assertEquals(a.equals(b), false, a + " <=> " + b);
2490                 } else {
2491                     assertEquals(a.compareTo(b), 0, a + " <=> " + b);
2492                     assertEquals(a.isBefore(b), false, a + " <=> " + b);
2493                     assertEquals(a.isAfter(b), false, a + " <=> " + b);
2494                     assertEquals(a.equals(b), true, a + " <=> " + b);
2495                 }
2496             }
2497         }
2498     }
2499 
2500     @Test(expectedExceptions=NullPointerException.class)
2501     public void test_compareTo_ObjectNull() {
2502         TEST_12_30_40_987654321.compareTo(null);
2503     }
2504 
2505     @Test(expectedExceptions=NullPointerException.class)
2506     public void test_isBefore_ObjectNull() {
2507         TEST_12_30_40_987654321.isBefore(null);
2508     }
2509 
2510     @Test(expectedExceptions=NullPointerException.class)
2511     public void test_isAfter_ObjectNull() {
2512         TEST_12_30_40_987654321.isAfter(null);
2513     }
2514 
2515     @Test(expectedExceptions=ClassCastException.class)
2516     @SuppressWarnings({"unchecked", "rawtypes"})
2517     public void compareToNonLocalTime() {
2518        Comparable c = TEST_12_30_40_987654321;
2519        c.compareTo(new Object());
2520     }
2521 
2522     //-----------------------------------------------------------------------
2523     // equals()
2524     //-----------------------------------------------------------------------
2525     @Test(dataProvider="sampleTimes")
2526     public void test_equals_true(int h, int m, int s, int n) {
2527         LocalTime a = LocalTime.of(h, m, s, n);
2528         LocalTime b = LocalTime.of(h, m, s, n);
2529         assertEquals(a.equals(b), true);
2530     }
2531     @Test(dataProvider="sampleTimes")
2532     public void test_equals_false_hour_differs(int h, int m, int s, int n) {
2533         LocalTime a = LocalTime.of(h, m, s, n);
2534         LocalTime b = LocalTime.of(h + 1, m, s, n);
2535         assertEquals(a.equals(b), false);
2536     }
2537     @Test(dataProvider="sampleTimes")
2538     public void test_equals_false_minute_differs(int h, int m, int s, int n) {
2539         LocalTime a = LocalTime.of(h, m, s, n);
2540         LocalTime b = LocalTime.of(h, m + 1, s, n);
2541         assertEquals(a.equals(b), false);
2542     }
2543     @Test(dataProvider="sampleTimes")
2544     public void test_equals_false_second_differs(int h, int m, int s, int n) {
2545         LocalTime a = LocalTime.of(h, m, s, n);
2546         LocalTime b = LocalTime.of(h, m, s + 1, n);
2547         assertEquals(a.equals(b), false);
2548     }
2549     @Test(dataProvider="sampleTimes")
2550     public void test_equals_false_nano_differs(int h, int m, int s, int n) {
2551         LocalTime a = LocalTime.of(h, m, s, n);
2552         LocalTime b = LocalTime.of(h, m, s, n + 1);
2553         assertEquals(a.equals(b), false);
2554     }
2555 
2556     @Test
2557     public void test_equals_itself_true() {
2558         assertEquals(TEST_12_30_40_987654321.equals(TEST_12_30_40_987654321), true);
2559     }
2560 
2561     @Test
2562     public void test_equals_string_false() {
2563         assertEquals(TEST_12_30_40_987654321.equals("2007-07-15"), false);
2564     }
2565 
2566     @Test
2567     public void test_equals_null_false() {
2568         assertEquals(TEST_12_30_40_987654321.equals(null), false);
2569     }
2570 
2571     //-----------------------------------------------------------------------
2572     // hashCode()
2573     //-----------------------------------------------------------------------
2574     @Test(dataProvider="sampleTimes")
2575     public void test_hashCode_same(int h, int m, int s, int n) {
2576         LocalTime a = LocalTime.of(h, m, s, n);
2577         LocalTime b = LocalTime.of(h, m, s, n);
2578         assertEquals(a.hashCode(), b.hashCode());
2579     }
2580 
2581     @Test(dataProvider="sampleTimes")
2582     public void test_hashCode_hour_differs(int h, int m, int s, int n) {
2583         LocalTime a = LocalTime.of(h, m, s, n);
2584         LocalTime b = LocalTime.of(h + 1, m, s, n);
2585         assertEquals(a.hashCode() == b.hashCode(), false);
2586     }
2587 
2588     @Test(dataProvider="sampleTimes")
2589     public void test_hashCode_minute_differs(int h, int m, int s, int n) {
2590         LocalTime a = LocalTime.of(h, m, s, n);
2591         LocalTime b = LocalTime.of(h, m + 1, s, n);
2592         assertEquals(a.hashCode() == b.hashCode(), false);
2593     }
2594 
2595     @Test(dataProvider="sampleTimes")
2596     public void test_hashCode_second_differs(int h, int m, int s, int n) {
2597         LocalTime a = LocalTime.of(h, m, s, n);
2598         LocalTime b = LocalTime.of(h, m, s + 1, n);
2599         assertEquals(a.hashCode() == b.hashCode(), false);
2600     }
2601 
2602     @Test(dataProvider="sampleTimes")
2603     public void test_hashCode_nano_differs(int h, int m, int s, int n) {
2604         LocalTime a = LocalTime.of(h, m, s, n);
2605         LocalTime b = LocalTime.of(h, m, s, n + 1);
2606         assertEquals(a.hashCode() == b.hashCode(), false);
2607     }
2608 
2609     //-----------------------------------------------------------------------
2610     // toString()
2611     //-----------------------------------------------------------------------
2612     @DataProvider(name="sampleToString")
2613     Object[][] provider_sampleToString() {
2614         return new Object[][] {
2615             {0, 0, 0, 0, "00:00"},
2616             {1, 0, 0, 0, "01:00"},
2617             {23, 0, 0, 0, "23:00"},
2618             {0, 1, 0, 0, "00:01"},
2619             {12, 30, 0, 0, "12:30"},
2620             {23, 59, 0, 0, "23:59"},
2621             {0, 0, 1, 0, "00:00:01"},
2622             {0, 0, 59, 0, "00:00:59"},
2623             {0, 0, 0, 100000000, "00:00:00.100"},
2624             {0, 0, 0, 10000000, "00:00:00.010"},
2625             {0, 0, 0, 1000000, "00:00:00.001"},
2626             {0, 0, 0, 100000, "00:00:00.000100"},
2627             {0, 0, 0, 10000, "00:00:00.000010"},
2628             {0, 0, 0, 1000, "00:00:00.000001"},
2629             {0, 0, 0, 100, "00:00:00.000000100"},
2630             {0, 0, 0, 10, "00:00:00.000000010"},
2631             {0, 0, 0, 1, "00:00:00.000000001"},
2632             {0, 0, 0, 999999999, "00:00:00.999999999"},
2633             {0, 0, 0, 99999999, "00:00:00.099999999"},
2634             {0, 0, 0, 9999999, "00:00:00.009999999"},
2635             {0, 0, 0, 999999, "00:00:00.000999999"},
2636             {0, 0, 0, 99999, "00:00:00.000099999"},
2637             {0, 0, 0, 9999, "00:00:00.000009999"},
2638             {0, 0, 0, 999, "00:00:00.000000999"},
2639             {0, 0, 0, 99, "00:00:00.000000099"},
2640             {0, 0, 0, 9, "00:00:00.000000009"},
2641         };
2642     }
2643 
2644     @Test(dataProvider="sampleToString")
2645     public void test_toString(int h, int m, int s, int n, String expected) {
2646         LocalTime t = LocalTime.of(h, m, s, n);
2647         String str = t.toString();
2648         assertEquals(str, expected);
2649     }
2650 
2651     private LocalTime time(int hour, int min, int sec, int nano) {
2652         return LocalTime.of(hour, min, sec, nano);
2653     }
2654 }