1 /*
   2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * This file is available under and governed by the GNU General Public
  26  * License version 2 only, as published by the Free Software Foundation.
  27  * However, the following notice accompanied the original version of this
  28  * file:
  29  *
  30  * Copyright (c) 2008-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.OFFSET_SECONDS;
  76 import static java.time.temporal.ChronoField.SECOND_OF_DAY;
  77 import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
  78 import static java.time.temporal.ChronoUnit.MONTHS;
  79 import static java.time.temporal.ChronoUnit.DAYS;
  80 import static java.time.temporal.ChronoUnit.HOURS;
  81 import static java.time.temporal.ChronoUnit.MINUTES;
  82 import static java.time.temporal.ChronoUnit.MICROS;
  83 import static java.time.temporal.ChronoUnit.MILLIS;
  84 import static java.time.temporal.ChronoUnit.HALF_DAYS;
  85 import static java.time.temporal.ChronoUnit.NANOS;
  86 import static java.time.temporal.ChronoUnit.SECONDS;
  87 import static org.testng.Assert.assertEquals;
  88 import static org.testng.Assert.assertNotNull;
  89 import static org.testng.Assert.assertTrue;
  90 import static org.testng.Assert.fail;
  91 
  92 import java.io.ByteArrayOutputStream;
  93 import java.io.DataOutputStream;
  94 import java.lang.reflect.Constructor;
  95 import java.lang.reflect.InvocationTargetException;
  96 import java.time.Clock;
  97 import java.time.DateTimeException;
  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.ZoneId;
 106 import java.time.ZoneOffset;
 107 import java.time.ZonedDateTime;
 108 import java.time.format.DateTimeFormatter;
 109 import java.time.format.DateTimeParseException;
 110 import java.time.temporal.ChronoField;
 111 import java.time.temporal.ChronoUnit;
 112 import java.time.temporal.JulianFields;
 113 import java.time.temporal.Temporal;
 114 import java.time.temporal.TemporalAccessor;
 115 import java.time.temporal.TemporalAdjuster;
 116 import java.time.temporal.TemporalAmount;
 117 import java.time.temporal.TemporalField;
 118 import java.time.temporal.TemporalQuery;
 119 import java.time.temporal.TemporalUnit;
 120 import java.util.ArrayList;
 121 import java.util.Arrays;
 122 import java.util.List;
 123 
 124 import org.testng.annotations.BeforeMethod;
 125 import org.testng.annotations.DataProvider;
 126 import org.testng.annotations.Test;
 127 import test.java.time.MockSimplePeriod;
 128 
 129 /**
 130  * Test OffsetTime.
 131  */
 132 @Test
 133 public class TCKOffsetTime extends AbstractDateTimeTest {
 134 
 135     private static final ZoneId ZONE_GAZA = ZoneId.of("Asia/Gaza");
 136     private static final ZoneOffset OFFSET_PONE = ZoneOffset.ofHours(1);
 137     private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2);
 138     private static final LocalDate DATE = LocalDate.of(2008, 12, 3);
 139     private OffsetTime TEST_11_30_59_500_PONE;
 140 
 141     @BeforeMethod
 142     public void setUp() {
 143         TEST_11_30_59_500_PONE = OffsetTime.of(11, 30, 59, 500, OFFSET_PONE);
 144     }
 145 
 146     //-----------------------------------------------------------------------
 147     @Override
 148     protected List<TemporalAccessor> samples() {
 149         TemporalAccessor[] array = {TEST_11_30_59_500_PONE, OffsetTime.MIN, OffsetTime.MAX};
 150         return Arrays.asList(array);
 151     }
 152 
 153     @Override
 154     protected List<TemporalField> validFields() {
 155         TemporalField[] array = {
 156             NANO_OF_SECOND,
 157             NANO_OF_DAY,
 158             MICRO_OF_SECOND,
 159             MICRO_OF_DAY,
 160             MILLI_OF_SECOND,
 161             MILLI_OF_DAY,
 162             SECOND_OF_MINUTE,
 163             SECOND_OF_DAY,
 164             MINUTE_OF_HOUR,
 165             MINUTE_OF_DAY,
 166             CLOCK_HOUR_OF_AMPM,
 167             HOUR_OF_AMPM,
 168             CLOCK_HOUR_OF_DAY,
 169             HOUR_OF_DAY,
 170             AMPM_OF_DAY,
 171             OFFSET_SECONDS,
 172         };
 173         return Arrays.asList(array);
 174     }
 175 
 176     @Override
 177     protected List<TemporalField> invalidFields() {
 178         List<TemporalField> list = new ArrayList<>(Arrays.<TemporalField>asList(ChronoField.values()));
 179         list.removeAll(validFields());
 180         list.add(JulianFields.JULIAN_DAY);
 181         list.add(JulianFields.MODIFIED_JULIAN_DAY);
 182         list.add(JulianFields.RATA_DIE);
 183         return list;
 184     }
 185 
 186     //-----------------------------------------------------------------------
 187     @Test
 188     public void test_serialization() throws Exception {
 189         assertSerializable(TEST_11_30_59_500_PONE);
 190         assertSerializable(OffsetTime.MIN);
 191         assertSerializable(OffsetTime.MAX);
 192     }
 193 
 194     @Test
 195     public void test_serialization_format() throws Exception {
 196         ByteArrayOutputStream baos = new ByteArrayOutputStream();
 197         try (DataOutputStream dos = new DataOutputStream(baos) ) {
 198             dos.writeByte(9);       // java.time.Ser.OFFSET_TIME_TYPE
 199         }
 200         byte[] bytes = baos.toByteArray();
 201         ByteArrayOutputStream baosTime = new ByteArrayOutputStream();
 202         try (DataOutputStream dos = new DataOutputStream(baosTime) ) {
 203             dos.writeByte(4);
 204             dos.writeByte(22);
 205             dos.writeByte(17);
 206             dos.writeByte(59);
 207             dos.writeInt(464_000_000);
 208         }
 209         byte[] bytesTime = baosTime.toByteArray();
 210         ByteArrayOutputStream baosOffset = new ByteArrayOutputStream();
 211         try (DataOutputStream dos = new DataOutputStream(baosOffset) ) {
 212             dos.writeByte(8);
 213             dos.writeByte(4);  // quarter hours stored: 3600 / 900
 214         }
 215         byte[] bytesOffset = baosOffset.toByteArray();
 216         assertSerializedBySer(OffsetTime.of(22, 17, 59, 464_000_000, ZoneOffset.ofHours(1)), bytes,
 217                 bytesTime, bytesOffset);
 218     }
 219 
 220     //-----------------------------------------------------------------------
 221     // constants
 222     //-----------------------------------------------------------------------
 223     @Test
 224     public void constant_MIN() {
 225         check(OffsetTime.MIN, 0, 0, 0, 0, ZoneOffset.MAX);
 226     }
 227 
 228     @Test
 229     public void constant_MAX() {
 230         check(OffsetTime.MAX, 23, 59, 59, 999999999, ZoneOffset.MIN);
 231     }
 232 
 233     //-----------------------------------------------------------------------
 234     // now()
 235     //-----------------------------------------------------------------------
 236     @Test
 237     public void now() {
 238         ZonedDateTime nowDT = ZonedDateTime.now();
 239 
 240         OffsetTime expected = OffsetTime.now(Clock.systemDefaultZone());
 241         OffsetTime test = OffsetTime.now();
 242         long diff = Math.abs(test.toLocalTime().toNanoOfDay() - expected.toLocalTime().toNanoOfDay());
 243         assertTrue(diff < 100000000);  // less than 0.1 secs
 244         assertEquals(test.getOffset(), nowDT.getOffset());
 245     }
 246 
 247     //-----------------------------------------------------------------------
 248     // now(Clock)
 249     //-----------------------------------------------------------------------
 250     @Test
 251     public void now_Clock_allSecsInDay() {
 252         for (int i = 0; i < (2 * 24 * 60 * 60); i++) {
 253             Instant instant = Instant.ofEpochSecond(i, 8);
 254             Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
 255             OffsetTime test = OffsetTime.now(clock);
 256             assertEquals(test.getHour(), (i / (60 * 60)) % 24);
 257             assertEquals(test.getMinute(), (i / 60) % 60);
 258             assertEquals(test.getSecond(), i % 60);
 259             assertEquals(test.getNano(), 8);
 260             assertEquals(test.getOffset(), ZoneOffset.UTC);
 261         }
 262     }
 263 
 264     @Test
 265     public void now_Clock_beforeEpoch() {
 266         for (int i =-1; i >= -(24 * 60 * 60); i--) {
 267             Instant instant = Instant.ofEpochSecond(i, 8);
 268             Clock clock = Clock.fixed(instant, ZoneOffset.UTC);
 269             OffsetTime test = OffsetTime.now(clock);
 270             assertEquals(test.getHour(), ((i + 24 * 60 * 60) / (60 * 60)) % 24);
 271             assertEquals(test.getMinute(), ((i + 24 * 60 * 60) / 60) % 60);
 272             assertEquals(test.getSecond(), (i + 24 * 60 * 60) % 60);
 273             assertEquals(test.getNano(), 8);
 274             assertEquals(test.getOffset(), ZoneOffset.UTC);
 275         }
 276     }
 277 
 278     @Test
 279     public void now_Clock_offsets() {
 280         Instant base = LocalDateTime.of(1970, 1, 1, 12, 0).toInstant(ZoneOffset.UTC);
 281         for (int i = -9; i < 15; i++) {
 282             ZoneOffset offset = ZoneOffset.ofHours(i);
 283             Clock clock = Clock.fixed(base, offset);
 284             OffsetTime test = OffsetTime.now(clock);
 285             assertEquals(test.getHour(), (12 + i) % 24);
 286             assertEquals(test.getMinute(), 0);
 287             assertEquals(test.getSecond(), 0);
 288             assertEquals(test.getNano(), 0);
 289             assertEquals(test.getOffset(), offset);
 290         }
 291     }
 292 
 293     @Test(expectedExceptions=NullPointerException.class)
 294     public void now_Clock_nullZoneId() {
 295         OffsetTime.now((ZoneId) null);
 296     }
 297 
 298     @Test(expectedExceptions=NullPointerException.class)
 299     public void now_Clock_nullClock() {
 300         OffsetTime.now((Clock) null);
 301     }
 302 
 303     //-----------------------------------------------------------------------
 304     // factories
 305     //-----------------------------------------------------------------------
 306     private void check(OffsetTime test, int h, int m, int s, int n, ZoneOffset offset) {
 307         assertEquals(test.toLocalTime(), LocalTime.of(h, m, s, n));
 308         assertEquals(test.getOffset(), offset);
 309 
 310         assertEquals(test.getHour(), h);
 311         assertEquals(test.getMinute(), m);
 312         assertEquals(test.getSecond(), s);
 313         assertEquals(test.getNano(), n);
 314 
 315         assertEquals(test, test);
 316         assertEquals(test.hashCode(), test.hashCode());
 317         assertEquals(OffsetTime.of(LocalTime.of(h, m, s, n), offset), test);
 318     }
 319 
 320     //-----------------------------------------------------------------------
 321     @Test
 322     public void factory_intsHMSN() {
 323         OffsetTime test = OffsetTime.of(11, 30, 10, 500, OFFSET_PONE);
 324         check(test, 11, 30, 10, 500, OFFSET_PONE);
 325     }
 326 
 327     //-----------------------------------------------------------------------
 328     @Test
 329     public void factory_LocalTimeZoneOffset() {
 330         LocalTime localTime = LocalTime.of(11, 30, 10, 500);
 331         OffsetTime test = OffsetTime.of(localTime, OFFSET_PONE);
 332         check(test, 11, 30, 10, 500, OFFSET_PONE);
 333     }
 334 
 335     @Test(expectedExceptions=NullPointerException.class)
 336     public void factory_LocalTimeZoneOffset_nullTime() {
 337         OffsetTime.of((LocalTime) null, OFFSET_PONE);
 338     }
 339 
 340     @Test(expectedExceptions=NullPointerException.class)
 341     public void factory_LocalTimeZoneOffset_nullOffset() {
 342         LocalTime localTime = LocalTime.of(11, 30, 10, 500);
 343         OffsetTime.of(localTime, (ZoneOffset) null);
 344     }
 345 
 346     //-----------------------------------------------------------------------
 347     // ofInstant()
 348     //-----------------------------------------------------------------------
 349     @Test(expectedExceptions=NullPointerException.class)
 350     public void factory_ofInstant_nullInstant() {
 351         OffsetTime.ofInstant((Instant) null, ZoneOffset.UTC);
 352     }
 353 
 354     @Test(expectedExceptions=NullPointerException.class)
 355     public void factory_ofInstant_nullOffset() {
 356         Instant instant = Instant.ofEpochSecond(0L);
 357         OffsetTime.ofInstant(instant, (ZoneOffset) null);
 358     }
 359 
 360     @Test
 361     public void factory_ofInstant_allSecsInDay() {
 362         for (int i = 0; i < (2 * 24 * 60 * 60); i++) {
 363             Instant instant = Instant.ofEpochSecond(i, 8);
 364             OffsetTime test = OffsetTime.ofInstant(instant, ZoneOffset.UTC);
 365             assertEquals(test.getHour(), (i / (60 * 60)) % 24);
 366             assertEquals(test.getMinute(), (i / 60) % 60);
 367             assertEquals(test.getSecond(), i % 60);
 368             assertEquals(test.getNano(), 8);
 369         }
 370     }
 371 
 372     @Test
 373     public void factory_ofInstant_beforeEpoch() {
 374         for (int i =-1; i >= -(24 * 60 * 60); i--) {
 375             Instant instant = Instant.ofEpochSecond(i, 8);
 376             OffsetTime test = OffsetTime.ofInstant(instant, ZoneOffset.UTC);
 377             assertEquals(test.getHour(), ((i + 24 * 60 * 60) / (60 * 60)) % 24);
 378             assertEquals(test.getMinute(), ((i + 24 * 60 * 60) / 60) % 60);
 379             assertEquals(test.getSecond(), (i + 24 * 60 * 60) % 60);
 380             assertEquals(test.getNano(), 8);
 381         }
 382     }
 383 
 384     //-----------------------------------------------------------------------
 385     @Test
 386     public void factory_ofInstant_maxYear() {
 387         OffsetTime test = OffsetTime.ofInstant(Instant.MAX, ZoneOffset.UTC);
 388         assertEquals(test.getHour(), 23);
 389         assertEquals(test.getMinute(), 59);
 390         assertEquals(test.getSecond(), 59);
 391         assertEquals(test.getNano(), 999_999_999);
 392     }
 393 
 394     @Test
 395     public void factory_ofInstant_minYear() {
 396         OffsetTime test = OffsetTime.ofInstant(Instant.MIN, ZoneOffset.UTC);
 397         assertEquals(test.getHour(), 0);
 398         assertEquals(test.getMinute(), 0);
 399         assertEquals(test.getSecond(), 0);
 400         assertEquals(test.getNano(), 0);
 401     }
 402 
 403     //-----------------------------------------------------------------------
 404     // from(TemporalAccessor)
 405     //-----------------------------------------------------------------------
 406     @Test
 407     public void factory_from_TemporalAccessor_OT() {
 408         assertEquals(OffsetTime.from(OffsetTime.of(17, 30, 0, 0, OFFSET_PONE)), OffsetTime.of(17, 30, 0, 0, OFFSET_PONE));
 409     }
 410 
 411     @Test
 412     public void test_from_TemporalAccessor_ZDT() {
 413         ZonedDateTime base = LocalDateTime.of(2007, 7, 15, 11, 30, 59, 500).atZone(OFFSET_PONE);
 414         assertEquals(OffsetTime.from(base), TEST_11_30_59_500_PONE);
 415     }
 416 
 417     @Test(expectedExceptions=DateTimeException.class)
 418     public void factory_from_TemporalAccessor_invalid_noDerive() {
 419         OffsetTime.from(LocalDate.of(2007, 7, 15));
 420     }
 421 
 422     @Test(expectedExceptions=NullPointerException.class)
 423     public void factory_from_TemporalAccessor_null() {
 424         OffsetTime.from((TemporalAccessor) null);
 425     }
 426 
 427     //-----------------------------------------------------------------------
 428     // parse()
 429     //-----------------------------------------------------------------------
 430     @Test(dataProvider = "sampleToString")
 431     public void factory_parse_validText(int h, int m, int s, int n, String offsetId, String parsable) {
 432         OffsetTime t = OffsetTime.parse(parsable);
 433         assertNotNull(t, parsable);
 434         check(t, h, m, s, n, ZoneOffset.of(offsetId));
 435     }
 436 
 437     @DataProvider(name="sampleBadParse")
 438     Object[][] provider_sampleBadParse() {
 439         return new Object[][]{
 440                 {"00;00"},
 441                 {"12-00"},
 442                 {"-01:00"},
 443                 {"00:00:00-09"},
 444                 {"00:00:00,09"},
 445                 {"00:00:abs"},
 446                 {"11"},
 447                 {"11:30"},
 448                 {"11:30+01:00[Europe/Paris]"},
 449         };
 450     }
 451 
 452     @Test(dataProvider = "sampleBadParse", expectedExceptions={DateTimeParseException.class})
 453     public void factory_parse_invalidText(String unparsable) {
 454         OffsetTime.parse(unparsable);
 455     }
 456 
 457     //-----------------------------------------------------------------------s
 458     @Test(expectedExceptions={DateTimeParseException.class})
 459     public void factory_parse_illegalHour() {
 460         OffsetTime.parse("25:00+01:00");
 461     }
 462 
 463     @Test(expectedExceptions={DateTimeParseException.class})
 464     public void factory_parse_illegalMinute() {
 465         OffsetTime.parse("12:60+01:00");
 466     }
 467 
 468     @Test(expectedExceptions={DateTimeParseException.class})
 469     public void factory_parse_illegalSecond() {
 470         OffsetTime.parse("12:12:60+01:00");
 471     }
 472 
 473     //-----------------------------------------------------------------------
 474     // parse(DateTimeFormatter)
 475     //-----------------------------------------------------------------------
 476     @Test
 477     public void factory_parse_formatter() {
 478         DateTimeFormatter f = DateTimeFormatter.ofPattern("H m s XXX");
 479         OffsetTime test = OffsetTime.parse("11 30 0 +01:00", f);
 480         assertEquals(test, OffsetTime.of(11, 30, 0, 0, ZoneOffset.ofHours(1)));
 481     }
 482 
 483     @Test(expectedExceptions=NullPointerException.class)
 484     public void factory_parse_formatter_nullText() {
 485         DateTimeFormatter f = DateTimeFormatter.ofPattern("y M d H m s");
 486         OffsetTime.parse((String) null, f);
 487     }
 488 
 489     @Test(expectedExceptions=NullPointerException.class)
 490     public void factory_parse_formatter_nullFormatter() {
 491         OffsetTime.parse("ANY", null);
 492     }
 493 
 494     //-----------------------------------------------------------------------
 495     // constructor
 496     //-----------------------------------------------------------------------
 497     @Test(expectedExceptions=NullPointerException.class)
 498     public void constructor_nullTime() throws Throwable  {
 499         Constructor<OffsetTime> con = OffsetTime.class.getDeclaredConstructor(LocalTime.class, ZoneOffset.class);
 500         con.setAccessible(true);
 501         try {
 502             con.newInstance(null, OFFSET_PONE);
 503         } catch (InvocationTargetException ex) {
 504             throw ex.getCause();
 505         }
 506     }
 507 
 508     @Test(expectedExceptions=NullPointerException.class)
 509     public void constructor_nullOffset() throws Throwable  {
 510         Constructor<OffsetTime> con = OffsetTime.class.getDeclaredConstructor(LocalTime.class, ZoneOffset.class);
 511         con.setAccessible(true);
 512         try {
 513             con.newInstance(LocalTime.of(11, 30, 0, 0), null);
 514         } catch (InvocationTargetException ex) {
 515             throw ex.getCause();
 516         }
 517     }
 518 
 519     //-----------------------------------------------------------------------
 520     // basics
 521     //-----------------------------------------------------------------------
 522     @DataProvider(name="sampleTimes")
 523     Object[][] provider_sampleTimes() {
 524         return new Object[][] {
 525             {11, 30, 20, 500, OFFSET_PONE},
 526             {11, 0, 0, 0, OFFSET_PONE},
 527             {23, 59, 59, 999999999, OFFSET_PONE},
 528         };
 529     }
 530 
 531     @Test(dataProvider="sampleTimes")
 532     public void test_get(int h, int m, int s, int n, ZoneOffset offset) {
 533         LocalTime localTime = LocalTime.of(h, m, s, n);
 534         OffsetTime a = OffsetTime.of(localTime, offset);
 535 
 536         assertEquals(a.toLocalTime(), localTime);
 537         assertEquals(a.getOffset(), offset);
 538         assertEquals(a.toString(), localTime.toString() + offset.toString());
 539         assertEquals(a.getHour(), localTime.getHour());
 540         assertEquals(a.getMinute(), localTime.getMinute());
 541         assertEquals(a.getSecond(), localTime.getSecond());
 542         assertEquals(a.getNano(), localTime.getNano());
 543     }
 544 
 545     //-----------------------------------------------------------------------
 546     // get(TemporalField)
 547     //-----------------------------------------------------------------------
 548     @Test
 549     public void test_get_TemporalField() {
 550         OffsetTime test = OffsetTime.of(12, 30, 40, 987654321, OFFSET_PONE);
 551         assertEquals(test.get(ChronoField.HOUR_OF_DAY), 12);
 552         assertEquals(test.get(ChronoField.MINUTE_OF_HOUR), 30);
 553         assertEquals(test.get(ChronoField.SECOND_OF_MINUTE), 40);
 554         assertEquals(test.get(ChronoField.NANO_OF_SECOND), 987654321);
 555         assertEquals(test.get(ChronoField.HOUR_OF_AMPM), 0);
 556         assertEquals(test.get(ChronoField.AMPM_OF_DAY), 1);
 557 
 558         assertEquals(test.get(ChronoField.OFFSET_SECONDS), 3600);
 559     }
 560 
 561     @Test
 562     public void test_getLong_TemporalField() {
 563         OffsetTime test = OffsetTime.of(12, 30, 40, 987654321, OFFSET_PONE);
 564         assertEquals(test.getLong(ChronoField.HOUR_OF_DAY), 12);
 565         assertEquals(test.getLong(ChronoField.MINUTE_OF_HOUR), 30);
 566         assertEquals(test.getLong(ChronoField.SECOND_OF_MINUTE), 40);
 567         assertEquals(test.getLong(ChronoField.NANO_OF_SECOND), 987654321);
 568         assertEquals(test.getLong(ChronoField.HOUR_OF_AMPM), 0);
 569         assertEquals(test.getLong(ChronoField.AMPM_OF_DAY), 1);
 570 
 571         assertEquals(test.getLong(ChronoField.OFFSET_SECONDS), 3600);
 572     }
 573 
 574     //-----------------------------------------------------------------------
 575     // query(TemporalQuery)
 576     //-----------------------------------------------------------------------
 577     @DataProvider(name="query")
 578     Object[][] data_query() {
 579         return new Object[][] {
 580                 {TEST_11_30_59_500_PONE, TemporalQuery.chronology(), null},
 581                 {TEST_11_30_59_500_PONE, TemporalQuery.zoneId(), null},
 582                 {TEST_11_30_59_500_PONE, TemporalQuery.precision(), ChronoUnit.NANOS},
 583                 {TEST_11_30_59_500_PONE, TemporalQuery.zone(), OFFSET_PONE},
 584                 {TEST_11_30_59_500_PONE, TemporalQuery.offset(), OFFSET_PONE},
 585                 {TEST_11_30_59_500_PONE, TemporalQuery.localDate(), null},
 586                 {TEST_11_30_59_500_PONE, TemporalQuery.localTime(), LocalTime.of(11, 30, 59, 500)},
 587         };
 588     }
 589 
 590     @Test(dataProvider="query")
 591     public <T> void test_query(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
 592         assertEquals(temporal.query(query), expected);
 593     }
 594 
 595     @Test(dataProvider="query")
 596     public <T> void test_queryFrom(TemporalAccessor temporal, TemporalQuery<T> query, T expected) {
 597         assertEquals(query.queryFrom(temporal), expected);
 598     }
 599 
 600     @Test(expectedExceptions=NullPointerException.class)
 601     public void test_query_null() {
 602         TEST_11_30_59_500_PONE.query(null);
 603     }
 604 
 605     //-----------------------------------------------------------------------
 606     // withOffsetSameLocal()
 607     //-----------------------------------------------------------------------
 608     @Test
 609     public void test_withOffsetSameLocal() {
 610         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 611         OffsetTime test = base.withOffsetSameLocal(OFFSET_PTWO);
 612         assertEquals(test.toLocalTime(), base.toLocalTime());
 613         assertEquals(test.getOffset(), OFFSET_PTWO);
 614     }
 615 
 616     @Test
 617     public void test_withOffsetSameLocal_noChange() {
 618         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 619         OffsetTime test = base.withOffsetSameLocal(OFFSET_PONE);
 620         assertEquals(test, base);
 621     }
 622 
 623     @Test(expectedExceptions=NullPointerException.class)
 624     public void test_withOffsetSameLocal_null() {
 625         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 626         base.withOffsetSameLocal(null);
 627     }
 628 
 629     //-----------------------------------------------------------------------
 630     // withOffsetSameInstant()
 631     //-----------------------------------------------------------------------
 632     @Test
 633     public void test_withOffsetSameInstant() {
 634         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 635         OffsetTime test = base.withOffsetSameInstant(OFFSET_PTWO);
 636         OffsetTime expected = OffsetTime.of(12, 30, 59, 0, OFFSET_PTWO);
 637         assertEquals(test, expected);
 638     }
 639 
 640     @Test
 641     public void test_withOffsetSameInstant_noChange() {
 642         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 643         OffsetTime test = base.withOffsetSameInstant(OFFSET_PONE);
 644         assertEquals(test, base);
 645     }
 646 
 647     @Test(expectedExceptions=NullPointerException.class)
 648     public void test_withOffsetSameInstant_null() {
 649         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 650         base.withOffsetSameInstant(null);
 651     }
 652 
 653     //-----------------------------------------------------------------------
 654     // adjustInto(Temporal)
 655     //-----------------------------------------------------------------------
 656     @DataProvider(name="adjustInto")
 657     Object[][] data_adjustInto() {
 658         return new Object[][]{
 659                 {OffsetTime.of(LocalTime.of(23, 5), OFFSET_PONE), OffsetTime.of(LocalTime.of(1, 1, 1, 100), ZoneOffset.UTC), OffsetTime.of(LocalTime.of(23, 5), OFFSET_PONE), null},
 660                 {OffsetTime.of(LocalTime.of(23, 5), OFFSET_PONE), OffsetTime.MAX, OffsetTime.of(LocalTime.of(23, 5), OFFSET_PONE), null},
 661                 {OffsetTime.of(LocalTime.of(23, 5), OFFSET_PONE), OffsetTime.MIN, OffsetTime.of(LocalTime.of(23 , 5), OFFSET_PONE), null},
 662                 {OffsetTime.MAX, OffsetTime.of(LocalTime.of(23, 5), OFFSET_PONE), OffsetTime.of(OffsetTime.MAX.toLocalTime(), ZoneOffset.ofHours(-18)), null},
 663                 {OffsetTime.MIN, OffsetTime.of(LocalTime.of(23, 5), OFFSET_PONE), OffsetTime.of(OffsetTime.MIN.toLocalTime(), ZoneOffset.ofHours(18)), null},
 664 
 665 
 666                 {OffsetTime.of(LocalTime.of(23, 5), OFFSET_PONE), ZonedDateTime.of(LocalDateTime.of(2012, 3, 4, 1, 1, 1, 100), ZONE_GAZA), ZonedDateTime.of(LocalDateTime.of(2012, 3, 4, 23, 5), ZONE_GAZA), null},
 667                 {OffsetTime.of(LocalTime.of(23, 5), OFFSET_PONE), OffsetDateTime.of(LocalDateTime.of(2012, 3, 4, 1, 1, 1, 100), ZoneOffset.UTC), OffsetDateTime.of(LocalDateTime.of(2012, 3, 4, 23, 5), OFFSET_PONE), null},
 668 
 669                 {OffsetTime.of(LocalTime.of(23, 5), OFFSET_PONE), LocalDateTime.of(2012, 3, 4, 1, 1, 1, 100), null, DateTimeException.class},
 670                 {OffsetTime.of(LocalTime.of(23, 5), OFFSET_PONE), LocalDate.of(2210, 2, 2), null, DateTimeException.class},
 671                 {OffsetTime.of(LocalTime.of(23, 5), OFFSET_PONE), LocalTime.of(22, 3, 0), null, DateTimeException.class},
 672                 {OffsetTime.of(LocalTime.of(23, 5), OFFSET_PONE), null, null, NullPointerException.class},
 673 
 674         };
 675     }
 676 
 677     @Test(dataProvider="adjustInto")
 678     public void test_adjustInto(OffsetTime test, Temporal temporal, Temporal expected, Class<?> expectedEx) {
 679         if (expectedEx == null) {
 680             Temporal result = test.adjustInto(temporal);
 681             assertEquals(result, expected);
 682         } else {
 683             try {
 684                 Temporal result = test.adjustInto(temporal);
 685                 fail();
 686             } catch (Exception ex) {
 687                 assertTrue(expectedEx.isInstance(ex));
 688             }
 689         }
 690     }
 691 
 692     //-----------------------------------------------------------------------
 693     // with(WithAdjuster)
 694     //-----------------------------------------------------------------------
 695     @Test
 696     public void test_with_adjustment() {
 697         final OffsetTime sample = OffsetTime.of(23, 5, 0, 0, OFFSET_PONE);
 698         TemporalAdjuster adjuster = new TemporalAdjuster() {
 699             @Override
 700             public Temporal adjustInto(Temporal dateTime) {
 701                 return sample;
 702             }
 703         };
 704         assertEquals(TEST_11_30_59_500_PONE.with(adjuster), sample);
 705     }
 706 
 707     @Test
 708     public void test_with_adjustment_LocalTime() {
 709         OffsetTime test = TEST_11_30_59_500_PONE.with(LocalTime.of(13, 30));
 710         assertEquals(test, OffsetTime.of(13, 30, 0, 0, OFFSET_PONE));
 711     }
 712 
 713     @Test
 714     public void test_with_adjustment_OffsetTime() {
 715         OffsetTime test = TEST_11_30_59_500_PONE.with(OffsetTime.of(13, 35, 0, 0, OFFSET_PTWO));
 716         assertEquals(test, OffsetTime.of(13, 35, 0, 0, OFFSET_PTWO));
 717     }
 718 
 719     @Test
 720     public void test_with_adjustment_ZoneOffset() {
 721         OffsetTime test = TEST_11_30_59_500_PONE.with(OFFSET_PTWO);
 722         assertEquals(test, OffsetTime.of(11, 30, 59, 500, OFFSET_PTWO));
 723     }
 724 
 725     @Test
 726     public void test_with_adjustment_AmPm() {
 727         OffsetTime test = TEST_11_30_59_500_PONE.with(new TemporalAdjuster() {
 728             @Override
 729             public Temporal adjustInto(Temporal dateTime) {
 730                 return dateTime.with(HOUR_OF_DAY, 23);
 731             }
 732         });
 733         assertEquals(test, OffsetTime.of(23, 30, 59, 500, OFFSET_PONE));
 734     }
 735 
 736     @Test(expectedExceptions=NullPointerException.class)
 737     public void test_with_adjustment_null() {
 738         TEST_11_30_59_500_PONE.with((TemporalAdjuster) null);
 739     }
 740 
 741     //-----------------------------------------------------------------------
 742     // with(TemporalField, long)
 743     //-----------------------------------------------------------------------
 744     @Test
 745     public void test_with_TemporalField() {
 746         OffsetTime test = OffsetTime.of(12, 30, 40, 987654321, OFFSET_PONE);
 747         assertEquals(test.with(ChronoField.HOUR_OF_DAY, 15), OffsetTime.of(15, 30, 40, 987654321, OFFSET_PONE));
 748         assertEquals(test.with(ChronoField.MINUTE_OF_HOUR, 50), OffsetTime.of(12, 50, 40, 987654321, OFFSET_PONE));
 749         assertEquals(test.with(ChronoField.SECOND_OF_MINUTE, 50), OffsetTime.of(12, 30, 50, 987654321, OFFSET_PONE));
 750         assertEquals(test.with(ChronoField.NANO_OF_SECOND, 12345), OffsetTime.of(12, 30, 40, 12345, OFFSET_PONE));
 751         assertEquals(test.with(ChronoField.HOUR_OF_AMPM, 6), OffsetTime.of(18, 30, 40, 987654321, OFFSET_PONE));
 752         assertEquals(test.with(ChronoField.AMPM_OF_DAY, 0), OffsetTime.of(0, 30, 40, 987654321, OFFSET_PONE));
 753 
 754         assertEquals(test.with(ChronoField.OFFSET_SECONDS, 7205), OffsetTime.of(12, 30, 40, 987654321, ZoneOffset.ofHoursMinutesSeconds(2, 0, 5)));
 755     }
 756 
 757     @Test(expectedExceptions=NullPointerException.class )
 758     public void test_with_TemporalField_null() {
 759         TEST_11_30_59_500_PONE.with((TemporalField) null, 0);
 760     }
 761 
 762     @Test(expectedExceptions=DateTimeException.class )
 763     public void test_with_TemporalField_invalidField() {
 764         TEST_11_30_59_500_PONE.with(ChronoField.YEAR, 0);
 765     }
 766 
 767     //-----------------------------------------------------------------------
 768     // withHour()
 769     //-----------------------------------------------------------------------
 770     @Test
 771     public void test_withHour_normal() {
 772         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 773         OffsetTime test = base.withHour(15);
 774         assertEquals(test, OffsetTime.of(15, 30, 59, 0, OFFSET_PONE));
 775     }
 776 
 777     @Test
 778     public void test_withHour_noChange() {
 779         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 780         OffsetTime test = base.withHour(11);
 781         assertEquals(test, base);
 782     }
 783 
 784     //-----------------------------------------------------------------------
 785     // withMinute()
 786     //-----------------------------------------------------------------------
 787     @Test
 788     public void test_withMinute_normal() {
 789         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 790         OffsetTime test = base.withMinute(15);
 791         assertEquals(test, OffsetTime.of(11, 15, 59, 0, OFFSET_PONE));
 792     }
 793 
 794     @Test
 795     public void test_withMinute_noChange() {
 796         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 797         OffsetTime test = base.withMinute(30);
 798         assertEquals(test, base);
 799     }
 800 
 801     //-----------------------------------------------------------------------
 802     // withSecond()
 803     //-----------------------------------------------------------------------
 804     @Test
 805     public void test_withSecond_normal() {
 806         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 807         OffsetTime test = base.withSecond(15);
 808         assertEquals(test, OffsetTime.of(11, 30, 15, 0, OFFSET_PONE));
 809     }
 810 
 811     @Test
 812     public void test_withSecond_noChange() {
 813         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 814         OffsetTime test = base.withSecond(59);
 815         assertEquals(test, base);
 816     }
 817 
 818     //-----------------------------------------------------------------------
 819     // withNano()
 820     //-----------------------------------------------------------------------
 821     @Test
 822     public void test_withNanoOfSecond_normal() {
 823         OffsetTime base = OffsetTime.of(11, 30, 59, 1, OFFSET_PONE);
 824         OffsetTime test = base.withNano(15);
 825         assertEquals(test, OffsetTime.of(11, 30, 59, 15, OFFSET_PONE));
 826     }
 827 
 828     @Test
 829     public void test_withNanoOfSecond_noChange() {
 830         OffsetTime base = OffsetTime.of(11, 30, 59, 1, OFFSET_PONE);
 831         OffsetTime test = base.withNano(1);
 832         assertEquals(test, base);
 833     }
 834 
 835     //-----------------------------------------------------------------------
 836     // truncatedTo(TemporalUnit)
 837     //-----------------------------------------------------------------------
 838     @Test
 839     public void test_truncatedTo_normal() {
 840         assertEquals(TEST_11_30_59_500_PONE.truncatedTo(NANOS), TEST_11_30_59_500_PONE);
 841         assertEquals(TEST_11_30_59_500_PONE.truncatedTo(SECONDS), TEST_11_30_59_500_PONE.withNano(0));
 842         assertEquals(TEST_11_30_59_500_PONE.truncatedTo(DAYS), TEST_11_30_59_500_PONE.with(LocalTime.MIDNIGHT));
 843     }
 844 
 845     @Test(expectedExceptions=NullPointerException.class)
 846     public void test_truncatedTo_null() {
 847         TEST_11_30_59_500_PONE.truncatedTo(null);
 848     }
 849 
 850     //-----------------------------------------------------------------------
 851     // plus(PlusAdjuster)
 852     //-----------------------------------------------------------------------
 853     @Test
 854     public void test_plus_PlusAdjuster() {
 855         MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MINUTES);
 856         OffsetTime t = TEST_11_30_59_500_PONE.plus(period);
 857         assertEquals(t, OffsetTime.of(11, 37, 59, 500, OFFSET_PONE));
 858     }
 859 
 860     @Test
 861     public void test_plus_PlusAdjuster_noChange() {
 862         OffsetTime t = TEST_11_30_59_500_PONE.plus(MockSimplePeriod.of(0, SECONDS));
 863         assertEquals(t, TEST_11_30_59_500_PONE);
 864     }
 865 
 866     @Test
 867     public void test_plus_PlusAdjuster_zero() {
 868         OffsetTime t = TEST_11_30_59_500_PONE.plus(Period.ZERO);
 869         assertEquals(t, TEST_11_30_59_500_PONE);
 870     }
 871 
 872     @Test(expectedExceptions=NullPointerException.class)
 873     public void test_plus_PlusAdjuster_null() {
 874         TEST_11_30_59_500_PONE.plus((TemporalAmount) null);
 875     }
 876 
 877     //-----------------------------------------------------------------------
 878     // plusHours()
 879     //-----------------------------------------------------------------------
 880     @Test
 881     public void test_plusHours() {
 882         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 883         OffsetTime test = base.plusHours(13);
 884         assertEquals(test, OffsetTime.of(0, 30, 59, 0, OFFSET_PONE));
 885     }
 886 
 887     @Test
 888     public void test_plusHours_zero() {
 889         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 890         OffsetTime test = base.plusHours(0);
 891         assertEquals(test, base);
 892     }
 893 
 894     //-----------------------------------------------------------------------
 895     // plusMinutes()
 896     //-----------------------------------------------------------------------
 897     @Test
 898     public void test_plusMinutes() {
 899         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 900         OffsetTime test = base.plusMinutes(30);
 901         assertEquals(test, OffsetTime.of(12, 0, 59, 0, OFFSET_PONE));
 902     }
 903 
 904     @Test
 905     public void test_plusMinutes_zero() {
 906         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 907         OffsetTime test = base.plusMinutes(0);
 908         assertEquals(test, base);
 909     }
 910 
 911     //-----------------------------------------------------------------------
 912     // plusSeconds()
 913     //-----------------------------------------------------------------------
 914     @Test
 915     public void test_plusSeconds() {
 916         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 917         OffsetTime test = base.plusSeconds(1);
 918         assertEquals(test, OffsetTime.of(11, 31, 0, 0, OFFSET_PONE));
 919     }
 920 
 921     @Test
 922     public void test_plusSeconds_zero() {
 923         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 924         OffsetTime test = base.plusSeconds(0);
 925         assertEquals(test, base);
 926     }
 927 
 928     //-----------------------------------------------------------------------
 929     // plusNanos()
 930     //-----------------------------------------------------------------------
 931     @Test
 932     public void test_plusNanos() {
 933         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 934         OffsetTime test = base.plusNanos(1);
 935         assertEquals(test, OffsetTime.of(11, 30, 59, 1, OFFSET_PONE));
 936     }
 937 
 938     @Test
 939     public void test_plusNanos_zero() {
 940         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 941         OffsetTime test = base.plusNanos(0);
 942         assertEquals(test, base);
 943     }
 944 
 945     //-----------------------------------------------------------------------
 946     // minus(MinusAdjuster)
 947     //-----------------------------------------------------------------------
 948     @Test
 949     public void test_minus_MinusAdjuster() {
 950         MockSimplePeriod period = MockSimplePeriod.of(7, ChronoUnit.MINUTES);
 951         OffsetTime t = TEST_11_30_59_500_PONE.minus(period);
 952         assertEquals(t, OffsetTime.of(11, 23, 59, 500, OFFSET_PONE));
 953     }
 954 
 955     @Test
 956     public void test_minus_MinusAdjuster_noChange() {
 957         OffsetTime t = TEST_11_30_59_500_PONE.minus(MockSimplePeriod.of(0, SECONDS));
 958         assertEquals(t, TEST_11_30_59_500_PONE);
 959     }
 960 
 961     @Test
 962     public void test_minus_MinusAdjuster_zero() {
 963         OffsetTime t = TEST_11_30_59_500_PONE.minus(Period.ZERO);
 964         assertEquals(t, TEST_11_30_59_500_PONE);
 965     }
 966 
 967     @Test(expectedExceptions=NullPointerException.class)
 968     public void test_minus_MinusAdjuster_null() {
 969         TEST_11_30_59_500_PONE.minus((TemporalAmount) null);
 970     }
 971 
 972     //-----------------------------------------------------------------------
 973     // minusHours()
 974     //-----------------------------------------------------------------------
 975     @Test
 976     public void test_minusHours() {
 977         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 978         OffsetTime test = base.minusHours(-13);
 979         assertEquals(test, OffsetTime.of(0, 30, 59, 0, OFFSET_PONE));
 980     }
 981 
 982     @Test
 983     public void test_minusHours_zero() {
 984         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 985         OffsetTime test = base.minusHours(0);
 986         assertEquals(test, base);
 987     }
 988 
 989     //-----------------------------------------------------------------------
 990     // minusMinutes()
 991     //-----------------------------------------------------------------------
 992     @Test
 993     public void test_minusMinutes() {
 994         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
 995         OffsetTime test = base.minusMinutes(50);
 996         assertEquals(test, OffsetTime.of(10, 40, 59, 0, OFFSET_PONE));
 997     }
 998 
 999     @Test
1000     public void test_minusMinutes_zero() {
1001         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
1002         OffsetTime test = base.minusMinutes(0);
1003         assertEquals(test, base);
1004     }
1005 
1006     //-----------------------------------------------------------------------
1007     // minusSeconds()
1008     //-----------------------------------------------------------------------
1009     @Test
1010     public void test_minusSeconds() {
1011         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
1012         OffsetTime test = base.minusSeconds(60);
1013         assertEquals(test, OffsetTime.of(11, 29, 59, 0, OFFSET_PONE));
1014     }
1015 
1016     @Test
1017     public void test_minusSeconds_zero() {
1018         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
1019         OffsetTime test = base.minusSeconds(0);
1020         assertEquals(test, base);
1021     }
1022 
1023     //-----------------------------------------------------------------------
1024     // minusNanos()
1025     //-----------------------------------------------------------------------
1026     @Test
1027     public void test_minusNanos() {
1028         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
1029         OffsetTime test = base.minusNanos(1);
1030         assertEquals(test, OffsetTime.of(11, 30, 58, 999999999, OFFSET_PONE));
1031     }
1032 
1033     @Test
1034     public void test_minusNanos_zero() {
1035         OffsetTime base = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
1036         OffsetTime test = base.minusNanos(0);
1037         assertEquals(test, base);
1038     }
1039 
1040     //-----------------------------------------------------------------------
1041     // periodUntil(Temporal, TemporalUnit)
1042     //-----------------------------------------------------------------------
1043     @DataProvider(name="periodUntilUnit")
1044     Object[][] data_periodUntilUnit() {
1045         return new Object[][] {
1046             {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(13, 1, 1), ZoneOffset.ofHours(1)), HALF_DAYS, 1},
1047             {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), HOURS, 1},
1048             {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), MINUTES, 60},
1049             {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), SECONDS, 3600},
1050             {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), MILLIS, 3600*1000},
1051             {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), MICROS, 3600*1000*1000L},
1052             {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1)), NANOS, 3600*1000*1000L*1000},
1053 
1054             {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(14, 1, 1), ZoneOffset.ofHours(2)), HALF_DAYS, 1},
1055             {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), HOURS, 1},
1056             {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), MINUTES, 60},
1057             {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), SECONDS, 3600},
1058             {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), MILLIS, 3600*1000},
1059             {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), MICROS, 3600*1000*1000L},
1060             {OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1)), OffsetTime.of(LocalTime.of(3, 1, 1), ZoneOffset.ofHours(2)), NANOS, 3600*1000*1000L*1000},
1061         };
1062     }
1063 
1064     @Test(dataProvider="periodUntilUnit")
1065     public void test_periodUntil_TemporalUnit(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) {
1066         long amount = offsetTime1.periodUntil(offsetTime2, unit);
1067         assertEquals(amount, expected);
1068     }
1069 
1070     @Test(dataProvider="periodUntilUnit")
1071     public void test_periodUntil_TemporalUnit_negated(OffsetTime offsetTime1, OffsetTime offsetTime2, TemporalUnit unit, long expected) {
1072         long amount = offsetTime2.periodUntil(offsetTime1, unit);
1073         assertEquals(amount, -expected);
1074     }
1075 
1076     @Test(expectedExceptions=DateTimeException.class)
1077     public void test_periodUntil_InvalidType() {
1078         OffsetTime offsetTime = OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1));
1079         OffsetDateTime offsetDateTime = offsetTime.atDate(LocalDate.of(1980, 2, 10));
1080         offsetTime.periodUntil(offsetDateTime, SECONDS);
1081     }
1082 
1083     @Test(expectedExceptions=DateTimeException.class)
1084     public void test_periodUntil_InvalidTemporalUnit() {
1085         OffsetTime offsetTime1 = OffsetTime.of(LocalTime.of(1, 1, 1), ZoneOffset.ofHours(1));
1086         OffsetTime offsetTime2 = OffsetTime.of(LocalTime.of(2, 1, 1), ZoneOffset.ofHours(1));
1087         offsetTime1.periodUntil(offsetTime2, MONTHS);
1088     }
1089 
1090     //-----------------------------------------------------------------------
1091     // format(DateTimeFormatter)
1092     //-----------------------------------------------------------------------
1093     @Test
1094     public void test_format_formatter() {
1095         DateTimeFormatter f = DateTimeFormatter.ofPattern("H m s");
1096         String t = OffsetTime.of(11, 30, 0, 0, OFFSET_PONE).format(f);
1097         assertEquals(t, "11 30 0");
1098     }
1099 
1100     @Test(expectedExceptions=NullPointerException.class)
1101     public void test_format_formatter_null() {
1102         OffsetTime.of(11, 30, 0, 0, OFFSET_PONE).format(null);
1103     }
1104 
1105     //-----------------------------------------------------------------------
1106     // compareTo()
1107     //-----------------------------------------------------------------------
1108     @Test
1109     public void test_compareTo_time() {
1110         OffsetTime a = OffsetTime.of(11, 29, 0, 0, OFFSET_PONE);
1111         OffsetTime b = OffsetTime.of(11, 30, 0, 0, OFFSET_PONE);  // a is before b due to time
1112         assertEquals(a.compareTo(b) < 0, true);
1113         assertEquals(b.compareTo(a) > 0, true);
1114         assertEquals(a.compareTo(a) == 0, true);
1115         assertEquals(b.compareTo(b) == 0, true);
1116         assertEquals(convertInstant(a).compareTo(convertInstant(b)) < 0, true);
1117     }
1118 
1119     @Test
1120     public void test_compareTo_offset() {
1121         OffsetTime a = OffsetTime.of(11, 30, 0, 0, OFFSET_PTWO);
1122         OffsetTime b = OffsetTime.of(11, 30, 0, 0, OFFSET_PONE);  // a is before b due to offset
1123         assertEquals(a.compareTo(b) < 0, true);
1124         assertEquals(b.compareTo(a) > 0, true);
1125         assertEquals(a.compareTo(a) == 0, true);
1126         assertEquals(b.compareTo(b) == 0, true);
1127         assertEquals(convertInstant(a).compareTo(convertInstant(b)) < 0, true);
1128     }
1129 
1130     @Test
1131     public void test_compareTo_both() {
1132         OffsetTime a = OffsetTime.of(11, 50, 0, 0, OFFSET_PTWO);
1133         OffsetTime b = OffsetTime.of(11, 20, 0, 0, OFFSET_PONE);  // a is before b on instant scale
1134         assertEquals(a.compareTo(b) < 0, true);
1135         assertEquals(b.compareTo(a) > 0, true);
1136         assertEquals(a.compareTo(a) == 0, true);
1137         assertEquals(b.compareTo(b) == 0, true);
1138         assertEquals(convertInstant(a).compareTo(convertInstant(b)) < 0, true);
1139     }
1140 
1141     @Test
1142     public void test_compareTo_bothNearStartOfDay() {
1143         OffsetTime a = OffsetTime.of(0, 10, 0, 0, OFFSET_PONE);
1144         OffsetTime b = OffsetTime.of(2, 30, 0, 0, OFFSET_PTWO);  // a is before b on instant scale
1145         assertEquals(a.compareTo(b) < 0, true);
1146         assertEquals(b.compareTo(a) > 0, true);
1147         assertEquals(a.compareTo(a) == 0, true);
1148         assertEquals(b.compareTo(b) == 0, true);
1149         assertEquals(convertInstant(a).compareTo(convertInstant(b)) < 0, true);
1150     }
1151 
1152     @Test
1153     public void test_compareTo_hourDifference() {
1154         OffsetTime a = OffsetTime.of(10, 0, 0, 0, OFFSET_PONE);
1155         OffsetTime b = OffsetTime.of(11, 0, 0, 0, OFFSET_PTWO);  // a is before b despite being same time-line time
1156         assertEquals(a.compareTo(b) < 0, true);
1157         assertEquals(b.compareTo(a) > 0, true);
1158         assertEquals(a.compareTo(a) == 0, true);
1159         assertEquals(b.compareTo(b) == 0, true);
1160         assertEquals(convertInstant(a).compareTo(convertInstant(b)) == 0, true);
1161     }
1162 
1163     @Test(expectedExceptions=NullPointerException.class)
1164     public void test_compareTo_null() {
1165         OffsetTime a = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
1166         a.compareTo(null);
1167     }
1168 
1169     @Test(expectedExceptions=ClassCastException.class)
1170     @SuppressWarnings({"unchecked", "rawtypes"})
1171     public void compareToNonOffsetTime() {
1172        Comparable c = TEST_11_30_59_500_PONE;
1173        c.compareTo(new Object());
1174     }
1175 
1176     private Instant convertInstant(OffsetTime ot) {
1177         return DATE.atTime(ot.toLocalTime()).toInstant(ot.getOffset());
1178     }
1179 
1180     //-----------------------------------------------------------------------
1181     // isAfter() / isBefore() / isEqual()
1182     //-----------------------------------------------------------------------
1183     @Test
1184     public void test_isBeforeIsAfterIsEqual1() {
1185         OffsetTime a = OffsetTime.of(11, 30, 58, 0, OFFSET_PONE);
1186         OffsetTime b = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);  // a is before b due to time
1187         assertEquals(a.isBefore(b), true);
1188         assertEquals(a.isEqual(b), false);
1189         assertEquals(a.isAfter(b), false);
1190 
1191         assertEquals(b.isBefore(a), false);
1192         assertEquals(b.isEqual(a), false);
1193         assertEquals(b.isAfter(a), true);
1194 
1195         assertEquals(a.isBefore(a), false);
1196         assertEquals(b.isBefore(b), false);
1197 
1198         assertEquals(a.isEqual(a), true);
1199         assertEquals(b.isEqual(b), true);
1200 
1201         assertEquals(a.isAfter(a), false);
1202         assertEquals(b.isAfter(b), false);
1203     }
1204 
1205     @Test
1206     public void test_isBeforeIsAfterIsEqual1nanos() {
1207         OffsetTime a = OffsetTime.of(11, 30, 59, 3, OFFSET_PONE);
1208         OffsetTime b = OffsetTime.of(11, 30, 59, 4, OFFSET_PONE);  // a is before b due to time
1209         assertEquals(a.isBefore(b), true);
1210         assertEquals(a.isEqual(b), false);
1211         assertEquals(a.isAfter(b), false);
1212 
1213         assertEquals(b.isBefore(a), false);
1214         assertEquals(b.isEqual(a), false);
1215         assertEquals(b.isAfter(a), true);
1216 
1217         assertEquals(a.isBefore(a), false);
1218         assertEquals(b.isBefore(b), false);
1219 
1220         assertEquals(a.isEqual(a), true);
1221         assertEquals(b.isEqual(b), true);
1222 
1223         assertEquals(a.isAfter(a), false);
1224         assertEquals(b.isAfter(b), false);
1225     }
1226 
1227     @Test
1228     public void test_isBeforeIsAfterIsEqual2() {
1229         OffsetTime a = OffsetTime.of(11, 30, 59, 0, OFFSET_PTWO);
1230         OffsetTime b = OffsetTime.of(11, 30, 58, 0, OFFSET_PONE);  // a is before b due to offset
1231         assertEquals(a.isBefore(b), true);
1232         assertEquals(a.isEqual(b), false);
1233         assertEquals(a.isAfter(b), false);
1234 
1235         assertEquals(b.isBefore(a), false);
1236         assertEquals(b.isEqual(a), false);
1237         assertEquals(b.isAfter(a), true);
1238 
1239         assertEquals(a.isBefore(a), false);
1240         assertEquals(b.isBefore(b), false);
1241 
1242         assertEquals(a.isEqual(a), true);
1243         assertEquals(b.isEqual(b), true);
1244 
1245         assertEquals(a.isAfter(a), false);
1246         assertEquals(b.isAfter(b), false);
1247     }
1248 
1249     @Test
1250     public void test_isBeforeIsAfterIsEqual2nanos() {
1251         OffsetTime a = OffsetTime.of(11, 30, 59, 4, ZoneOffset.ofTotalSeconds(OFFSET_PONE.getTotalSeconds() + 1));
1252         OffsetTime b = OffsetTime.of(11, 30, 59, 3, OFFSET_PONE);  // a is before b due to offset
1253         assertEquals(a.isBefore(b), true);
1254         assertEquals(a.isEqual(b), false);
1255         assertEquals(a.isAfter(b), false);
1256 
1257         assertEquals(b.isBefore(a), false);
1258         assertEquals(b.isEqual(a), false);
1259         assertEquals(b.isAfter(a), true);
1260 
1261         assertEquals(a.isBefore(a), false);
1262         assertEquals(b.isBefore(b), false);
1263 
1264         assertEquals(a.isEqual(a), true);
1265         assertEquals(b.isEqual(b), true);
1266 
1267         assertEquals(a.isAfter(a), false);
1268         assertEquals(b.isAfter(b), false);
1269     }
1270 
1271     @Test
1272     public void test_isBeforeIsAfterIsEqual_instantComparison() {
1273         OffsetTime a = OffsetTime.of(11, 30, 59, 0, OFFSET_PTWO);
1274         OffsetTime b = OffsetTime.of(10, 30, 59, 0, OFFSET_PONE);  // a is same instant as b
1275         assertEquals(a.isBefore(b), false);
1276         assertEquals(a.isEqual(b), true);
1277         assertEquals(a.isAfter(b), false);
1278 
1279         assertEquals(b.isBefore(a), false);
1280         assertEquals(b.isEqual(a), true);
1281         assertEquals(b.isAfter(a), false);
1282 
1283         assertEquals(a.isBefore(a), false);
1284         assertEquals(b.isBefore(b), false);
1285 
1286         assertEquals(a.isEqual(a), true);
1287         assertEquals(b.isEqual(b), true);
1288 
1289         assertEquals(a.isAfter(a), false);
1290         assertEquals(b.isAfter(b), false);
1291     }
1292 
1293     @Test(expectedExceptions=NullPointerException.class)
1294     public void test_isBefore_null() {
1295         OffsetTime a = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
1296         a.isBefore(null);
1297     }
1298 
1299     @Test(expectedExceptions=NullPointerException.class)
1300     public void test_isAfter_null() {
1301         OffsetTime a = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
1302         a.isAfter(null);
1303     }
1304 
1305     @Test(expectedExceptions=NullPointerException.class)
1306     public void test_isEqual_null() {
1307         OffsetTime a = OffsetTime.of(11, 30, 59, 0, OFFSET_PONE);
1308         a.isEqual(null);
1309     }
1310 
1311     //-----------------------------------------------------------------------
1312     // equals() / hashCode()
1313     //-----------------------------------------------------------------------
1314     @Test(dataProvider="sampleTimes")
1315     public void test_equals_true(int h, int m, int s, int n, ZoneOffset ignored) {
1316         OffsetTime a = OffsetTime.of(h, m, s, n, OFFSET_PONE);
1317         OffsetTime b = OffsetTime.of(h, m, s, n, OFFSET_PONE);
1318         assertEquals(a.equals(b), true);
1319         assertEquals(a.hashCode() == b.hashCode(), true);
1320     }
1321     @Test(dataProvider="sampleTimes")
1322     public void test_equals_false_hour_differs(int h, int m, int s, int n, ZoneOffset ignored) {
1323         h = (h == 23 ? 22 : h);
1324         OffsetTime a = OffsetTime.of(h, m, s, n, OFFSET_PONE);
1325         OffsetTime b = OffsetTime.of(h + 1, m, s, n, OFFSET_PONE);
1326         assertEquals(a.equals(b), false);
1327     }
1328     @Test(dataProvider="sampleTimes")
1329     public void test_equals_false_minute_differs(int h, int m, int s, int n, ZoneOffset ignored) {
1330         m = (m == 59 ? 58 : m);
1331         OffsetTime a = OffsetTime.of(h, m, s, n, OFFSET_PONE);
1332         OffsetTime b = OffsetTime.of(h, m + 1, s, n, OFFSET_PONE);
1333         assertEquals(a.equals(b), false);
1334     }
1335     @Test(dataProvider="sampleTimes")
1336     public void test_equals_false_second_differs(int h, int m, int s, int n, ZoneOffset ignored) {
1337         s = (s == 59 ? 58 : s);
1338         OffsetTime a = OffsetTime.of(h, m, s, n, OFFSET_PONE);
1339         OffsetTime b = OffsetTime.of(h, m, s + 1, n, OFFSET_PONE);
1340         assertEquals(a.equals(b), false);
1341     }
1342     @Test(dataProvider="sampleTimes")
1343     public void test_equals_false_nano_differs(int h, int m, int s, int n, ZoneOffset ignored) {
1344         n = (n == 999999999 ? 999999998 : n);
1345         OffsetTime a = OffsetTime.of(h, m, s, n, OFFSET_PONE);
1346         OffsetTime b = OffsetTime.of(h, m, s, n + 1, OFFSET_PONE);
1347         assertEquals(a.equals(b), false);
1348     }
1349     @Test(dataProvider="sampleTimes")
1350     public void test_equals_false_offset_differs(int h, int m, int s, int n, ZoneOffset ignored) {
1351         OffsetTime a = OffsetTime.of(h, m, s, n, OFFSET_PONE);
1352         OffsetTime b = OffsetTime.of(h, m, s, n, OFFSET_PTWO);
1353         assertEquals(a.equals(b), false);
1354     }
1355 
1356     @Test
1357     public void test_equals_itself_true() {
1358         assertEquals(TEST_11_30_59_500_PONE.equals(TEST_11_30_59_500_PONE), true);
1359     }
1360 
1361     @Test
1362     public void test_equals_string_false() {
1363         assertEquals(TEST_11_30_59_500_PONE.equals("2007-07-15"), false);
1364     }
1365 
1366     @Test
1367     public void test_equals_null_false() {
1368         assertEquals(TEST_11_30_59_500_PONE.equals(null), false);
1369     }
1370 
1371     //-----------------------------------------------------------------------
1372     // toString()
1373     //-----------------------------------------------------------------------
1374     @DataProvider(name="sampleToString")
1375     Object[][] provider_sampleToString() {
1376         return new Object[][] {
1377             {11, 30, 59, 0, "Z", "11:30:59Z"},
1378             {11, 30, 59, 0, "+01:00", "11:30:59+01:00"},
1379             {11, 30, 59, 999000000, "Z", "11:30:59.999Z"},
1380             {11, 30, 59, 999000000, "+01:00", "11:30:59.999+01:00"},
1381             {11, 30, 59, 999000, "Z", "11:30:59.000999Z"},
1382             {11, 30, 59, 999000, "+01:00", "11:30:59.000999+01:00"},
1383             {11, 30, 59, 999, "Z", "11:30:59.000000999Z"},
1384             {11, 30, 59, 999, "+01:00", "11:30:59.000000999+01:00"},
1385         };
1386     }
1387 
1388     @Test(dataProvider="sampleToString")
1389     public void test_toString(int h, int m, int s, int n, String offsetId, String expected) {
1390         OffsetTime t = OffsetTime.of(h, m, s, n, ZoneOffset.of(offsetId));
1391         String str = t.toString();
1392         assertEquals(str, expected);
1393     }
1394 
1395 }