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