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