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