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