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