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