1 /* 2 * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * This file is available under and governed by the GNU General Public 28 * License version 2 only, as published by the Free Software Foundation. 29 * However, the following notice accompanied the original version of this 30 * file: 31 * 32 * Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos 33 * 34 * All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions are met: 38 * 39 * * Redistributions of source code must retain the above copyright notice, 40 * this list of conditions and the following disclaimer. 41 * 42 * * Redistributions in binary form must reproduce the above copyright notice, 43 * this list of conditions and the following disclaimer in the documentation 44 * and/or other materials provided with the distribution. 45 * 46 * * Neither the name of JSR-310 nor the names of its contributors 47 * may be used to endorse or promote products derived from this software 48 * without specific prior written permission. 49 * 50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 54 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 55 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 56 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 57 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 58 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 59 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 60 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 61 */ 62 package java.time; 63 64 import static java.time.temporal.ChronoField.HOUR_OF_DAY; 65 import static java.time.temporal.ChronoField.MICRO_OF_DAY; 66 import static java.time.temporal.ChronoField.MINUTE_OF_HOUR; 67 import static java.time.temporal.ChronoField.NANO_OF_DAY; 68 import static java.time.temporal.ChronoField.NANO_OF_SECOND; 69 import static java.time.temporal.ChronoField.SECOND_OF_DAY; 70 import static java.time.temporal.ChronoField.SECOND_OF_MINUTE; 71 import static java.time.temporal.ChronoUnit.NANOS; 72 73 import java.io.DataInput; 74 import java.io.DataOutput; 75 import java.io.IOException; 76 import java.io.InvalidObjectException; 77 import java.io.ObjectInputStream; 78 import java.io.Serializable; 79 import java.time.format.DateTimeFormatter; 80 import java.time.format.DateTimeParseException; 81 import java.time.temporal.ChronoField; 82 import java.time.temporal.ChronoUnit; 83 import java.time.temporal.Temporal; 84 import java.time.temporal.TemporalAccessor; 85 import java.time.temporal.TemporalAdjuster; 86 import java.time.temporal.TemporalAmount; 87 import java.time.temporal.TemporalField; 88 import java.time.temporal.TemporalQueries; 89 import java.time.temporal.TemporalQuery; 90 import java.time.temporal.TemporalUnit; 91 import java.time.temporal.UnsupportedTemporalTypeException; 92 import java.time.temporal.ValueRange; 93 import java.util.Objects; 94 95 // Android-changed: removed ValueBased paragraph. 96 /** 97 * A time without a time-zone in the ISO-8601 calendar system, 98 * such as {@code 10:15:30}. 99 * <p> 100 * {@code LocalTime} is an immutable date-time object that represents a time, 101 * often viewed as hour-minute-second. 102 * Time is represented to nanosecond precision. 103 * For example, the value "13:45.30.123456789" can be stored in a {@code LocalTime}. 104 * <p> 105 * This class does not store or represent a date or time-zone. 106 * Instead, it is a description of the local time as seen on a wall clock. 107 * It cannot represent an instant on the time-line without additional information 108 * such as an offset or time-zone. 109 * <p> 110 * The ISO-8601 calendar system is the modern civil calendar system used today 111 * in most of the world. This API assumes that all calendar systems use the same 112 * representation, this class, for time-of-day. 113 * 114 * @implSpec 115 * This class is immutable and thread-safe. 116 * 117 * @since 1.8 118 */ 119 public final class LocalTime 120 implements Temporal, TemporalAdjuster, Comparable<LocalTime>, Serializable { 121 122 /** 123 * The minimum supported {@code LocalTime}, '00:00'. 124 * This is the time of midnight at the start of the day. 125 */ 126 public static final LocalTime MIN; 127 /** 128 * The maximum supported {@code LocalTime}, '23:59:59.999999999'. 129 * This is the time just before midnight at the end of the day. 130 */ 131 public static final LocalTime MAX; 132 /** 133 * The time of midnight at the start of the day, '00:00'. 134 */ 135 public static final LocalTime MIDNIGHT; 136 /** 137 * The time of noon in the middle of the day, '12:00'. 138 */ 139 public static final LocalTime NOON; 140 /** 141 * Constants for the local time of each hour. 142 */ 143 private static final LocalTime[] HOURS = new LocalTime[24]; 144 static { 145 for (int i = 0; i < HOURS.length; i++) { 146 HOURS[i] = new LocalTime(i, 0, 0, 0); 147 } 148 MIDNIGHT = HOURS[0]; 149 NOON = HOURS[12]; 150 MIN = HOURS[0]; 151 MAX = new LocalTime(23, 59, 59, 999_999_999); 152 } 153 154 /** 155 * Hours per day. 156 */ 157 static final int HOURS_PER_DAY = 24; 158 /** 159 * Minutes per hour. 160 */ 161 static final int MINUTES_PER_HOUR = 60; 162 /** 163 * Minutes per day. 164 */ 165 static final int MINUTES_PER_DAY = MINUTES_PER_HOUR * HOURS_PER_DAY; 166 /** 167 * Seconds per minute. 168 */ 169 static final int SECONDS_PER_MINUTE = 60; 170 /** 171 * Seconds per hour. 172 */ 173 static final int SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR; 174 /** 175 * Seconds per day. 176 */ 177 static final int SECONDS_PER_DAY = SECONDS_PER_HOUR * HOURS_PER_DAY; 178 /** 179 * Milliseconds per day. 180 */ 181 static final long MILLIS_PER_DAY = SECONDS_PER_DAY * 1000L; 182 /** 183 * Microseconds per day. 184 */ 185 static final long MICROS_PER_DAY = SECONDS_PER_DAY * 1000_000L; 186 /** 187 * Nanos per millisecond. 188 */ 189 static final long NANOS_PER_MILLI = 1000_000L; 190 /** 191 * Nanos per second. 192 */ 193 static final long NANOS_PER_SECOND = 1000_000_000L; 194 /** 195 * Nanos per minute. 196 */ 197 static final long NANOS_PER_MINUTE = NANOS_PER_SECOND * SECONDS_PER_MINUTE; 198 /** 199 * Nanos per hour. 200 */ 201 static final long NANOS_PER_HOUR = NANOS_PER_MINUTE * MINUTES_PER_HOUR; 202 /** 203 * Nanos per day. 204 */ 205 static final long NANOS_PER_DAY = NANOS_PER_HOUR * HOURS_PER_DAY; 206 207 /** 208 * Serialization version. 209 */ 210 private static final long serialVersionUID = 6414437269572265201L; 211 212 /** 213 * The hour. 214 */ 215 private final byte hour; 216 /** 217 * The minute. 218 */ 219 private final byte minute; 220 /** 221 * The second. 222 */ 223 private final byte second; 224 /** 225 * The nanosecond. 226 */ 227 private final int nano; 228 229 //----------------------------------------------------------------------- 230 /** 231 * Obtains the current time from the system clock in the default time-zone. 232 * <p> 233 * This will query the {@link Clock#systemDefaultZone() system clock} in the default 234 * time-zone to obtain the current time. 235 * <p> 236 * Using this method will prevent the ability to use an alternate clock for testing 237 * because the clock is hard-coded. 238 * 239 * @return the current time using the system clock and default time-zone, not null 240 */ now()241 public static LocalTime now() { 242 return now(Clock.systemDefaultZone()); 243 } 244 245 /** 246 * Obtains the current time from the system clock in the specified time-zone. 247 * <p> 248 * This will query the {@link Clock#system(ZoneId) system clock} to obtain the current time. 249 * Specifying the time-zone avoids dependence on the default time-zone. 250 * <p> 251 * Using this method will prevent the ability to use an alternate clock for testing 252 * because the clock is hard-coded. 253 * 254 * @param zone the zone ID to use, not null 255 * @return the current time using the system clock, not null 256 */ now(ZoneId zone)257 public static LocalTime now(ZoneId zone) { 258 return now(Clock.system(zone)); 259 } 260 261 /** 262 * Obtains the current time from the specified clock. 263 * <p> 264 * This will query the specified clock to obtain the current time. 265 * Using this method allows the use of an alternate clock for testing. 266 * The alternate clock may be introduced using {@link Clock dependency injection}. 267 * 268 * @param clock the clock to use, not null 269 * @return the current time, not null 270 */ now(Clock clock)271 public static LocalTime now(Clock clock) { 272 Objects.requireNonNull(clock, "clock"); 273 // inline OffsetTime factory to avoid creating object and InstantProvider checks 274 final Instant now = clock.instant(); // called once 275 return ofInstant(now, clock.getZone()); 276 } 277 278 //----------------------------------------------------------------------- 279 /** 280 * Obtains an instance of {@code LocalTime} from an hour and minute. 281 * <p> 282 * This returns a {@code LocalTime} with the specified hour and minute. 283 * The second and nanosecond fields will be set to zero. 284 * 285 * @param hour the hour-of-day to represent, from 0 to 23 286 * @param minute the minute-of-hour to represent, from 0 to 59 287 * @return the local time, not null 288 * @throws DateTimeException if the value of any field is out of range 289 */ of(int hour, int minute)290 public static LocalTime of(int hour, int minute) { 291 HOUR_OF_DAY.checkValidValue(hour); 292 if (minute == 0) { 293 return HOURS[hour]; // for performance 294 } 295 MINUTE_OF_HOUR.checkValidValue(minute); 296 return new LocalTime(hour, minute, 0, 0); 297 } 298 299 /** 300 * Obtains an instance of {@code LocalTime} from an hour, minute and second. 301 * <p> 302 * This returns a {@code LocalTime} with the specified hour, minute and second. 303 * The nanosecond field will be set to zero. 304 * 305 * @param hour the hour-of-day to represent, from 0 to 23 306 * @param minute the minute-of-hour to represent, from 0 to 59 307 * @param second the second-of-minute to represent, from 0 to 59 308 * @return the local time, not null 309 * @throws DateTimeException if the value of any field is out of range 310 */ of(int hour, int minute, int second)311 public static LocalTime of(int hour, int minute, int second) { 312 HOUR_OF_DAY.checkValidValue(hour); 313 if ((minute | second) == 0) { 314 return HOURS[hour]; // for performance 315 } 316 MINUTE_OF_HOUR.checkValidValue(minute); 317 SECOND_OF_MINUTE.checkValidValue(second); 318 return new LocalTime(hour, minute, second, 0); 319 } 320 321 /** 322 * Obtains an instance of {@code LocalTime} from an hour, minute, second and nanosecond. 323 * <p> 324 * This returns a {@code LocalTime} with the specified hour, minute, second and nanosecond. 325 * 326 * @param hour the hour-of-day to represent, from 0 to 23 327 * @param minute the minute-of-hour to represent, from 0 to 59 328 * @param second the second-of-minute to represent, from 0 to 59 329 * @param nanoOfSecond the nano-of-second to represent, from 0 to 999,999,999 330 * @return the local time, not null 331 * @throws DateTimeException if the value of any field is out of range 332 */ of(int hour, int minute, int second, int nanoOfSecond)333 public static LocalTime of(int hour, int minute, int second, int nanoOfSecond) { 334 HOUR_OF_DAY.checkValidValue(hour); 335 MINUTE_OF_HOUR.checkValidValue(minute); 336 SECOND_OF_MINUTE.checkValidValue(second); 337 NANO_OF_SECOND.checkValidValue(nanoOfSecond); 338 return create(hour, minute, second, nanoOfSecond); 339 } 340 341 /** 342 * Obtains an instance of {@code LocalTime} from an {@code Instant} and zone ID. 343 * <p> 344 * This creates a local time based on the specified instant. 345 * First, the offset from UTC/Greenwich is obtained using the zone ID and instant, 346 * which is simple as there is only one valid offset for each instant. 347 * Then, the instant and offset are used to calculate the local time. 348 * 349 * @param instant the instant to create the time from, not null 350 * @param zone the time-zone, which may be an offset, not null 351 * @return the local time, not null 352 * @since 9 353 */ ofInstant(Instant instant, ZoneId zone)354 public static LocalTime ofInstant(Instant instant, ZoneId zone) { 355 Objects.requireNonNull(instant, "instant"); 356 Objects.requireNonNull(zone, "zone"); 357 ZoneOffset offset = zone.getRules().getOffset(instant); 358 long localSecond = instant.getEpochSecond() + offset.getTotalSeconds(); 359 int secsOfDay = Math.floorMod(localSecond, SECONDS_PER_DAY); 360 return ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + instant.getNano()); 361 } 362 363 //----------------------------------------------------------------------- 364 /** 365 * Obtains an instance of {@code LocalTime} from a second-of-day value. 366 * <p> 367 * This returns a {@code LocalTime} with the specified second-of-day. 368 * The nanosecond field will be set to zero. 369 * 370 * @param secondOfDay the second-of-day, from {@code 0} to {@code 24 * 60 * 60 - 1} 371 * @return the local time, not null 372 * @throws DateTimeException if the second-of-day value is invalid 373 */ ofSecondOfDay(long secondOfDay)374 public static LocalTime ofSecondOfDay(long secondOfDay) { 375 SECOND_OF_DAY.checkValidValue(secondOfDay); 376 int hours = (int) (secondOfDay / SECONDS_PER_HOUR); 377 secondOfDay -= hours * SECONDS_PER_HOUR; 378 int minutes = (int) (secondOfDay / SECONDS_PER_MINUTE); 379 secondOfDay -= minutes * SECONDS_PER_MINUTE; 380 return create(hours, minutes, (int) secondOfDay, 0); 381 } 382 383 /** 384 * Obtains an instance of {@code LocalTime} from a nanos-of-day value. 385 * <p> 386 * This returns a {@code LocalTime} with the specified nanosecond-of-day. 387 * 388 * @param nanoOfDay the nano of day, from {@code 0} to {@code 24 * 60 * 60 * 1,000,000,000 - 1} 389 * @return the local time, not null 390 * @throws DateTimeException if the nanos of day value is invalid 391 */ ofNanoOfDay(long nanoOfDay)392 public static LocalTime ofNanoOfDay(long nanoOfDay) { 393 NANO_OF_DAY.checkValidValue(nanoOfDay); 394 int hours = (int) (nanoOfDay / NANOS_PER_HOUR); 395 nanoOfDay -= hours * NANOS_PER_HOUR; 396 int minutes = (int) (nanoOfDay / NANOS_PER_MINUTE); 397 nanoOfDay -= minutes * NANOS_PER_MINUTE; 398 int seconds = (int) (nanoOfDay / NANOS_PER_SECOND); 399 nanoOfDay -= seconds * NANOS_PER_SECOND; 400 return create(hours, minutes, seconds, (int) nanoOfDay); 401 } 402 403 //----------------------------------------------------------------------- 404 /** 405 * Obtains an instance of {@code LocalTime} from a temporal object. 406 * <p> 407 * This obtains a local time based on the specified temporal. 408 * A {@code TemporalAccessor} represents an arbitrary set of date and time information, 409 * which this factory converts to an instance of {@code LocalTime}. 410 * <p> 411 * The conversion uses the {@link TemporalQueries#localTime()} query, which relies 412 * on extracting the {@link ChronoField#NANO_OF_DAY NANO_OF_DAY} field. 413 * <p> 414 * This method matches the signature of the functional interface {@link TemporalQuery} 415 * allowing it to be used as a query via method reference, {@code LocalTime::from}. 416 * 417 * @param temporal the temporal object to convert, not null 418 * @return the local time, not null 419 * @throws DateTimeException if unable to convert to a {@code LocalTime} 420 */ from(TemporalAccessor temporal)421 public static LocalTime from(TemporalAccessor temporal) { 422 Objects.requireNonNull(temporal, "temporal"); 423 LocalTime time = temporal.query(TemporalQueries.localTime()); 424 if (time == null) { 425 throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: " + 426 temporal + " of type " + temporal.getClass().getName()); 427 } 428 return time; 429 } 430 431 //----------------------------------------------------------------------- 432 /** 433 * Obtains an instance of {@code LocalTime} from a text string such as {@code 10:15}. 434 * <p> 435 * The string must represent a valid time and is parsed using 436 * {@link java.time.format.DateTimeFormatter#ISO_LOCAL_TIME}. 437 * 438 * @param text the text to parse such as "10:15:30", not null 439 * @return the parsed local time, not null 440 * @throws DateTimeParseException if the text cannot be parsed 441 */ parse(CharSequence text)442 public static LocalTime parse(CharSequence text) { 443 return parse(text, DateTimeFormatter.ISO_LOCAL_TIME); 444 } 445 446 /** 447 * Obtains an instance of {@code LocalTime} from a text string using a specific formatter. 448 * <p> 449 * The text is parsed using the formatter, returning a time. 450 * 451 * @param text the text to parse, not null 452 * @param formatter the formatter to use, not null 453 * @return the parsed local time, not null 454 * @throws DateTimeParseException if the text cannot be parsed 455 */ parse(CharSequence text, DateTimeFormatter formatter)456 public static LocalTime parse(CharSequence text, DateTimeFormatter formatter) { 457 Objects.requireNonNull(formatter, "formatter"); 458 return formatter.parse(text, LocalTime::from); 459 } 460 461 //----------------------------------------------------------------------- 462 /** 463 * Creates a local time from the hour, minute, second and nanosecond fields. 464 * <p> 465 * This factory may return a cached value, but applications must not rely on this. 466 * 467 * @param hour the hour-of-day to represent, validated from 0 to 23 468 * @param minute the minute-of-hour to represent, validated from 0 to 59 469 * @param second the second-of-minute to represent, validated from 0 to 59 470 * @param nanoOfSecond the nano-of-second to represent, validated from 0 to 999,999,999 471 * @return the local time, not null 472 */ create(int hour, int minute, int second, int nanoOfSecond)473 private static LocalTime create(int hour, int minute, int second, int nanoOfSecond) { 474 if ((minute | second | nanoOfSecond) == 0) { 475 return HOURS[hour]; 476 } 477 return new LocalTime(hour, minute, second, nanoOfSecond); 478 } 479 480 /** 481 * Constructor, previously validated. 482 * 483 * @param hour the hour-of-day to represent, validated from 0 to 23 484 * @param minute the minute-of-hour to represent, validated from 0 to 59 485 * @param second the second-of-minute to represent, validated from 0 to 59 486 * @param nanoOfSecond the nano-of-second to represent, validated from 0 to 999,999,999 487 */ LocalTime(int hour, int minute, int second, int nanoOfSecond)488 private LocalTime(int hour, int minute, int second, int nanoOfSecond) { 489 this.hour = (byte) hour; 490 this.minute = (byte) minute; 491 this.second = (byte) second; 492 this.nano = nanoOfSecond; 493 } 494 495 //----------------------------------------------------------------------- 496 /** 497 * Checks if the specified field is supported. 498 * <p> 499 * This checks if this time can be queried for the specified field. 500 * If false, then calling the {@link #range(TemporalField) range}, 501 * {@link #get(TemporalField) get} and {@link #with(TemporalField, long)} 502 * methods will throw an exception. 503 * <p> 504 * If the field is a {@link ChronoField} then the query is implemented here. 505 * The supported fields are: 506 * <ul> 507 * <li>{@code NANO_OF_SECOND} 508 * <li>{@code NANO_OF_DAY} 509 * <li>{@code MICRO_OF_SECOND} 510 * <li>{@code MICRO_OF_DAY} 511 * <li>{@code MILLI_OF_SECOND} 512 * <li>{@code MILLI_OF_DAY} 513 * <li>{@code SECOND_OF_MINUTE} 514 * <li>{@code SECOND_OF_DAY} 515 * <li>{@code MINUTE_OF_HOUR} 516 * <li>{@code MINUTE_OF_DAY} 517 * <li>{@code HOUR_OF_AMPM} 518 * <li>{@code CLOCK_HOUR_OF_AMPM} 519 * <li>{@code HOUR_OF_DAY} 520 * <li>{@code CLOCK_HOUR_OF_DAY} 521 * <li>{@code AMPM_OF_DAY} 522 * </ul> 523 * All other {@code ChronoField} instances will return false. 524 * <p> 525 * If the field is not a {@code ChronoField}, then the result of this method 526 * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)} 527 * passing {@code this} as the argument. 528 * Whether the field is supported is determined by the field. 529 * 530 * @param field the field to check, null returns false 531 * @return true if the field is supported on this time, false if not 532 */ 533 @Override isSupported(TemporalField field)534 public boolean isSupported(TemporalField field) { 535 if (field instanceof ChronoField) { 536 return field.isTimeBased(); 537 } 538 return field != null && field.isSupportedBy(this); 539 } 540 541 /** 542 * Checks if the specified unit is supported. 543 * <p> 544 * This checks if the specified unit can be added to, or subtracted from, this time. 545 * If false, then calling the {@link #plus(long, TemporalUnit)} and 546 * {@link #minus(long, TemporalUnit) minus} methods will throw an exception. 547 * <p> 548 * If the unit is a {@link ChronoUnit} then the query is implemented here. 549 * The supported units are: 550 * <ul> 551 * <li>{@code NANOS} 552 * <li>{@code MICROS} 553 * <li>{@code MILLIS} 554 * <li>{@code SECONDS} 555 * <li>{@code MINUTES} 556 * <li>{@code HOURS} 557 * <li>{@code HALF_DAYS} 558 * </ul> 559 * All other {@code ChronoUnit} instances will return false. 560 * <p> 561 * If the unit is not a {@code ChronoUnit}, then the result of this method 562 * is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)} 563 * passing {@code this} as the argument. 564 * Whether the unit is supported is determined by the unit. 565 * 566 * @param unit the unit to check, null returns false 567 * @return true if the unit can be added/subtracted, false if not 568 */ 569 @Override // override for Javadoc isSupported(TemporalUnit unit)570 public boolean isSupported(TemporalUnit unit) { 571 if (unit instanceof ChronoUnit) { 572 return unit.isTimeBased(); 573 } 574 return unit != null && unit.isSupportedBy(this); 575 } 576 577 //----------------------------------------------------------------------- 578 /** 579 * Gets the range of valid values for the specified field. 580 * <p> 581 * The range object expresses the minimum and maximum valid values for a field. 582 * This time is used to enhance the accuracy of the returned range. 583 * If it is not possible to return the range, because the field is not supported 584 * or for some other reason, an exception is thrown. 585 * <p> 586 * If the field is a {@link ChronoField} then the query is implemented here. 587 * The {@link #isSupported(TemporalField) supported fields} will return 588 * appropriate range instances. 589 * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}. 590 * <p> 591 * If the field is not a {@code ChronoField}, then the result of this method 592 * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)} 593 * passing {@code this} as the argument. 594 * Whether the range can be obtained is determined by the field. 595 * 596 * @param field the field to query the range for, not null 597 * @return the range of valid values for the field, not null 598 * @throws DateTimeException if the range for the field cannot be obtained 599 * @throws UnsupportedTemporalTypeException if the field is not supported 600 */ 601 @Override // override for Javadoc range(TemporalField field)602 public ValueRange range(TemporalField field) { 603 return Temporal.super.range(field); 604 } 605 606 /** 607 * Gets the value of the specified field from this time as an {@code int}. 608 * <p> 609 * This queries this time for the value of the specified field. 610 * The returned value will always be within the valid range of values for the field. 611 * If it is not possible to return the value, because the field is not supported 612 * or for some other reason, an exception is thrown. 613 * <p> 614 * If the field is a {@link ChronoField} then the query is implemented here. 615 * The {@link #isSupported(TemporalField) supported fields} will return valid 616 * values based on this time, except {@code NANO_OF_DAY} and {@code MICRO_OF_DAY} 617 * which are too large to fit in an {@code int} and throw an {@code UnsupportedTemporalTypeException}. 618 * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}. 619 * <p> 620 * If the field is not a {@code ChronoField}, then the result of this method 621 * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)} 622 * passing {@code this} as the argument. Whether the value can be obtained, 623 * and what the value represents, is determined by the field. 624 * 625 * @param field the field to get, not null 626 * @return the value for the field 627 * @throws DateTimeException if a value for the field cannot be obtained or 628 * the value is outside the range of valid values for the field 629 * @throws UnsupportedTemporalTypeException if the field is not supported or 630 * the range of values exceeds an {@code int} 631 * @throws ArithmeticException if numeric overflow occurs 632 */ 633 @Override // override for Javadoc and performance get(TemporalField field)634 public int get(TemporalField field) { 635 if (field instanceof ChronoField) { 636 return get0(field); 637 } 638 return Temporal.super.get(field); 639 } 640 641 /** 642 * Gets the value of the specified field from this time as a {@code long}. 643 * <p> 644 * This queries this time for the value of the specified field. 645 * If it is not possible to return the value, because the field is not supported 646 * or for some other reason, an exception is thrown. 647 * <p> 648 * If the field is a {@link ChronoField} then the query is implemented here. 649 * The {@link #isSupported(TemporalField) supported fields} will return valid 650 * values based on this time. 651 * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}. 652 * <p> 653 * If the field is not a {@code ChronoField}, then the result of this method 654 * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)} 655 * passing {@code this} as the argument. Whether the value can be obtained, 656 * and what the value represents, is determined by the field. 657 * 658 * @param field the field to get, not null 659 * @return the value for the field 660 * @throws DateTimeException if a value for the field cannot be obtained 661 * @throws UnsupportedTemporalTypeException if the field is not supported 662 * @throws ArithmeticException if numeric overflow occurs 663 */ 664 @Override getLong(TemporalField field)665 public long getLong(TemporalField field) { 666 if (field instanceof ChronoField) { 667 if (field == NANO_OF_DAY) { 668 return toNanoOfDay(); 669 } 670 if (field == MICRO_OF_DAY) { 671 return toNanoOfDay() / 1000; 672 } 673 return get0(field); 674 } 675 return field.getFrom(this); 676 } 677 get0(TemporalField field)678 private int get0(TemporalField field) { 679 switch ((ChronoField) field) { 680 case NANO_OF_SECOND: return nano; 681 case NANO_OF_DAY: throw new UnsupportedTemporalTypeException("Invalid field 'NanoOfDay' for get() method, use getLong() instead"); 682 case MICRO_OF_SECOND: return nano / 1000; 683 case MICRO_OF_DAY: throw new UnsupportedTemporalTypeException("Invalid field 'MicroOfDay' for get() method, use getLong() instead"); 684 case MILLI_OF_SECOND: return nano / 1000_000; 685 case MILLI_OF_DAY: return (int) (toNanoOfDay() / 1000_000); 686 case SECOND_OF_MINUTE: return second; 687 case SECOND_OF_DAY: return toSecondOfDay(); 688 case MINUTE_OF_HOUR: return minute; 689 case MINUTE_OF_DAY: return hour * 60 + minute; 690 case HOUR_OF_AMPM: return hour % 12; 691 case CLOCK_HOUR_OF_AMPM: int ham = hour % 12; return (ham % 12 == 0 ? 12 : ham); 692 case HOUR_OF_DAY: return hour; 693 case CLOCK_HOUR_OF_DAY: return (hour == 0 ? 24 : hour); 694 case AMPM_OF_DAY: return hour / 12; 695 } 696 throw new UnsupportedTemporalTypeException("Unsupported field: " + field); 697 } 698 699 //----------------------------------------------------------------------- 700 /** 701 * Gets the hour-of-day field. 702 * 703 * @return the hour-of-day, from 0 to 23 704 */ getHour()705 public int getHour() { 706 return hour; 707 } 708 709 /** 710 * Gets the minute-of-hour field. 711 * 712 * @return the minute-of-hour, from 0 to 59 713 */ getMinute()714 public int getMinute() { 715 return minute; 716 } 717 718 /** 719 * Gets the second-of-minute field. 720 * 721 * @return the second-of-minute, from 0 to 59 722 */ getSecond()723 public int getSecond() { 724 return second; 725 } 726 727 /** 728 * Gets the nano-of-second field. 729 * 730 * @return the nano-of-second, from 0 to 999,999,999 731 */ getNano()732 public int getNano() { 733 return nano; 734 } 735 736 //----------------------------------------------------------------------- 737 /** 738 * Returns an adjusted copy of this time. 739 * <p> 740 * This returns a {@code LocalTime}, based on this one, with the time adjusted. 741 * The adjustment takes place using the specified adjuster strategy object. 742 * Read the documentation of the adjuster to understand what adjustment will be made. 743 * <p> 744 * A simple adjuster might simply set the one of the fields, such as the hour field. 745 * A more complex adjuster might set the time to the last hour of the day. 746 * <p> 747 * The result of this method is obtained by invoking the 748 * {@link TemporalAdjuster#adjustInto(Temporal)} method on the 749 * specified adjuster passing {@code this} as the argument. 750 * <p> 751 * This instance is immutable and unaffected by this method call. 752 * 753 * @param adjuster the adjuster to use, not null 754 * @return a {@code LocalTime} based on {@code this} with the adjustment made, not null 755 * @throws DateTimeException if the adjustment cannot be made 756 * @throws ArithmeticException if numeric overflow occurs 757 */ 758 @Override with(TemporalAdjuster adjuster)759 public LocalTime with(TemporalAdjuster adjuster) { 760 // optimizations 761 if (adjuster instanceof LocalTime) { 762 return (LocalTime) adjuster; 763 } 764 return (LocalTime) adjuster.adjustInto(this); 765 } 766 767 /** 768 * Returns a copy of this time with the specified field set to a new value. 769 * <p> 770 * This returns a {@code LocalTime}, based on this one, with the value 771 * for the specified field changed. 772 * This can be used to change any supported field, such as the hour, minute or second. 773 * If it is not possible to set the value, because the field is not supported or for 774 * some other reason, an exception is thrown. 775 * <p> 776 * If the field is a {@link ChronoField} then the adjustment is implemented here. 777 * The supported fields behave as follows: 778 * <ul> 779 * <li>{@code NANO_OF_SECOND} - 780 * Returns a {@code LocalTime} with the specified nano-of-second. 781 * The hour, minute and second will be unchanged. 782 * <li>{@code NANO_OF_DAY} - 783 * Returns a {@code LocalTime} with the specified nano-of-day. 784 * This completely replaces the time and is equivalent to {@link #ofNanoOfDay(long)}. 785 * <li>{@code MICRO_OF_SECOND} - 786 * Returns a {@code LocalTime} with the nano-of-second replaced by the specified 787 * micro-of-second multiplied by 1,000. 788 * The hour, minute and second will be unchanged. 789 * <li>{@code MICRO_OF_DAY} - 790 * Returns a {@code LocalTime} with the specified micro-of-day. 791 * This completely replaces the time and is equivalent to using {@link #ofNanoOfDay(long)} 792 * with the micro-of-day multiplied by 1,000. 793 * <li>{@code MILLI_OF_SECOND} - 794 * Returns a {@code LocalTime} with the nano-of-second replaced by the specified 795 * milli-of-second multiplied by 1,000,000. 796 * The hour, minute and second will be unchanged. 797 * <li>{@code MILLI_OF_DAY} - 798 * Returns a {@code LocalTime} with the specified milli-of-day. 799 * This completely replaces the time and is equivalent to using {@link #ofNanoOfDay(long)} 800 * with the milli-of-day multiplied by 1,000,000. 801 * <li>{@code SECOND_OF_MINUTE} - 802 * Returns a {@code LocalTime} with the specified second-of-minute. 803 * The hour, minute and nano-of-second will be unchanged. 804 * <li>{@code SECOND_OF_DAY} - 805 * Returns a {@code LocalTime} with the specified second-of-day. 806 * The nano-of-second will be unchanged. 807 * <li>{@code MINUTE_OF_HOUR} - 808 * Returns a {@code LocalTime} with the specified minute-of-hour. 809 * The hour, second-of-minute and nano-of-second will be unchanged. 810 * <li>{@code MINUTE_OF_DAY} - 811 * Returns a {@code LocalTime} with the specified minute-of-day. 812 * The second-of-minute and nano-of-second will be unchanged. 813 * <li>{@code HOUR_OF_AMPM} - 814 * Returns a {@code LocalTime} with the specified hour-of-am-pm. 815 * The AM/PM, minute-of-hour, second-of-minute and nano-of-second will be unchanged. 816 * <li>{@code CLOCK_HOUR_OF_AMPM} - 817 * Returns a {@code LocalTime} with the specified clock-hour-of-am-pm. 818 * The AM/PM, minute-of-hour, second-of-minute and nano-of-second will be unchanged. 819 * <li>{@code HOUR_OF_DAY} - 820 * Returns a {@code LocalTime} with the specified hour-of-day. 821 * The minute-of-hour, second-of-minute and nano-of-second will be unchanged. 822 * <li>{@code CLOCK_HOUR_OF_DAY} - 823 * Returns a {@code LocalTime} with the specified clock-hour-of-day. 824 * The minute-of-hour, second-of-minute and nano-of-second will be unchanged. 825 * <li>{@code AMPM_OF_DAY} - 826 * Returns a {@code LocalTime} with the specified AM/PM. 827 * The hour-of-am-pm, minute-of-hour, second-of-minute and nano-of-second will be unchanged. 828 * </ul> 829 * <p> 830 * In all cases, if the new value is outside the valid range of values for the field 831 * then a {@code DateTimeException} will be thrown. 832 * <p> 833 * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}. 834 * <p> 835 * If the field is not a {@code ChronoField}, then the result of this method 836 * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)} 837 * passing {@code this} as the argument. In this case, the field determines 838 * whether and how to adjust the instant. 839 * <p> 840 * This instance is immutable and unaffected by this method call. 841 * 842 * @param field the field to set in the result, not null 843 * @param newValue the new value of the field in the result 844 * @return a {@code LocalTime} based on {@code this} with the specified field set, not null 845 * @throws DateTimeException if the field cannot be set 846 * @throws UnsupportedTemporalTypeException if the field is not supported 847 * @throws ArithmeticException if numeric overflow occurs 848 */ 849 @Override with(TemporalField field, long newValue)850 public LocalTime with(TemporalField field, long newValue) { 851 if (field instanceof ChronoField) { 852 ChronoField f = (ChronoField) field; 853 f.checkValidValue(newValue); 854 switch (f) { 855 case NANO_OF_SECOND: return withNano((int) newValue); 856 case NANO_OF_DAY: return LocalTime.ofNanoOfDay(newValue); 857 case MICRO_OF_SECOND: return withNano((int) newValue * 1000); 858 case MICRO_OF_DAY: return LocalTime.ofNanoOfDay(newValue * 1000); 859 case MILLI_OF_SECOND: return withNano((int) newValue * 1000_000); 860 case MILLI_OF_DAY: return LocalTime.ofNanoOfDay(newValue * 1000_000); 861 case SECOND_OF_MINUTE: return withSecond((int) newValue); 862 case SECOND_OF_DAY: return plusSeconds(newValue - toSecondOfDay()); 863 case MINUTE_OF_HOUR: return withMinute((int) newValue); 864 case MINUTE_OF_DAY: return plusMinutes(newValue - (hour * 60 + minute)); 865 case HOUR_OF_AMPM: return plusHours(newValue - (hour % 12)); 866 case CLOCK_HOUR_OF_AMPM: return plusHours((newValue == 12 ? 0 : newValue) - (hour % 12)); 867 case HOUR_OF_DAY: return withHour((int) newValue); 868 case CLOCK_HOUR_OF_DAY: return withHour((int) (newValue == 24 ? 0 : newValue)); 869 case AMPM_OF_DAY: return plusHours((newValue - (hour / 12)) * 12); 870 } 871 throw new UnsupportedTemporalTypeException("Unsupported field: " + field); 872 } 873 return field.adjustInto(this, newValue); 874 } 875 876 //----------------------------------------------------------------------- 877 /** 878 * Returns a copy of this {@code LocalTime} with the hour-of-day altered. 879 * <p> 880 * This instance is immutable and unaffected by this method call. 881 * 882 * @param hour the hour-of-day to set in the result, from 0 to 23 883 * @return a {@code LocalTime} based on this time with the requested hour, not null 884 * @throws DateTimeException if the hour value is invalid 885 */ withHour(int hour)886 public LocalTime withHour(int hour) { 887 if (this.hour == hour) { 888 return this; 889 } 890 HOUR_OF_DAY.checkValidValue(hour); 891 return create(hour, minute, second, nano); 892 } 893 894 /** 895 * Returns a copy of this {@code LocalTime} with the minute-of-hour altered. 896 * <p> 897 * This instance is immutable and unaffected by this method call. 898 * 899 * @param minute the minute-of-hour to set in the result, from 0 to 59 900 * @return a {@code LocalTime} based on this time with the requested minute, not null 901 * @throws DateTimeException if the minute value is invalid 902 */ withMinute(int minute)903 public LocalTime withMinute(int minute) { 904 if (this.minute == minute) { 905 return this; 906 } 907 MINUTE_OF_HOUR.checkValidValue(minute); 908 return create(hour, minute, second, nano); 909 } 910 911 /** 912 * Returns a copy of this {@code LocalTime} with the second-of-minute altered. 913 * <p> 914 * This instance is immutable and unaffected by this method call. 915 * 916 * @param second the second-of-minute to set in the result, from 0 to 59 917 * @return a {@code LocalTime} based on this time with the requested second, not null 918 * @throws DateTimeException if the second value is invalid 919 */ withSecond(int second)920 public LocalTime withSecond(int second) { 921 if (this.second == second) { 922 return this; 923 } 924 SECOND_OF_MINUTE.checkValidValue(second); 925 return create(hour, minute, second, nano); 926 } 927 928 /** 929 * Returns a copy of this {@code LocalTime} with the nano-of-second altered. 930 * <p> 931 * This instance is immutable and unaffected by this method call. 932 * 933 * @param nanoOfSecond the nano-of-second to set in the result, from 0 to 999,999,999 934 * @return a {@code LocalTime} based on this time with the requested nanosecond, not null 935 * @throws DateTimeException if the nanos value is invalid 936 */ withNano(int nanoOfSecond)937 public LocalTime withNano(int nanoOfSecond) { 938 if (this.nano == nanoOfSecond) { 939 return this; 940 } 941 NANO_OF_SECOND.checkValidValue(nanoOfSecond); 942 return create(hour, minute, second, nanoOfSecond); 943 } 944 945 //----------------------------------------------------------------------- 946 /** 947 * Returns a copy of this {@code LocalTime} with the time truncated. 948 * <p> 949 * Truncation returns a copy of the original time with fields 950 * smaller than the specified unit set to zero. 951 * For example, truncating with the {@link ChronoUnit#MINUTES minutes} unit 952 * will set the second-of-minute and nano-of-second field to zero. 953 * <p> 954 * The unit must have a {@linkplain TemporalUnit#getDuration() duration} 955 * that divides into the length of a standard day without remainder. 956 * This includes all supplied time units on {@link ChronoUnit} and 957 * {@link ChronoUnit#DAYS DAYS}. Other units throw an exception. 958 * <p> 959 * This instance is immutable and unaffected by this method call. 960 * 961 * @param unit the unit to truncate to, not null 962 * @return a {@code LocalTime} based on this time with the time truncated, not null 963 * @throws DateTimeException if unable to truncate 964 * @throws UnsupportedTemporalTypeException if the unit is not supported 965 */ truncatedTo(TemporalUnit unit)966 public LocalTime truncatedTo(TemporalUnit unit) { 967 if (unit == ChronoUnit.NANOS) { 968 return this; 969 } 970 Duration unitDur = unit.getDuration(); 971 if (unitDur.getSeconds() > SECONDS_PER_DAY) { 972 throw new UnsupportedTemporalTypeException("Unit is too large to be used for truncation"); 973 } 974 long dur = unitDur.toNanos(); 975 if ((NANOS_PER_DAY % dur) != 0) { 976 throw new UnsupportedTemporalTypeException("Unit must divide into a standard day without remainder"); 977 } 978 long nod = toNanoOfDay(); 979 return ofNanoOfDay((nod / dur) * dur); 980 } 981 982 //----------------------------------------------------------------------- 983 /** 984 * Returns a copy of this time with the specified amount added. 985 * <p> 986 * This returns a {@code LocalTime}, based on this one, with the specified amount added. 987 * The amount is typically {@link Duration} but may be any other type implementing 988 * the {@link TemporalAmount} interface. 989 * <p> 990 * The calculation is delegated to the amount object by calling 991 * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free 992 * to implement the addition in any way it wishes, however it typically 993 * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation 994 * of the amount implementation to determine if it can be successfully added. 995 * <p> 996 * This instance is immutable and unaffected by this method call. 997 * 998 * @param amountToAdd the amount to add, not null 999 * @return a {@code LocalTime} based on this time with the addition made, not null 1000 * @throws DateTimeException if the addition cannot be made 1001 * @throws ArithmeticException if numeric overflow occurs 1002 */ 1003 @Override plus(TemporalAmount amountToAdd)1004 public LocalTime plus(TemporalAmount amountToAdd) { 1005 return (LocalTime) amountToAdd.addTo(this); 1006 } 1007 1008 /** 1009 * Returns a copy of this time with the specified amount added. 1010 * <p> 1011 * This returns a {@code LocalTime}, based on this one, with the amount 1012 * in terms of the unit added. If it is not possible to add the amount, because the 1013 * unit is not supported or for some other reason, an exception is thrown. 1014 * <p> 1015 * If the field is a {@link ChronoUnit} then the addition is implemented here. 1016 * The supported fields behave as follows: 1017 * <ul> 1018 * <li>{@code NANOS} - 1019 * Returns a {@code LocalTime} with the specified number of nanoseconds added. 1020 * This is equivalent to {@link #plusNanos(long)}. 1021 * <li>{@code MICROS} - 1022 * Returns a {@code LocalTime} with the specified number of microseconds added. 1023 * This is equivalent to {@link #plusNanos(long)} with the amount 1024 * multiplied by 1,000. 1025 * <li>{@code MILLIS} - 1026 * Returns a {@code LocalTime} with the specified number of milliseconds added. 1027 * This is equivalent to {@link #plusNanos(long)} with the amount 1028 * multiplied by 1,000,000. 1029 * <li>{@code SECONDS} - 1030 * Returns a {@code LocalTime} with the specified number of seconds added. 1031 * This is equivalent to {@link #plusSeconds(long)}. 1032 * <li>{@code MINUTES} - 1033 * Returns a {@code LocalTime} with the specified number of minutes added. 1034 * This is equivalent to {@link #plusMinutes(long)}. 1035 * <li>{@code HOURS} - 1036 * Returns a {@code LocalTime} with the specified number of hours added. 1037 * This is equivalent to {@link #plusHours(long)}. 1038 * <li>{@code HALF_DAYS} - 1039 * Returns a {@code LocalTime} with the specified number of half-days added. 1040 * This is equivalent to {@link #plusHours(long)} with the amount 1041 * multiplied by 12. 1042 * </ul> 1043 * <p> 1044 * All other {@code ChronoUnit} instances will throw an {@code UnsupportedTemporalTypeException}. 1045 * <p> 1046 * If the field is not a {@code ChronoUnit}, then the result of this method 1047 * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)} 1048 * passing {@code this} as the argument. In this case, the unit determines 1049 * whether and how to perform the addition. 1050 * <p> 1051 * This instance is immutable and unaffected by this method call. 1052 * 1053 * @param amountToAdd the amount of the unit to add to the result, may be negative 1054 * @param unit the unit of the amount to add, not null 1055 * @return a {@code LocalTime} based on this time with the specified amount added, not null 1056 * @throws DateTimeException if the addition cannot be made 1057 * @throws UnsupportedTemporalTypeException if the unit is not supported 1058 * @throws ArithmeticException if numeric overflow occurs 1059 */ 1060 @Override plus(long amountToAdd, TemporalUnit unit)1061 public LocalTime plus(long amountToAdd, TemporalUnit unit) { 1062 if (unit instanceof ChronoUnit) { 1063 switch ((ChronoUnit) unit) { 1064 case NANOS: return plusNanos(amountToAdd); 1065 case MICROS: return plusNanos((amountToAdd % MICROS_PER_DAY) * 1000); 1066 case MILLIS: return plusNanos((amountToAdd % MILLIS_PER_DAY) * 1000_000); 1067 case SECONDS: return plusSeconds(amountToAdd); 1068 case MINUTES: return plusMinutes(amountToAdd); 1069 case HOURS: return plusHours(amountToAdd); 1070 case HALF_DAYS: return plusHours((amountToAdd % 2) * 12); 1071 } 1072 throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); 1073 } 1074 return unit.addTo(this, amountToAdd); 1075 } 1076 1077 //----------------------------------------------------------------------- 1078 /** 1079 * Returns a copy of this {@code LocalTime} with the specified number of hours added. 1080 * <p> 1081 * This adds the specified number of hours to this time, returning a new time. 1082 * The calculation wraps around midnight. 1083 * <p> 1084 * This instance is immutable and unaffected by this method call. 1085 * 1086 * @param hoursToAdd the hours to add, may be negative 1087 * @return a {@code LocalTime} based on this time with the hours added, not null 1088 */ plusHours(long hoursToAdd)1089 public LocalTime plusHours(long hoursToAdd) { 1090 if (hoursToAdd == 0) { 1091 return this; 1092 } 1093 int newHour = ((int) (hoursToAdd % HOURS_PER_DAY) + hour + HOURS_PER_DAY) % HOURS_PER_DAY; 1094 return create(newHour, minute, second, nano); 1095 } 1096 1097 /** 1098 * Returns a copy of this {@code LocalTime} with the specified number of minutes added. 1099 * <p> 1100 * This adds the specified number of minutes to this time, returning a new time. 1101 * The calculation wraps around midnight. 1102 * <p> 1103 * This instance is immutable and unaffected by this method call. 1104 * 1105 * @param minutesToAdd the minutes to add, may be negative 1106 * @return a {@code LocalTime} based on this time with the minutes added, not null 1107 */ plusMinutes(long minutesToAdd)1108 public LocalTime plusMinutes(long minutesToAdd) { 1109 if (minutesToAdd == 0) { 1110 return this; 1111 } 1112 int mofd = hour * MINUTES_PER_HOUR + minute; 1113 int newMofd = ((int) (minutesToAdd % MINUTES_PER_DAY) + mofd + MINUTES_PER_DAY) % MINUTES_PER_DAY; 1114 if (mofd == newMofd) { 1115 return this; 1116 } 1117 int newHour = newMofd / MINUTES_PER_HOUR; 1118 int newMinute = newMofd % MINUTES_PER_HOUR; 1119 return create(newHour, newMinute, second, nano); 1120 } 1121 1122 /** 1123 * Returns a copy of this {@code LocalTime} with the specified number of seconds added. 1124 * <p> 1125 * This adds the specified number of seconds to this time, returning a new time. 1126 * The calculation wraps around midnight. 1127 * <p> 1128 * This instance is immutable and unaffected by this method call. 1129 * 1130 * @param secondstoAdd the seconds to add, may be negative 1131 * @return a {@code LocalTime} based on this time with the seconds added, not null 1132 */ plusSeconds(long secondstoAdd)1133 public LocalTime plusSeconds(long secondstoAdd) { 1134 if (secondstoAdd == 0) { 1135 return this; 1136 } 1137 int sofd = hour * SECONDS_PER_HOUR + 1138 minute * SECONDS_PER_MINUTE + second; 1139 int newSofd = ((int) (secondstoAdd % SECONDS_PER_DAY) + sofd + SECONDS_PER_DAY) % SECONDS_PER_DAY; 1140 if (sofd == newSofd) { 1141 return this; 1142 } 1143 int newHour = newSofd / SECONDS_PER_HOUR; 1144 int newMinute = (newSofd / SECONDS_PER_MINUTE) % MINUTES_PER_HOUR; 1145 int newSecond = newSofd % SECONDS_PER_MINUTE; 1146 return create(newHour, newMinute, newSecond, nano); 1147 } 1148 1149 /** 1150 * Returns a copy of this {@code LocalTime} with the specified number of nanoseconds added. 1151 * <p> 1152 * This adds the specified number of nanoseconds to this time, returning a new time. 1153 * The calculation wraps around midnight. 1154 * <p> 1155 * This instance is immutable and unaffected by this method call. 1156 * 1157 * @param nanosToAdd the nanos to add, may be negative 1158 * @return a {@code LocalTime} based on this time with the nanoseconds added, not null 1159 */ plusNanos(long nanosToAdd)1160 public LocalTime plusNanos(long nanosToAdd) { 1161 if (nanosToAdd == 0) { 1162 return this; 1163 } 1164 long nofd = toNanoOfDay(); 1165 long newNofd = ((nanosToAdd % NANOS_PER_DAY) + nofd + NANOS_PER_DAY) % NANOS_PER_DAY; 1166 if (nofd == newNofd) { 1167 return this; 1168 } 1169 int newHour = (int) (newNofd / NANOS_PER_HOUR); 1170 int newMinute = (int) ((newNofd / NANOS_PER_MINUTE) % MINUTES_PER_HOUR); 1171 int newSecond = (int) ((newNofd / NANOS_PER_SECOND) % SECONDS_PER_MINUTE); 1172 int newNano = (int) (newNofd % NANOS_PER_SECOND); 1173 return create(newHour, newMinute, newSecond, newNano); 1174 } 1175 1176 //----------------------------------------------------------------------- 1177 /** 1178 * Returns a copy of this time with the specified amount subtracted. 1179 * <p> 1180 * This returns a {@code LocalTime}, based on this one, with the specified amount subtracted. 1181 * The amount is typically {@link Duration} but may be any other type implementing 1182 * the {@link TemporalAmount} interface. 1183 * <p> 1184 * The calculation is delegated to the amount object by calling 1185 * {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free 1186 * to implement the subtraction in any way it wishes, however it typically 1187 * calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation 1188 * of the amount implementation to determine if it can be successfully subtracted. 1189 * <p> 1190 * This instance is immutable and unaffected by this method call. 1191 * 1192 * @param amountToSubtract the amount to subtract, not null 1193 * @return a {@code LocalTime} based on this time with the subtraction made, not null 1194 * @throws DateTimeException if the subtraction cannot be made 1195 * @throws ArithmeticException if numeric overflow occurs 1196 */ 1197 @Override minus(TemporalAmount amountToSubtract)1198 public LocalTime minus(TemporalAmount amountToSubtract) { 1199 return (LocalTime) amountToSubtract.subtractFrom(this); 1200 } 1201 1202 /** 1203 * Returns a copy of this time with the specified amount subtracted. 1204 * <p> 1205 * This returns a {@code LocalTime}, based on this one, with the amount 1206 * in terms of the unit subtracted. If it is not possible to subtract the amount, 1207 * because the unit is not supported or for some other reason, an exception is thrown. 1208 * <p> 1209 * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated. 1210 * See that method for a full description of how addition, and thus subtraction, works. 1211 * <p> 1212 * This instance is immutable and unaffected by this method call. 1213 * 1214 * @param amountToSubtract the amount of the unit to subtract from the result, may be negative 1215 * @param unit the unit of the amount to subtract, not null 1216 * @return a {@code LocalTime} based on this time with the specified amount subtracted, not null 1217 * @throws DateTimeException if the subtraction cannot be made 1218 * @throws UnsupportedTemporalTypeException if the unit is not supported 1219 * @throws ArithmeticException if numeric overflow occurs 1220 */ 1221 @Override minus(long amountToSubtract, TemporalUnit unit)1222 public LocalTime minus(long amountToSubtract, TemporalUnit unit) { 1223 return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); 1224 } 1225 1226 //----------------------------------------------------------------------- 1227 /** 1228 * Returns a copy of this {@code LocalTime} with the specified number of hours subtracted. 1229 * <p> 1230 * This subtracts the specified number of hours from this time, returning a new time. 1231 * The calculation wraps around midnight. 1232 * <p> 1233 * This instance is immutable and unaffected by this method call. 1234 * 1235 * @param hoursToSubtract the hours to subtract, may be negative 1236 * @return a {@code LocalTime} based on this time with the hours subtracted, not null 1237 */ minusHours(long hoursToSubtract)1238 public LocalTime minusHours(long hoursToSubtract) { 1239 return plusHours(-(hoursToSubtract % HOURS_PER_DAY)); 1240 } 1241 1242 /** 1243 * Returns a copy of this {@code LocalTime} with the specified number of minutes subtracted. 1244 * <p> 1245 * This subtracts the specified number of minutes from this time, returning a new time. 1246 * The calculation wraps around midnight. 1247 * <p> 1248 * This instance is immutable and unaffected by this method call. 1249 * 1250 * @param minutesToSubtract the minutes to subtract, may be negative 1251 * @return a {@code LocalTime} based on this time with the minutes subtracted, not null 1252 */ minusMinutes(long minutesToSubtract)1253 public LocalTime minusMinutes(long minutesToSubtract) { 1254 return plusMinutes(-(minutesToSubtract % MINUTES_PER_DAY)); 1255 } 1256 1257 /** 1258 * Returns a copy of this {@code LocalTime} with the specified number of seconds subtracted. 1259 * <p> 1260 * This subtracts the specified number of seconds from this time, returning a new time. 1261 * The calculation wraps around midnight. 1262 * <p> 1263 * This instance is immutable and unaffected by this method call. 1264 * 1265 * @param secondsToSubtract the seconds to subtract, may be negative 1266 * @return a {@code LocalTime} based on this time with the seconds subtracted, not null 1267 */ minusSeconds(long secondsToSubtract)1268 public LocalTime minusSeconds(long secondsToSubtract) { 1269 return plusSeconds(-(secondsToSubtract % SECONDS_PER_DAY)); 1270 } 1271 1272 /** 1273 * Returns a copy of this {@code LocalTime} with the specified number of nanoseconds subtracted. 1274 * <p> 1275 * This subtracts the specified number of nanoseconds from this time, returning a new time. 1276 * The calculation wraps around midnight. 1277 * <p> 1278 * This instance is immutable and unaffected by this method call. 1279 * 1280 * @param nanosToSubtract the nanos to subtract, may be negative 1281 * @return a {@code LocalTime} based on this time with the nanoseconds subtracted, not null 1282 */ minusNanos(long nanosToSubtract)1283 public LocalTime minusNanos(long nanosToSubtract) { 1284 return plusNanos(-(nanosToSubtract % NANOS_PER_DAY)); 1285 } 1286 1287 //----------------------------------------------------------------------- 1288 /** 1289 * Queries this time using the specified query. 1290 * <p> 1291 * This queries this time using the specified query strategy object. 1292 * The {@code TemporalQuery} object defines the logic to be used to 1293 * obtain the result. Read the documentation of the query to understand 1294 * what the result of this method will be. 1295 * <p> 1296 * The result of this method is obtained by invoking the 1297 * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the 1298 * specified query passing {@code this} as the argument. 1299 * 1300 * @param <R> the type of the result 1301 * @param query the query to invoke, not null 1302 * @return the query result, null may be returned (defined by the query) 1303 * @throws DateTimeException if unable to query (defined by the query) 1304 * @throws ArithmeticException if numeric overflow occurs (defined by the query) 1305 */ 1306 @SuppressWarnings("unchecked") 1307 @Override query(TemporalQuery<R> query)1308 public <R> R query(TemporalQuery<R> query) { 1309 if (query == TemporalQueries.chronology() || query == TemporalQueries.zoneId() || 1310 query == TemporalQueries.zone() || query == TemporalQueries.offset()) { 1311 return null; 1312 } else if (query == TemporalQueries.localTime()) { 1313 return (R) this; 1314 } else if (query == TemporalQueries.localDate()) { 1315 return null; 1316 } else if (query == TemporalQueries.precision()) { 1317 return (R) NANOS; 1318 } 1319 // inline TemporalAccessor.super.query(query) as an optimization 1320 // non-JDK classes are not permitted to make this optimization 1321 return query.queryFrom(this); 1322 } 1323 1324 /** 1325 * Adjusts the specified temporal object to have the same time as this object. 1326 * <p> 1327 * This returns a temporal object of the same observable type as the input 1328 * with the time changed to be the same as this. 1329 * <p> 1330 * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)} 1331 * passing {@link ChronoField#NANO_OF_DAY} as the field. 1332 * <p> 1333 * In most cases, it is clearer to reverse the calling pattern by using 1334 * {@link Temporal#with(TemporalAdjuster)}: 1335 * <pre> 1336 * // these two lines are equivalent, but the second approach is recommended 1337 * temporal = thisLocalTime.adjustInto(temporal); 1338 * temporal = temporal.with(thisLocalTime); 1339 * </pre> 1340 * <p> 1341 * This instance is immutable and unaffected by this method call. 1342 * 1343 * @param temporal the target object to be adjusted, not null 1344 * @return the adjusted object, not null 1345 * @throws DateTimeException if unable to make the adjustment 1346 * @throws ArithmeticException if numeric overflow occurs 1347 */ 1348 @Override adjustInto(Temporal temporal)1349 public Temporal adjustInto(Temporal temporal) { 1350 return temporal.with(NANO_OF_DAY, toNanoOfDay()); 1351 } 1352 1353 /** 1354 * Calculates the amount of time until another time in terms of the specified unit. 1355 * <p> 1356 * This calculates the amount of time between two {@code LocalTime} 1357 * objects in terms of a single {@code TemporalUnit}. 1358 * The start and end points are {@code this} and the specified time. 1359 * The result will be negative if the end is before the start. 1360 * The {@code Temporal} passed to this method is converted to a 1361 * {@code LocalTime} using {@link #from(TemporalAccessor)}. 1362 * For example, the amount in hours between two times can be calculated 1363 * using {@code startTime.until(endTime, HOURS)}. 1364 * <p> 1365 * The calculation returns a whole number, representing the number of 1366 * complete units between the two times. 1367 * For example, the amount in hours between 11:30 and 13:29 will only 1368 * be one hour as it is one minute short of two hours. 1369 * <p> 1370 * There are two equivalent ways of using this method. 1371 * The first is to invoke this method. 1372 * The second is to use {@link TemporalUnit#between(Temporal, Temporal)}: 1373 * <pre> 1374 * // these two lines are equivalent 1375 * amount = start.until(end, MINUTES); 1376 * amount = MINUTES.between(start, end); 1377 * </pre> 1378 * The choice should be made based on which makes the code more readable. 1379 * <p> 1380 * The calculation is implemented in this method for {@link ChronoUnit}. 1381 * The units {@code NANOS}, {@code MICROS}, {@code MILLIS}, {@code SECONDS}, 1382 * {@code MINUTES}, {@code HOURS} and {@code HALF_DAYS} are supported. 1383 * Other {@code ChronoUnit} values will throw an exception. 1384 * <p> 1385 * If the unit is not a {@code ChronoUnit}, then the result of this method 1386 * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} 1387 * passing {@code this} as the first argument and the converted input temporal 1388 * as the second argument. 1389 * <p> 1390 * This instance is immutable and unaffected by this method call. 1391 * 1392 * @param endExclusive the end time, exclusive, which is converted to a {@code LocalTime}, not null 1393 * @param unit the unit to measure the amount in, not null 1394 * @return the amount of time between this time and the end time 1395 * @throws DateTimeException if the amount cannot be calculated, or the end 1396 * temporal cannot be converted to a {@code LocalTime} 1397 * @throws UnsupportedTemporalTypeException if the unit is not supported 1398 * @throws ArithmeticException if numeric overflow occurs 1399 */ 1400 @Override until(Temporal endExclusive, TemporalUnit unit)1401 public long until(Temporal endExclusive, TemporalUnit unit) { 1402 LocalTime end = LocalTime.from(endExclusive); 1403 if (unit instanceof ChronoUnit) { 1404 long nanosUntil = end.toNanoOfDay() - toNanoOfDay(); // no overflow 1405 switch ((ChronoUnit) unit) { 1406 case NANOS: return nanosUntil; 1407 case MICROS: return nanosUntil / 1000; 1408 case MILLIS: return nanosUntil / 1000_000; 1409 case SECONDS: return nanosUntil / NANOS_PER_SECOND; 1410 case MINUTES: return nanosUntil / NANOS_PER_MINUTE; 1411 case HOURS: return nanosUntil / NANOS_PER_HOUR; 1412 case HALF_DAYS: return nanosUntil / (12 * NANOS_PER_HOUR); 1413 } 1414 throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit); 1415 } 1416 return unit.between(this, end); 1417 } 1418 1419 /** 1420 * Formats this time using the specified formatter. 1421 * <p> 1422 * This time will be passed to the formatter to produce a string. 1423 * 1424 * @param formatter the formatter to use, not null 1425 * @return the formatted time string, not null 1426 * @throws DateTimeException if an error occurs during printing 1427 */ format(DateTimeFormatter formatter)1428 public String format(DateTimeFormatter formatter) { 1429 Objects.requireNonNull(formatter, "formatter"); 1430 return formatter.format(this); 1431 } 1432 1433 //----------------------------------------------------------------------- 1434 /** 1435 * Combines this time with a date to create a {@code LocalDateTime}. 1436 * <p> 1437 * This returns a {@code LocalDateTime} formed from this time at the specified date. 1438 * All possible combinations of date and time are valid. 1439 * 1440 * @param date the date to combine with, not null 1441 * @return the local date-time formed from this time and the specified date, not null 1442 */ atDate(LocalDate date)1443 public LocalDateTime atDate(LocalDate date) { 1444 return LocalDateTime.of(date, this); 1445 } 1446 1447 /** 1448 * Combines this time with an offset to create an {@code OffsetTime}. 1449 * <p> 1450 * This returns an {@code OffsetTime} formed from this time at the specified offset. 1451 * All possible combinations of time and offset are valid. 1452 * 1453 * @param offset the offset to combine with, not null 1454 * @return the offset time formed from this time and the specified offset, not null 1455 */ atOffset(ZoneOffset offset)1456 public OffsetTime atOffset(ZoneOffset offset) { 1457 return OffsetTime.of(this, offset); 1458 } 1459 1460 //----------------------------------------------------------------------- 1461 /** 1462 * Extracts the time as seconds of day, 1463 * from {@code 0} to {@code 24 * 60 * 60 - 1}. 1464 * 1465 * @return the second-of-day equivalent to this time 1466 */ toSecondOfDay()1467 public int toSecondOfDay() { 1468 int total = hour * SECONDS_PER_HOUR; 1469 total += minute * SECONDS_PER_MINUTE; 1470 total += second; 1471 return total; 1472 } 1473 1474 /** 1475 * Extracts the time as nanos of day, 1476 * from {@code 0} to {@code 24 * 60 * 60 * 1,000,000,000 - 1}. 1477 * 1478 * @return the nano of day equivalent to this time 1479 */ toNanoOfDay()1480 public long toNanoOfDay() { 1481 long total = hour * NANOS_PER_HOUR; 1482 total += minute * NANOS_PER_MINUTE; 1483 total += second * NANOS_PER_SECOND; 1484 total += nano; 1485 return total; 1486 } 1487 1488 /** 1489 * Converts this {@code LocalTime} to the number of seconds since the epoch 1490 * of 1970-01-01T00:00:00Z. 1491 * <p> 1492 * This combines this local time with the specified date and 1493 * offset to calculate the epoch-second value, which is the 1494 * number of elapsed seconds from 1970-01-01T00:00:00Z. 1495 * Instants on the time-line after the epoch are positive, earlier 1496 * are negative. 1497 * 1498 * @param date the local date, not null 1499 * @param offset the zone offset, not null 1500 * @return the number of seconds since the epoch of 1970-01-01T00:00:00Z, may be negative 1501 * @since 9 1502 */ toEpochSecond(LocalDate date, ZoneOffset offset)1503 public long toEpochSecond(LocalDate date, ZoneOffset offset) { 1504 Objects.requireNonNull(date, "date"); 1505 Objects.requireNonNull(offset, "offset"); 1506 long epochDay = date.toEpochDay(); 1507 long secs = epochDay * 86400 + toSecondOfDay(); 1508 secs -= offset.getTotalSeconds(); 1509 return secs; 1510 } 1511 1512 //----------------------------------------------------------------------- 1513 /** 1514 * Compares this time to another time. 1515 * <p> 1516 * The comparison is based on the time-line position of the local times within a day. 1517 * It is "consistent with equals", as defined by {@link Comparable}. 1518 * 1519 * @param other the other time to compare to, not null 1520 * @return the comparator value, negative if less, positive if greater 1521 * @throws NullPointerException if {@code other} is null 1522 */ 1523 @Override compareTo(LocalTime other)1524 public int compareTo(LocalTime other) { 1525 int cmp = Integer.compare(hour, other.hour); 1526 if (cmp == 0) { 1527 cmp = Integer.compare(minute, other.minute); 1528 if (cmp == 0) { 1529 cmp = Integer.compare(second, other.second); 1530 if (cmp == 0) { 1531 cmp = Integer.compare(nano, other.nano); 1532 } 1533 } 1534 } 1535 return cmp; 1536 } 1537 1538 /** 1539 * Checks if this time is after the specified time. 1540 * <p> 1541 * The comparison is based on the time-line position of the time within a day. 1542 * 1543 * @param other the other time to compare to, not null 1544 * @return true if this is after the specified time 1545 * @throws NullPointerException if {@code other} is null 1546 */ isAfter(LocalTime other)1547 public boolean isAfter(LocalTime other) { 1548 return compareTo(other) > 0; 1549 } 1550 1551 /** 1552 * Checks if this time is before the specified time. 1553 * <p> 1554 * The comparison is based on the time-line position of the time within a day. 1555 * 1556 * @param other the other time to compare to, not null 1557 * @return true if this point is before the specified time 1558 * @throws NullPointerException if {@code other} is null 1559 */ isBefore(LocalTime other)1560 public boolean isBefore(LocalTime other) { 1561 return compareTo(other) < 0; 1562 } 1563 1564 //----------------------------------------------------------------------- 1565 /** 1566 * Checks if this time is equal to another time. 1567 * <p> 1568 * The comparison is based on the time-line position of the time within a day. 1569 * <p> 1570 * Only objects of type {@code LocalTime} are compared, other types return false. 1571 * To compare the date of two {@code TemporalAccessor} instances, use 1572 * {@link ChronoField#NANO_OF_DAY} as a comparator. 1573 * 1574 * @param obj the object to check, null returns false 1575 * @return true if this is equal to the other time 1576 */ 1577 @Override equals(Object obj)1578 public boolean equals(Object obj) { 1579 if (this == obj) { 1580 return true; 1581 } 1582 if (obj instanceof LocalTime) { 1583 LocalTime other = (LocalTime) obj; 1584 return hour == other.hour && minute == other.minute && 1585 second == other.second && nano == other.nano; 1586 } 1587 return false; 1588 } 1589 1590 /** 1591 * A hash code for this time. 1592 * 1593 * @return a suitable hash code 1594 */ 1595 @Override hashCode()1596 public int hashCode() { 1597 long nod = toNanoOfDay(); 1598 return (int) (nod ^ (nod >>> 32)); 1599 } 1600 1601 //----------------------------------------------------------------------- 1602 /** 1603 * Outputs this time as a {@code String}, such as {@code 10:15}. 1604 * <p> 1605 * The output will be one of the following ISO-8601 formats: 1606 * <ul> 1607 * <li>{@code HH:mm}</li> 1608 * <li>{@code HH:mm:ss}</li> 1609 * <li>{@code HH:mm:ss.SSS}</li> 1610 * <li>{@code HH:mm:ss.SSSSSS}</li> 1611 * <li>{@code HH:mm:ss.SSSSSSSSS}</li> 1612 * </ul> 1613 * The format used will be the shortest that outputs the full value of 1614 * the time where the omitted parts are implied to be zero. 1615 * 1616 * @return a string representation of this time, not null 1617 */ 1618 @Override toString()1619 public String toString() { 1620 StringBuilder buf = new StringBuilder(18); 1621 int hourValue = hour; 1622 int minuteValue = minute; 1623 int secondValue = second; 1624 int nanoValue = nano; 1625 buf.append(hourValue < 10 ? "0" : "").append(hourValue) 1626 .append(minuteValue < 10 ? ":0" : ":").append(minuteValue); 1627 if (secondValue > 0 || nanoValue > 0) { 1628 buf.append(secondValue < 10 ? ":0" : ":").append(secondValue); 1629 if (nanoValue > 0) { 1630 buf.append('.'); 1631 if (nanoValue % 1000_000 == 0) { 1632 buf.append(Integer.toString((nanoValue / 1000_000) + 1000).substring(1)); 1633 } else if (nanoValue % 1000 == 0) { 1634 buf.append(Integer.toString((nanoValue / 1000) + 1000_000).substring(1)); 1635 } else { 1636 buf.append(Integer.toString((nanoValue) + 1000_000_000).substring(1)); 1637 } 1638 } 1639 } 1640 return buf.toString(); 1641 } 1642 1643 //----------------------------------------------------------------------- 1644 /** 1645 * Writes the object using a 1646 * <a href="../../serialized-form.html#java.time.Ser">dedicated serialized form</a>. 1647 * @serialData 1648 * A twos-complement value indicates the remaining values are not in the stream 1649 * and should be set to zero. 1650 * <pre> 1651 * out.writeByte(4); // identifies a LocalTime 1652 * if (nano == 0) { 1653 * if (second == 0) { 1654 * if (minute == 0) { 1655 * out.writeByte(~hour); 1656 * } else { 1657 * out.writeByte(hour); 1658 * out.writeByte(~minute); 1659 * } 1660 * } else { 1661 * out.writeByte(hour); 1662 * out.writeByte(minute); 1663 * out.writeByte(~second); 1664 * } 1665 * } else { 1666 * out.writeByte(hour); 1667 * out.writeByte(minute); 1668 * out.writeByte(second); 1669 * out.writeInt(nano); 1670 * } 1671 * </pre> 1672 * 1673 * @return the instance of {@code Ser}, not null 1674 */ writeReplace()1675 private Object writeReplace() { 1676 return new Ser(Ser.LOCAL_TIME_TYPE, this); 1677 } 1678 1679 /** 1680 * Defend against malicious streams. 1681 * 1682 * @param s the stream to read 1683 * @throws InvalidObjectException always 1684 */ readObject(ObjectInputStream s)1685 private void readObject(ObjectInputStream s) throws InvalidObjectException { 1686 throw new InvalidObjectException("Deserialization via serialization delegate"); 1687 } 1688 writeExternal(DataOutput out)1689 void writeExternal(DataOutput out) throws IOException { 1690 if (nano == 0) { 1691 if (second == 0) { 1692 if (minute == 0) { 1693 out.writeByte(~hour); 1694 } else { 1695 out.writeByte(hour); 1696 out.writeByte(~minute); 1697 } 1698 } else { 1699 out.writeByte(hour); 1700 out.writeByte(minute); 1701 out.writeByte(~second); 1702 } 1703 } else { 1704 out.writeByte(hour); 1705 out.writeByte(minute); 1706 out.writeByte(second); 1707 out.writeInt(nano); 1708 } 1709 } 1710 readExternal(DataInput in)1711 static LocalTime readExternal(DataInput in) throws IOException { 1712 int hour = in.readByte(); 1713 int minute = 0; 1714 int second = 0; 1715 int nano = 0; 1716 if (hour < 0) { 1717 hour = ~hour; 1718 } else { 1719 minute = in.readByte(); 1720 if (minute < 0) { 1721 minute = ~minute; 1722 } else { 1723 second = in.readByte(); 1724 if (second < 0) { 1725 second = ~second; 1726 } else { 1727 nano = in.readInt(); 1728 } 1729 } 1730 } 1731 return LocalTime.of(hour, minute, second, nano); 1732 } 1733 1734 } 1735