Path: blob/master/src/java.base/share/classes/java/time/LocalTime.java
41152 views
/*1* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425/*26* This file is available under and governed by the GNU General Public27* License version 2 only, as published by the Free Software Foundation.28* However, the following notice accompanied the original version of this29* file:30*31* Copyright (c) 2007-2012, Stephen Colebourne & Michael Nascimento Santos32*33* All rights reserved.34*35* Redistribution and use in source and binary forms, with or without36* modification, are permitted provided that the following conditions are met:37*38* * Redistributions of source code must retain the above copyright notice,39* this list of conditions and the following disclaimer.40*41* * Redistributions in binary form must reproduce the above copyright notice,42* this list of conditions and the following disclaimer in the documentation43* and/or other materials provided with the distribution.44*45* * Neither the name of JSR-310 nor the names of its contributors46* may be used to endorse or promote products derived from this software47* without specific prior written permission.48*49* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS50* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT51* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR52* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR53* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,54* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,55* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR56* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF57* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING58* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS59* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.60*/61package java.time;6263import static java.time.temporal.ChronoField.HOUR_OF_DAY;64import static java.time.temporal.ChronoField.MICRO_OF_DAY;65import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;66import static java.time.temporal.ChronoField.NANO_OF_DAY;67import static java.time.temporal.ChronoField.NANO_OF_SECOND;68import static java.time.temporal.ChronoField.SECOND_OF_DAY;69import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;70import static java.time.temporal.ChronoUnit.NANOS;7172import java.io.DataInput;73import java.io.DataOutput;74import java.io.IOException;75import java.io.InvalidObjectException;76import java.io.ObjectInputStream;77import java.io.Serializable;78import java.time.format.DateTimeFormatter;79import java.time.format.DateTimeParseException;80import java.time.temporal.ChronoField;81import java.time.temporal.ChronoUnit;82import java.time.temporal.Temporal;83import java.time.temporal.TemporalAccessor;84import java.time.temporal.TemporalAdjuster;85import java.time.temporal.TemporalAmount;86import java.time.temporal.TemporalField;87import java.time.temporal.TemporalQueries;88import java.time.temporal.TemporalQuery;89import java.time.temporal.TemporalUnit;90import java.time.temporal.UnsupportedTemporalTypeException;91import java.time.temporal.ValueRange;92import java.util.Objects;9394/**95* A time without a time-zone in the ISO-8601 calendar system,96* such as {@code 10:15:30}.97* <p>98* {@code LocalTime} is an immutable date-time object that represents a time,99* often viewed as hour-minute-second.100* Time is represented to nanosecond precision.101* For example, the value "13:45.30.123456789" can be stored in a {@code LocalTime}.102* <p>103* This class does not store or represent a date or time-zone.104* Instead, it is a description of the local time as seen on a wall clock.105* It cannot represent an instant on the time-line without additional information106* such as an offset or time-zone.107* <p>108* The ISO-8601 calendar system is the modern civil calendar system used today109* in most of the world. This API assumes that all calendar systems use the same110* representation, this class, for time-of-day.111* <p>112* This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>113* class; programmers should treat instances that are114* {@linkplain #equals(Object) equal} as interchangeable and should not115* use instances for synchronization, or unpredictable behavior may116* occur. For example, in a future release, synchronization may fail.117* The {@code equals} method should be used for comparisons.118*119* @implSpec120* This class is immutable and thread-safe.121*122* @since 1.8123*/124@jdk.internal.ValueBased125public final class LocalTime126implements Temporal, TemporalAdjuster, Comparable<LocalTime>, Serializable {127128/**129* The minimum supported {@code LocalTime}, '00:00'.130* This is the time of midnight at the start of the day.131*/132public 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*/137public static final LocalTime MAX;138/**139* The time of midnight at the start of the day, '00:00'.140*/141public static final LocalTime MIDNIGHT;142/**143* The time of noon in the middle of the day, '12:00'.144*/145public static final LocalTime NOON;146/**147* Constants for the local time of each hour.148*/149private static final LocalTime[] HOURS = new LocalTime[24];150static {151for (int i = 0; i < HOURS.length; i++) {152HOURS[i] = new LocalTime(i, 0, 0, 0);153}154MIDNIGHT = HOURS[0];155NOON = HOURS[12];156MIN = HOURS[0];157MAX = new LocalTime(23, 59, 59, 999_999_999);158}159160/**161* Hours per day.162*/163static final int HOURS_PER_DAY = 24;164/**165* Minutes per hour.166*/167static final int MINUTES_PER_HOUR = 60;168/**169* Minutes per day.170*/171static final int MINUTES_PER_DAY = MINUTES_PER_HOUR * HOURS_PER_DAY;172/**173* Seconds per minute.174*/175static final int SECONDS_PER_MINUTE = 60;176/**177* Seconds per hour.178*/179static final int SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;180/**181* Seconds per day.182*/183static final int SECONDS_PER_DAY = SECONDS_PER_HOUR * HOURS_PER_DAY;184/**185* Milliseconds per day.186*/187static final long MILLIS_PER_DAY = SECONDS_PER_DAY * 1000L;188/**189* Microseconds per day.190*/191static final long MICROS_PER_DAY = SECONDS_PER_DAY * 1000_000L;192/**193* Nanos per millisecond.194*/195static final long NANOS_PER_MILLI = 1000_000L;196/**197* Nanos per second.198*/199static final long NANOS_PER_SECOND = 1000_000_000L;200/**201* Nanos per minute.202*/203static final long NANOS_PER_MINUTE = NANOS_PER_SECOND * SECONDS_PER_MINUTE;204/**205* Nanos per hour.206*/207static final long NANOS_PER_HOUR = NANOS_PER_MINUTE * MINUTES_PER_HOUR;208/**209* Nanos per day.210*/211static final long NANOS_PER_DAY = NANOS_PER_HOUR * HOURS_PER_DAY;212213/**214* Serialization version.215*/216@java.io.Serial217private static final long serialVersionUID = 6414437269572265201L;218219/**220* The hour.221*/222private final byte hour;223/**224* The minute.225*/226private final byte minute;227/**228* The second.229*/230private final byte second;231/**232* The nanosecond.233*/234private final int nano;235236//-----------------------------------------------------------------------237/**238* Obtains the current time from the system clock in the default time-zone.239* <p>240* This will query the {@link Clock#systemDefaultZone() system clock} in the default241* time-zone to obtain the current time.242* <p>243* Using this method will prevent the ability to use an alternate clock for testing244* because the clock is hard-coded.245*246* @return the current time using the system clock and default time-zone, not null247*/248public static LocalTime now() {249return now(Clock.systemDefaultZone());250}251252/**253* Obtains the current time from the system clock in the specified time-zone.254* <p>255* This will query the {@link Clock#system(ZoneId) system clock} to obtain the current time.256* Specifying the time-zone avoids dependence on the default time-zone.257* <p>258* Using this method will prevent the ability to use an alternate clock for testing259* because the clock is hard-coded.260*261* @param zone the zone ID to use, not null262* @return the current time using the system clock, not null263*/264public static LocalTime now(ZoneId zone) {265return now(Clock.system(zone));266}267268/**269* Obtains the current time from the specified clock.270* <p>271* This will query the specified clock to obtain the current time.272* Using this method allows the use of an alternate clock for testing.273* The alternate clock may be introduced using {@link Clock dependency injection}.274*275* @param clock the clock to use, not null276* @return the current time, not null277*/278public static LocalTime now(Clock clock) {279Objects.requireNonNull(clock, "clock");280final Instant now = clock.instant(); // called once281return ofInstant(now, clock.getZone());282}283284//-----------------------------------------------------------------------285/**286* Obtains an instance of {@code LocalTime} from an hour and minute.287* <p>288* This returns a {@code LocalTime} with the specified hour and minute.289* The second and nanosecond fields will be set to zero.290*291* @param hour the hour-of-day to represent, from 0 to 23292* @param minute the minute-of-hour to represent, from 0 to 59293* @return the local time, not null294* @throws DateTimeException if the value of any field is out of range295*/296public static LocalTime of(int hour, int minute) {297HOUR_OF_DAY.checkValidValue(hour);298if (minute == 0) {299return HOURS[hour]; // for performance300}301MINUTE_OF_HOUR.checkValidValue(minute);302return new LocalTime(hour, minute, 0, 0);303}304305/**306* Obtains an instance of {@code LocalTime} from an hour, minute and second.307* <p>308* This returns a {@code LocalTime} with the specified hour, minute and second.309* The nanosecond field will be set to zero.310*311* @param hour the hour-of-day to represent, from 0 to 23312* @param minute the minute-of-hour to represent, from 0 to 59313* @param second the second-of-minute to represent, from 0 to 59314* @return the local time, not null315* @throws DateTimeException if the value of any field is out of range316*/317public static LocalTime of(int hour, int minute, int second) {318HOUR_OF_DAY.checkValidValue(hour);319if ((minute | second) == 0) {320return HOURS[hour]; // for performance321}322MINUTE_OF_HOUR.checkValidValue(minute);323SECOND_OF_MINUTE.checkValidValue(second);324return new LocalTime(hour, minute, second, 0);325}326327/**328* Obtains an instance of {@code LocalTime} from an hour, minute, second and nanosecond.329* <p>330* This returns a {@code LocalTime} with the specified hour, minute, second and nanosecond.331*332* @param hour the hour-of-day to represent, from 0 to 23333* @param minute the minute-of-hour to represent, from 0 to 59334* @param second the second-of-minute to represent, from 0 to 59335* @param nanoOfSecond the nano-of-second to represent, from 0 to 999,999,999336* @return the local time, not null337* @throws DateTimeException if the value of any field is out of range338*/339public static LocalTime of(int hour, int minute, int second, int nanoOfSecond) {340HOUR_OF_DAY.checkValidValue(hour);341MINUTE_OF_HOUR.checkValidValue(minute);342SECOND_OF_MINUTE.checkValidValue(second);343NANO_OF_SECOND.checkValidValue(nanoOfSecond);344return create(hour, minute, second, nanoOfSecond);345}346347/**348* Obtains an instance of {@code LocalTime} from an {@code Instant} and zone ID.349* <p>350* This creates a local time based on the specified instant.351* First, the offset from UTC/Greenwich is obtained using the zone ID and instant,352* which is simple as there is only one valid offset for each instant.353* Then, the instant and offset are used to calculate the local time.354*355* @param instant the instant to create the time from, not null356* @param zone the time-zone, which may be an offset, not null357* @return the local time, not null358* @since 9359*/360public static LocalTime ofInstant(Instant instant, ZoneId zone) {361Objects.requireNonNull(instant, "instant");362Objects.requireNonNull(zone, "zone");363ZoneOffset offset = zone.getRules().getOffset(instant);364long localSecond = instant.getEpochSecond() + offset.getTotalSeconds();365int secsOfDay = Math.floorMod(localSecond, SECONDS_PER_DAY);366return ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + instant.getNano());367}368369//-----------------------------------------------------------------------370/**371* Obtains an instance of {@code LocalTime} from a second-of-day value.372* <p>373* This returns a {@code LocalTime} with the specified second-of-day.374* The nanosecond field will be set to zero.375*376* @param secondOfDay the second-of-day, from {@code 0} to {@code 24 * 60 * 60 - 1}377* @return the local time, not null378* @throws DateTimeException if the second-of-day value is invalid379*/380public static LocalTime ofSecondOfDay(long secondOfDay) {381SECOND_OF_DAY.checkValidValue(secondOfDay);382int hours = (int) (secondOfDay / SECONDS_PER_HOUR);383secondOfDay -= hours * SECONDS_PER_HOUR;384int minutes = (int) (secondOfDay / SECONDS_PER_MINUTE);385secondOfDay -= minutes * SECONDS_PER_MINUTE;386return create(hours, minutes, (int) secondOfDay, 0);387}388389/**390* Obtains an instance of {@code LocalTime} from a nanos-of-day value.391* <p>392* This returns a {@code LocalTime} with the specified nanosecond-of-day.393*394* @param nanoOfDay the nano of day, from {@code 0} to {@code 24 * 60 * 60 * 1,000,000,000 - 1}395* @return the local time, not null396* @throws DateTimeException if the nanos of day value is invalid397*/398public static LocalTime ofNanoOfDay(long nanoOfDay) {399NANO_OF_DAY.checkValidValue(nanoOfDay);400int hours = (int) (nanoOfDay / NANOS_PER_HOUR);401nanoOfDay -= hours * NANOS_PER_HOUR;402int minutes = (int) (nanoOfDay / NANOS_PER_MINUTE);403nanoOfDay -= minutes * NANOS_PER_MINUTE;404int seconds = (int) (nanoOfDay / NANOS_PER_SECOND);405nanoOfDay -= seconds * NANOS_PER_SECOND;406return create(hours, minutes, seconds, (int) nanoOfDay);407}408409//-----------------------------------------------------------------------410/**411* Obtains an instance of {@code LocalTime} from a temporal object.412* <p>413* This obtains a local time based on the specified temporal.414* A {@code TemporalAccessor} represents an arbitrary set of date and time information,415* which this factory converts to an instance of {@code LocalTime}.416* <p>417* The conversion uses the {@link TemporalQueries#localTime()} query, which relies418* on extracting the {@link ChronoField#NANO_OF_DAY NANO_OF_DAY} field.419* <p>420* This method matches the signature of the functional interface {@link TemporalQuery}421* allowing it to be used as a query via method reference, {@code LocalTime::from}.422*423* @param temporal the temporal object to convert, not null424* @return the local time, not null425* @throws DateTimeException if unable to convert to a {@code LocalTime}426*/427public static LocalTime from(TemporalAccessor temporal) {428Objects.requireNonNull(temporal, "temporal");429LocalTime time = temporal.query(TemporalQueries.localTime());430if (time == null) {431throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: " +432temporal + " of type " + temporal.getClass().getName());433}434return time;435}436437//-----------------------------------------------------------------------438/**439* Obtains an instance of {@code LocalTime} from a text string such as {@code 10:15}.440* <p>441* The string must represent a valid time and is parsed using442* {@link java.time.format.DateTimeFormatter#ISO_LOCAL_TIME}.443*444* @param text the text to parse such as "10:15:30", not null445* @return the parsed local time, not null446* @throws DateTimeParseException if the text cannot be parsed447*/448public static LocalTime parse(CharSequence text) {449return parse(text, DateTimeFormatter.ISO_LOCAL_TIME);450}451452/**453* Obtains an instance of {@code LocalTime} from a text string using a specific formatter.454* <p>455* The text is parsed using the formatter, returning a time.456*457* @param text the text to parse, not null458* @param formatter the formatter to use, not null459* @return the parsed local time, not null460* @throws DateTimeParseException if the text cannot be parsed461*/462public static LocalTime parse(CharSequence text, DateTimeFormatter formatter) {463Objects.requireNonNull(formatter, "formatter");464return formatter.parse(text, LocalTime::from);465}466467//-----------------------------------------------------------------------468/**469* Creates a local time from the hour, minute, second and nanosecond fields.470* <p>471* This factory may return a cached value, but applications must not rely on this.472*473* @param hour the hour-of-day to represent, validated from 0 to 23474* @param minute the minute-of-hour to represent, validated from 0 to 59475* @param second the second-of-minute to represent, validated from 0 to 59476* @param nanoOfSecond the nano-of-second to represent, validated from 0 to 999,999,999477* @return the local time, not null478*/479private static LocalTime create(int hour, int minute, int second, int nanoOfSecond) {480if ((minute | second | nanoOfSecond) == 0) {481return HOURS[hour];482}483return new LocalTime(hour, minute, second, nanoOfSecond);484}485486/**487* Constructor, previously validated.488*489* @param hour the hour-of-day to represent, validated from 0 to 23490* @param minute the minute-of-hour to represent, validated from 0 to 59491* @param second the second-of-minute to represent, validated from 0 to 59492* @param nanoOfSecond the nano-of-second to represent, validated from 0 to 999,999,999493*/494private LocalTime(int hour, int minute, int second, int nanoOfSecond) {495this.hour = (byte) hour;496this.minute = (byte) minute;497this.second = (byte) second;498this.nano = nanoOfSecond;499}500501//-----------------------------------------------------------------------502/**503* Checks if the specified field is supported.504* <p>505* This checks if this time can be queried for the specified field.506* If false, then calling the {@link #range(TemporalField) range},507* {@link #get(TemporalField) get} and {@link #with(TemporalField, long)}508* methods will throw an exception.509* <p>510* If the field is a {@link ChronoField} then the query is implemented here.511* The supported fields are:512* <ul>513* <li>{@code NANO_OF_SECOND}514* <li>{@code NANO_OF_DAY}515* <li>{@code MICRO_OF_SECOND}516* <li>{@code MICRO_OF_DAY}517* <li>{@code MILLI_OF_SECOND}518* <li>{@code MILLI_OF_DAY}519* <li>{@code SECOND_OF_MINUTE}520* <li>{@code SECOND_OF_DAY}521* <li>{@code MINUTE_OF_HOUR}522* <li>{@code MINUTE_OF_DAY}523* <li>{@code HOUR_OF_AMPM}524* <li>{@code CLOCK_HOUR_OF_AMPM}525* <li>{@code HOUR_OF_DAY}526* <li>{@code CLOCK_HOUR_OF_DAY}527* <li>{@code AMPM_OF_DAY}528* </ul>529* All other {@code ChronoField} instances will return false.530* <p>531* If the field is not a {@code ChronoField}, then the result of this method532* is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}533* passing {@code this} as the argument.534* Whether the field is supported is determined by the field.535*536* @param field the field to check, null returns false537* @return true if the field is supported on this time, false if not538*/539@Override540public boolean isSupported(TemporalField field) {541if (field instanceof ChronoField) {542return field.isTimeBased();543}544return field != null && field.isSupportedBy(this);545}546547/**548* Checks if the specified unit is supported.549* <p>550* This checks if the specified unit can be added to, or subtracted from, this time.551* If false, then calling the {@link #plus(long, TemporalUnit)} and552* {@link #minus(long, TemporalUnit) minus} methods will throw an exception.553* <p>554* If the unit is a {@link ChronoUnit} then the query is implemented here.555* The supported units are:556* <ul>557* <li>{@code NANOS}558* <li>{@code MICROS}559* <li>{@code MILLIS}560* <li>{@code SECONDS}561* <li>{@code MINUTES}562* <li>{@code HOURS}563* <li>{@code HALF_DAYS}564* </ul>565* All other {@code ChronoUnit} instances will return false.566* <p>567* If the unit is not a {@code ChronoUnit}, then the result of this method568* is obtained by invoking {@code TemporalUnit.isSupportedBy(Temporal)}569* passing {@code this} as the argument.570* Whether the unit is supported is determined by the unit.571*572* @param unit the unit to check, null returns false573* @return true if the unit can be added/subtracted, false if not574*/575@Override // override for Javadoc576public boolean isSupported(TemporalUnit unit) {577if (unit instanceof ChronoUnit) {578return unit.isTimeBased();579}580return unit != null && unit.isSupportedBy(this);581}582583//-----------------------------------------------------------------------584/**585* Gets the range of valid values for the specified field.586* <p>587* The range object expresses the minimum and maximum valid values for a field.588* This time is used to enhance the accuracy of the returned range.589* If it is not possible to return the range, because the field is not supported590* or for some other reason, an exception is thrown.591* <p>592* If the field is a {@link ChronoField} then the query is implemented here.593* The {@link #isSupported(TemporalField) supported fields} will return594* appropriate range instances.595* All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.596* <p>597* If the field is not a {@code ChronoField}, then the result of this method598* is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}599* passing {@code this} as the argument.600* Whether the range can be obtained is determined by the field.601*602* @param field the field to query the range for, not null603* @return the range of valid values for the field, not null604* @throws DateTimeException if the range for the field cannot be obtained605* @throws UnsupportedTemporalTypeException if the field is not supported606*/607@Override // override for Javadoc608public ValueRange range(TemporalField field) {609return Temporal.super.range(field);610}611612/**613* Gets the value of the specified field from this time as an {@code int}.614* <p>615* This queries this time for the value of the specified field.616* The returned value will always be within the valid range of values for the field.617* If it is not possible to return the value, because the field is not supported618* or for some other reason, an exception is thrown.619* <p>620* If the field is a {@link ChronoField} then the query is implemented here.621* The {@link #isSupported(TemporalField) supported fields} will return valid622* values based on this time, except {@code NANO_OF_DAY} and {@code MICRO_OF_DAY}623* which are too large to fit in an {@code int} and throw an {@code UnsupportedTemporalTypeException}.624* All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.625* <p>626* If the field is not a {@code ChronoField}, then the result of this method627* is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}628* passing {@code this} as the argument. Whether the value can be obtained,629* and what the value represents, is determined by the field.630*631* @param field the field to get, not null632* @return the value for the field633* @throws DateTimeException if a value for the field cannot be obtained or634* the value is outside the range of valid values for the field635* @throws UnsupportedTemporalTypeException if the field is not supported or636* the range of values exceeds an {@code int}637* @throws ArithmeticException if numeric overflow occurs638*/639@Override // override for Javadoc and performance640public int get(TemporalField field) {641if (field instanceof ChronoField) {642return get0(field);643}644return Temporal.super.get(field);645}646647/**648* Gets the value of the specified field from this time as a {@code long}.649* <p>650* This queries this time for the value of the specified field.651* If it is not possible to return the value, because the field is not supported652* or for some other reason, an exception is thrown.653* <p>654* If the field is a {@link ChronoField} then the query is implemented here.655* The {@link #isSupported(TemporalField) supported fields} will return valid656* values based on this time.657* All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.658* <p>659* If the field is not a {@code ChronoField}, then the result of this method660* is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}661* passing {@code this} as the argument. Whether the value can be obtained,662* and what the value represents, is determined by the field.663*664* @param field the field to get, not null665* @return the value for the field666* @throws DateTimeException if a value for the field cannot be obtained667* @throws UnsupportedTemporalTypeException if the field is not supported668* @throws ArithmeticException if numeric overflow occurs669*/670@Override671public long getLong(TemporalField field) {672if (field instanceof ChronoField) {673if (field == NANO_OF_DAY) {674return toNanoOfDay();675}676if (field == MICRO_OF_DAY) {677return toNanoOfDay() / 1000;678}679return get0(field);680}681return field.getFrom(this);682}683684private int get0(TemporalField field) {685switch ((ChronoField) field) {686case NANO_OF_SECOND: return nano;687case NANO_OF_DAY: throw new UnsupportedTemporalTypeException("Invalid field 'NanoOfDay' for get() method, use getLong() instead");688case MICRO_OF_SECOND: return nano / 1000;689case MICRO_OF_DAY: throw new UnsupportedTemporalTypeException("Invalid field 'MicroOfDay' for get() method, use getLong() instead");690case MILLI_OF_SECOND: return nano / 1000_000;691case MILLI_OF_DAY: return (int) (toNanoOfDay() / 1000_000);692case SECOND_OF_MINUTE: return second;693case SECOND_OF_DAY: return toSecondOfDay();694case MINUTE_OF_HOUR: return minute;695case MINUTE_OF_DAY: return hour * 60 + minute;696case HOUR_OF_AMPM: return hour % 12;697case CLOCK_HOUR_OF_AMPM: int ham = hour % 12; return (ham % 12 == 0 ? 12 : ham);698case HOUR_OF_DAY: return hour;699case CLOCK_HOUR_OF_DAY: return (hour == 0 ? 24 : hour);700case AMPM_OF_DAY: return hour / 12;701}702throw new UnsupportedTemporalTypeException("Unsupported field: " + field);703}704705//-----------------------------------------------------------------------706/**707* Gets the hour-of-day field.708*709* @return the hour-of-day, from 0 to 23710*/711public int getHour() {712return hour;713}714715/**716* Gets the minute-of-hour field.717*718* @return the minute-of-hour, from 0 to 59719*/720public int getMinute() {721return minute;722}723724/**725* Gets the second-of-minute field.726*727* @return the second-of-minute, from 0 to 59728*/729public int getSecond() {730return second;731}732733/**734* Gets the nano-of-second field.735*736* @return the nano-of-second, from 0 to 999,999,999737*/738public int getNano() {739return nano;740}741742//-----------------------------------------------------------------------743/**744* Returns an adjusted copy of this time.745* <p>746* This returns a {@code LocalTime}, based on this one, with the time adjusted.747* The adjustment takes place using the specified adjuster strategy object.748* Read the documentation of the adjuster to understand what adjustment will be made.749* <p>750* A simple adjuster might simply set the one of the fields, such as the hour field.751* A more complex adjuster might set the time to the last hour of the day.752* <p>753* The result of this method is obtained by invoking the754* {@link TemporalAdjuster#adjustInto(Temporal)} method on the755* specified adjuster passing {@code this} as the argument.756* <p>757* This instance is immutable and unaffected by this method call.758*759* @param adjuster the adjuster to use, not null760* @return a {@code LocalTime} based on {@code this} with the adjustment made, not null761* @throws DateTimeException if the adjustment cannot be made762* @throws ArithmeticException if numeric overflow occurs763*/764@Override765public LocalTime with(TemporalAdjuster adjuster) {766// optimizations767if (adjuster instanceof LocalTime) {768return (LocalTime) adjuster;769}770return (LocalTime) adjuster.adjustInto(this);771}772773/**774* Returns a copy of this time with the specified field set to a new value.775* <p>776* This returns a {@code LocalTime}, based on this one, with the value777* for the specified field changed.778* This can be used to change any supported field, such as the hour, minute or second.779* If it is not possible to set the value, because the field is not supported or for780* some other reason, an exception is thrown.781* <p>782* If the field is a {@link ChronoField} then the adjustment is implemented here.783* The supported fields behave as follows:784* <ul>785* <li>{@code NANO_OF_SECOND} -786* Returns a {@code LocalTime} with the specified nano-of-second.787* The hour, minute and second will be unchanged.788* <li>{@code NANO_OF_DAY} -789* Returns a {@code LocalTime} with the specified nano-of-day.790* This completely replaces the time and is equivalent to {@link #ofNanoOfDay(long)}.791* <li>{@code MICRO_OF_SECOND} -792* Returns a {@code LocalTime} with the nano-of-second replaced by the specified793* micro-of-second multiplied by 1,000.794* The hour, minute and second will be unchanged.795* <li>{@code MICRO_OF_DAY} -796* Returns a {@code LocalTime} with the specified micro-of-day.797* This completely replaces the time and is equivalent to using {@link #ofNanoOfDay(long)}798* with the micro-of-day multiplied by 1,000.799* <li>{@code MILLI_OF_SECOND} -800* Returns a {@code LocalTime} with the nano-of-second replaced by the specified801* milli-of-second multiplied by 1,000,000.802* The hour, minute and second will be unchanged.803* <li>{@code MILLI_OF_DAY} -804* Returns a {@code LocalTime} with the specified milli-of-day.805* This completely replaces the time and is equivalent to using {@link #ofNanoOfDay(long)}806* with the milli-of-day multiplied by 1,000,000.807* <li>{@code SECOND_OF_MINUTE} -808* Returns a {@code LocalTime} with the specified second-of-minute.809* The hour, minute and nano-of-second will be unchanged.810* <li>{@code SECOND_OF_DAY} -811* Returns a {@code LocalTime} with the specified second-of-day.812* The nano-of-second will be unchanged.813* <li>{@code MINUTE_OF_HOUR} -814* Returns a {@code LocalTime} with the specified minute-of-hour.815* The hour, second-of-minute and nano-of-second will be unchanged.816* <li>{@code MINUTE_OF_DAY} -817* Returns a {@code LocalTime} with the specified minute-of-day.818* The second-of-minute and nano-of-second will be unchanged.819* <li>{@code HOUR_OF_AMPM} -820* Returns a {@code LocalTime} with the specified hour-of-am-pm.821* The AM/PM, minute-of-hour, second-of-minute and nano-of-second will be unchanged.822* <li>{@code CLOCK_HOUR_OF_AMPM} -823* Returns a {@code LocalTime} with the specified clock-hour-of-am-pm.824* The AM/PM, minute-of-hour, second-of-minute and nano-of-second will be unchanged.825* <li>{@code HOUR_OF_DAY} -826* Returns a {@code LocalTime} with the specified hour-of-day.827* The minute-of-hour, second-of-minute and nano-of-second will be unchanged.828* <li>{@code CLOCK_HOUR_OF_DAY} -829* Returns a {@code LocalTime} with the specified clock-hour-of-day.830* The minute-of-hour, second-of-minute and nano-of-second will be unchanged.831* <li>{@code AMPM_OF_DAY} -832* Returns a {@code LocalTime} with the specified AM/PM.833* The hour-of-am-pm, minute-of-hour, second-of-minute and nano-of-second will be unchanged.834* </ul>835* <p>836* In all cases, if the new value is outside the valid range of values for the field837* then a {@code DateTimeException} will be thrown.838* <p>839* All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.840* <p>841* If the field is not a {@code ChronoField}, then the result of this method842* is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}843* passing {@code this} as the argument. In this case, the field determines844* whether and how to adjust the instant.845* <p>846* This instance is immutable and unaffected by this method call.847*848* @param field the field to set in the result, not null849* @param newValue the new value of the field in the result850* @return a {@code LocalTime} based on {@code this} with the specified field set, not null851* @throws DateTimeException if the field cannot be set852* @throws UnsupportedTemporalTypeException if the field is not supported853* @throws ArithmeticException if numeric overflow occurs854*/855@Override856public LocalTime with(TemporalField field, long newValue) {857if (field instanceof ChronoField chronoField) {858chronoField.checkValidValue(newValue);859switch (chronoField) {860case NANO_OF_SECOND: return withNano((int) newValue);861case NANO_OF_DAY: return LocalTime.ofNanoOfDay(newValue);862case MICRO_OF_SECOND: return withNano((int) newValue * 1000);863case MICRO_OF_DAY: return LocalTime.ofNanoOfDay(newValue * 1000);864case MILLI_OF_SECOND: return withNano((int) newValue * 1000_000);865case MILLI_OF_DAY: return LocalTime.ofNanoOfDay(newValue * 1000_000);866case SECOND_OF_MINUTE: return withSecond((int) newValue);867case SECOND_OF_DAY: return plusSeconds(newValue - toSecondOfDay());868case MINUTE_OF_HOUR: return withMinute((int) newValue);869case MINUTE_OF_DAY: return plusMinutes(newValue - (hour * 60 + minute));870case HOUR_OF_AMPM: return plusHours(newValue - (hour % 12));871case CLOCK_HOUR_OF_AMPM: return plusHours((newValue == 12 ? 0 : newValue) - (hour % 12));872case HOUR_OF_DAY: return withHour((int) newValue);873case CLOCK_HOUR_OF_DAY: return withHour((int) (newValue == 24 ? 0 : newValue));874case AMPM_OF_DAY: return plusHours((newValue - (hour / 12)) * 12);875}876throw new UnsupportedTemporalTypeException("Unsupported field: " + field);877}878return field.adjustInto(this, newValue);879}880881//-----------------------------------------------------------------------882/**883* Returns a copy of this {@code LocalTime} with the hour-of-day altered.884* <p>885* This instance is immutable and unaffected by this method call.886*887* @param hour the hour-of-day to set in the result, from 0 to 23888* @return a {@code LocalTime} based on this time with the requested hour, not null889* @throws DateTimeException if the hour value is invalid890*/891public LocalTime withHour(int hour) {892if (this.hour == hour) {893return this;894}895HOUR_OF_DAY.checkValidValue(hour);896return create(hour, minute, second, nano);897}898899/**900* Returns a copy of this {@code LocalTime} with the minute-of-hour altered.901* <p>902* This instance is immutable and unaffected by this method call.903*904* @param minute the minute-of-hour to set in the result, from 0 to 59905* @return a {@code LocalTime} based on this time with the requested minute, not null906* @throws DateTimeException if the minute value is invalid907*/908public LocalTime withMinute(int minute) {909if (this.minute == minute) {910return this;911}912MINUTE_OF_HOUR.checkValidValue(minute);913return create(hour, minute, second, nano);914}915916/**917* Returns a copy of this {@code LocalTime} with the second-of-minute altered.918* <p>919* This instance is immutable and unaffected by this method call.920*921* @param second the second-of-minute to set in the result, from 0 to 59922* @return a {@code LocalTime} based on this time with the requested second, not null923* @throws DateTimeException if the second value is invalid924*/925public LocalTime withSecond(int second) {926if (this.second == second) {927return this;928}929SECOND_OF_MINUTE.checkValidValue(second);930return create(hour, minute, second, nano);931}932933/**934* Returns a copy of this {@code LocalTime} with the nano-of-second altered.935* <p>936* This instance is immutable and unaffected by this method call.937*938* @param nanoOfSecond the nano-of-second to set in the result, from 0 to 999,999,999939* @return a {@code LocalTime} based on this time with the requested nanosecond, not null940* @throws DateTimeException if the nanos value is invalid941*/942public LocalTime withNano(int nanoOfSecond) {943if (this.nano == nanoOfSecond) {944return this;945}946NANO_OF_SECOND.checkValidValue(nanoOfSecond);947return create(hour, minute, second, nanoOfSecond);948}949950//-----------------------------------------------------------------------951/**952* Returns a copy of this {@code LocalTime} with the time truncated.953* <p>954* Truncation returns a copy of the original time with fields955* smaller than the specified unit set to zero.956* For example, truncating with the {@link ChronoUnit#MINUTES minutes} unit957* will set the second-of-minute and nano-of-second field to zero.958* <p>959* The unit must have a {@linkplain TemporalUnit#getDuration() duration}960* that divides into the length of a standard day without remainder.961* This includes all supplied time units on {@link ChronoUnit} and962* {@link ChronoUnit#DAYS DAYS}. Other units throw an exception.963* <p>964* This instance is immutable and unaffected by this method call.965*966* @param unit the unit to truncate to, not null967* @return a {@code LocalTime} based on this time with the time truncated, not null968* @throws DateTimeException if unable to truncate969* @throws UnsupportedTemporalTypeException if the unit is not supported970*/971public LocalTime truncatedTo(TemporalUnit unit) {972if (unit == ChronoUnit.NANOS) {973return this;974}975Duration unitDur = unit.getDuration();976if (unitDur.getSeconds() > SECONDS_PER_DAY) {977throw new UnsupportedTemporalTypeException("Unit is too large to be used for truncation");978}979long dur = unitDur.toNanos();980if ((NANOS_PER_DAY % dur) != 0) {981throw new UnsupportedTemporalTypeException("Unit must divide into a standard day without remainder");982}983long nod = toNanoOfDay();984return ofNanoOfDay((nod / dur) * dur);985}986987//-----------------------------------------------------------------------988/**989* Returns a copy of this time with the specified amount added.990* <p>991* This returns a {@code LocalTime}, based on this one, with the specified amount added.992* The amount is typically {@link Duration} but may be any other type implementing993* the {@link TemporalAmount} interface.994* <p>995* The calculation is delegated to the amount object by calling996* {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free997* to implement the addition in any way it wishes, however it typically998* calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation999* of the amount implementation to determine if it can be successfully added.1000* <p>1001* This instance is immutable and unaffected by this method call.1002*1003* @param amountToAdd the amount to add, not null1004* @return a {@code LocalTime} based on this time with the addition made, not null1005* @throws DateTimeException if the addition cannot be made1006* @throws ArithmeticException if numeric overflow occurs1007*/1008@Override1009public LocalTime plus(TemporalAmount amountToAdd) {1010return (LocalTime) amountToAdd.addTo(this);1011}10121013/**1014* Returns a copy of this time with the specified amount added.1015* <p>1016* This returns a {@code LocalTime}, based on this one, with the amount1017* in terms of the unit added. If it is not possible to add the amount, because the1018* unit is not supported or for some other reason, an exception is thrown.1019* <p>1020* If the field is a {@link ChronoUnit} then the addition is implemented here.1021* The supported fields behave as follows:1022* <ul>1023* <li>{@code NANOS} -1024* Returns a {@code LocalTime} with the specified number of nanoseconds added.1025* This is equivalent to {@link #plusNanos(long)}.1026* <li>{@code MICROS} -1027* Returns a {@code LocalTime} with the specified number of microseconds added.1028* This is equivalent to {@link #plusNanos(long)} with the amount1029* multiplied by 1,000.1030* <li>{@code MILLIS} -1031* Returns a {@code LocalTime} with the specified number of milliseconds added.1032* This is equivalent to {@link #plusNanos(long)} with the amount1033* multiplied by 1,000,000.1034* <li>{@code SECONDS} -1035* Returns a {@code LocalTime} with the specified number of seconds added.1036* This is equivalent to {@link #plusSeconds(long)}.1037* <li>{@code MINUTES} -1038* Returns a {@code LocalTime} with the specified number of minutes added.1039* This is equivalent to {@link #plusMinutes(long)}.1040* <li>{@code HOURS} -1041* Returns a {@code LocalTime} with the specified number of hours added.1042* This is equivalent to {@link #plusHours(long)}.1043* <li>{@code HALF_DAYS} -1044* Returns a {@code LocalTime} with the specified number of half-days added.1045* This is equivalent to {@link #plusHours(long)} with the amount1046* multiplied by 12.1047* </ul>1048* <p>1049* All other {@code ChronoUnit} instances will throw an {@code UnsupportedTemporalTypeException}.1050* <p>1051* If the field is not a {@code ChronoUnit}, then the result of this method1052* is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}1053* passing {@code this} as the argument. In this case, the unit determines1054* whether and how to perform the addition.1055* <p>1056* This instance is immutable and unaffected by this method call.1057*1058* @param amountToAdd the amount of the unit to add to the result, may be negative1059* @param unit the unit of the amount to add, not null1060* @return a {@code LocalTime} based on this time with the specified amount added, not null1061* @throws DateTimeException if the addition cannot be made1062* @throws UnsupportedTemporalTypeException if the unit is not supported1063* @throws ArithmeticException if numeric overflow occurs1064*/1065@Override1066public LocalTime plus(long amountToAdd, TemporalUnit unit) {1067if (unit instanceof ChronoUnit chronoUnit) {1068switch (chronoUnit) {1069case NANOS: return plusNanos(amountToAdd);1070case MICROS: return plusNanos((amountToAdd % MICROS_PER_DAY) * 1000);1071case MILLIS: return plusNanos((amountToAdd % MILLIS_PER_DAY) * 1000_000);1072case SECONDS: return plusSeconds(amountToAdd);1073case MINUTES: return plusMinutes(amountToAdd);1074case HOURS: return plusHours(amountToAdd);1075case HALF_DAYS: return plusHours((amountToAdd % 2) * 12);1076}1077throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);1078}1079return unit.addTo(this, amountToAdd);1080}10811082//-----------------------------------------------------------------------1083/**1084* Returns a copy of this {@code LocalTime} with the specified number of hours added.1085* <p>1086* This adds the specified number of hours to this time, returning a new time.1087* The calculation wraps around midnight.1088* <p>1089* This instance is immutable and unaffected by this method call.1090*1091* @param hoursToAdd the hours to add, may be negative1092* @return a {@code LocalTime} based on this time with the hours added, not null1093*/1094public LocalTime plusHours(long hoursToAdd) {1095if (hoursToAdd == 0) {1096return this;1097}1098int newHour = ((int) (hoursToAdd % HOURS_PER_DAY) + hour + HOURS_PER_DAY) % HOURS_PER_DAY;1099return create(newHour, minute, second, nano);1100}11011102/**1103* Returns a copy of this {@code LocalTime} with the specified number of minutes added.1104* <p>1105* This adds the specified number of minutes to this time, returning a new time.1106* The calculation wraps around midnight.1107* <p>1108* This instance is immutable and unaffected by this method call.1109*1110* @param minutesToAdd the minutes to add, may be negative1111* @return a {@code LocalTime} based on this time with the minutes added, not null1112*/1113public LocalTime plusMinutes(long minutesToAdd) {1114if (minutesToAdd == 0) {1115return this;1116}1117int mofd = hour * MINUTES_PER_HOUR + minute;1118int newMofd = ((int) (minutesToAdd % MINUTES_PER_DAY) + mofd + MINUTES_PER_DAY) % MINUTES_PER_DAY;1119if (mofd == newMofd) {1120return this;1121}1122int newHour = newMofd / MINUTES_PER_HOUR;1123int newMinute = newMofd % MINUTES_PER_HOUR;1124return create(newHour, newMinute, second, nano);1125}11261127/**1128* Returns a copy of this {@code LocalTime} with the specified number of seconds added.1129* <p>1130* This adds the specified number of seconds to this time, returning a new time.1131* The calculation wraps around midnight.1132* <p>1133* This instance is immutable and unaffected by this method call.1134*1135* @param secondstoAdd the seconds to add, may be negative1136* @return a {@code LocalTime} based on this time with the seconds added, not null1137*/1138public LocalTime plusSeconds(long secondstoAdd) {1139if (secondstoAdd == 0) {1140return this;1141}1142int sofd = hour * SECONDS_PER_HOUR +1143minute * SECONDS_PER_MINUTE + second;1144int newSofd = ((int) (secondstoAdd % SECONDS_PER_DAY) + sofd + SECONDS_PER_DAY) % SECONDS_PER_DAY;1145if (sofd == newSofd) {1146return this;1147}1148int newHour = newSofd / SECONDS_PER_HOUR;1149int newMinute = (newSofd / SECONDS_PER_MINUTE) % MINUTES_PER_HOUR;1150int newSecond = newSofd % SECONDS_PER_MINUTE;1151return create(newHour, newMinute, newSecond, nano);1152}11531154/**1155* Returns a copy of this {@code LocalTime} with the specified number of nanoseconds added.1156* <p>1157* This adds the specified number of nanoseconds to this time, returning a new time.1158* The calculation wraps around midnight.1159* <p>1160* This instance is immutable and unaffected by this method call.1161*1162* @param nanosToAdd the nanos to add, may be negative1163* @return a {@code LocalTime} based on this time with the nanoseconds added, not null1164*/1165public LocalTime plusNanos(long nanosToAdd) {1166if (nanosToAdd == 0) {1167return this;1168}1169long nofd = toNanoOfDay();1170long newNofd = ((nanosToAdd % NANOS_PER_DAY) + nofd + NANOS_PER_DAY) % NANOS_PER_DAY;1171if (nofd == newNofd) {1172return this;1173}1174int newHour = (int) (newNofd / NANOS_PER_HOUR);1175int newMinute = (int) ((newNofd / NANOS_PER_MINUTE) % MINUTES_PER_HOUR);1176int newSecond = (int) ((newNofd / NANOS_PER_SECOND) % SECONDS_PER_MINUTE);1177int newNano = (int) (newNofd % NANOS_PER_SECOND);1178return create(newHour, newMinute, newSecond, newNano);1179}11801181//-----------------------------------------------------------------------1182/**1183* Returns a copy of this time with the specified amount subtracted.1184* <p>1185* This returns a {@code LocalTime}, based on this one, with the specified amount subtracted.1186* The amount is typically {@link Duration} but may be any other type implementing1187* the {@link TemporalAmount} interface.1188* <p>1189* The calculation is delegated to the amount object by calling1190* {@link TemporalAmount#subtractFrom(Temporal)}. The amount implementation is free1191* to implement the subtraction in any way it wishes, however it typically1192* calls back to {@link #minus(long, TemporalUnit)}. Consult the documentation1193* of the amount implementation to determine if it can be successfully subtracted.1194* <p>1195* This instance is immutable and unaffected by this method call.1196*1197* @param amountToSubtract the amount to subtract, not null1198* @return a {@code LocalTime} based on this time with the subtraction made, not null1199* @throws DateTimeException if the subtraction cannot be made1200* @throws ArithmeticException if numeric overflow occurs1201*/1202@Override1203public LocalTime minus(TemporalAmount amountToSubtract) {1204return (LocalTime) amountToSubtract.subtractFrom(this);1205}12061207/**1208* Returns a copy of this time with the specified amount subtracted.1209* <p>1210* This returns a {@code LocalTime}, based on this one, with the amount1211* in terms of the unit subtracted. If it is not possible to subtract the amount,1212* because the unit is not supported or for some other reason, an exception is thrown.1213* <p>1214* This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.1215* See that method for a full description of how addition, and thus subtraction, works.1216* <p>1217* This instance is immutable and unaffected by this method call.1218*1219* @param amountToSubtract the amount of the unit to subtract from the result, may be negative1220* @param unit the unit of the amount to subtract, not null1221* @return a {@code LocalTime} based on this time with the specified amount subtracted, not null1222* @throws DateTimeException if the subtraction cannot be made1223* @throws UnsupportedTemporalTypeException if the unit is not supported1224* @throws ArithmeticException if numeric overflow occurs1225*/1226@Override1227public LocalTime minus(long amountToSubtract, TemporalUnit unit) {1228return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));1229}12301231//-----------------------------------------------------------------------1232/**1233* Returns a copy of this {@code LocalTime} with the specified number of hours subtracted.1234* <p>1235* This subtracts the specified number of hours from this time, returning a new time.1236* The calculation wraps around midnight.1237* <p>1238* This instance is immutable and unaffected by this method call.1239*1240* @param hoursToSubtract the hours to subtract, may be negative1241* @return a {@code LocalTime} based on this time with the hours subtracted, not null1242*/1243public LocalTime minusHours(long hoursToSubtract) {1244return plusHours(-(hoursToSubtract % HOURS_PER_DAY));1245}12461247/**1248* Returns a copy of this {@code LocalTime} with the specified number of minutes subtracted.1249* <p>1250* This subtracts the specified number of minutes from this time, returning a new time.1251* The calculation wraps around midnight.1252* <p>1253* This instance is immutable and unaffected by this method call.1254*1255* @param minutesToSubtract the minutes to subtract, may be negative1256* @return a {@code LocalTime} based on this time with the minutes subtracted, not null1257*/1258public LocalTime minusMinutes(long minutesToSubtract) {1259return plusMinutes(-(minutesToSubtract % MINUTES_PER_DAY));1260}12611262/**1263* Returns a copy of this {@code LocalTime} with the specified number of seconds subtracted.1264* <p>1265* This subtracts the specified number of seconds from this time, returning a new time.1266* The calculation wraps around midnight.1267* <p>1268* This instance is immutable and unaffected by this method call.1269*1270* @param secondsToSubtract the seconds to subtract, may be negative1271* @return a {@code LocalTime} based on this time with the seconds subtracted, not null1272*/1273public LocalTime minusSeconds(long secondsToSubtract) {1274return plusSeconds(-(secondsToSubtract % SECONDS_PER_DAY));1275}12761277/**1278* Returns a copy of this {@code LocalTime} with the specified number of nanoseconds subtracted.1279* <p>1280* This subtracts the specified number of nanoseconds from this time, returning a new time.1281* The calculation wraps around midnight.1282* <p>1283* This instance is immutable and unaffected by this method call.1284*1285* @param nanosToSubtract the nanos to subtract, may be negative1286* @return a {@code LocalTime} based on this time with the nanoseconds subtracted, not null1287*/1288public LocalTime minusNanos(long nanosToSubtract) {1289return plusNanos(-(nanosToSubtract % NANOS_PER_DAY));1290}12911292//-----------------------------------------------------------------------1293/**1294* Queries this time using the specified query.1295* <p>1296* This queries this time using the specified query strategy object.1297* The {@code TemporalQuery} object defines the logic to be used to1298* obtain the result. Read the documentation of the query to understand1299* what the result of this method will be.1300* <p>1301* The result of this method is obtained by invoking the1302* {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the1303* specified query passing {@code this} as the argument.1304*1305* @param <R> the type of the result1306* @param query the query to invoke, not null1307* @return the query result, null may be returned (defined by the query)1308* @throws DateTimeException if unable to query (defined by the query)1309* @throws ArithmeticException if numeric overflow occurs (defined by the query)1310*/1311@SuppressWarnings("unchecked")1312@Override1313public <R> R query(TemporalQuery<R> query) {1314if (query == TemporalQueries.chronology() || query == TemporalQueries.zoneId() ||1315query == TemporalQueries.zone() || query == TemporalQueries.offset()) {1316return null;1317} else if (query == TemporalQueries.localTime()) {1318return (R) this;1319} else if (query == TemporalQueries.localDate()) {1320return null;1321} else if (query == TemporalQueries.precision()) {1322return (R) NANOS;1323}1324// inline TemporalAccessor.super.query(query) as an optimization1325// non-JDK classes are not permitted to make this optimization1326return query.queryFrom(this);1327}13281329/**1330* Adjusts the specified temporal object to have the same time as this object.1331* <p>1332* This returns a temporal object of the same observable type as the input1333* with the time changed to be the same as this.1334* <p>1335* The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)}1336* passing {@link ChronoField#NANO_OF_DAY} as the field.1337* <p>1338* In most cases, it is clearer to reverse the calling pattern by using1339* {@link Temporal#with(TemporalAdjuster)}:1340* <pre>1341* // these two lines are equivalent, but the second approach is recommended1342* temporal = thisLocalTime.adjustInto(temporal);1343* temporal = temporal.with(thisLocalTime);1344* </pre>1345* <p>1346* This instance is immutable and unaffected by this method call.1347*1348* @param temporal the target object to be adjusted, not null1349* @return the adjusted object, not null1350* @throws DateTimeException if unable to make the adjustment1351* @throws ArithmeticException if numeric overflow occurs1352*/1353@Override1354public Temporal adjustInto(Temporal temporal) {1355return temporal.with(NANO_OF_DAY, toNanoOfDay());1356}13571358/**1359* Calculates the amount of time until another time in terms of the specified unit.1360* <p>1361* This calculates the amount of time between two {@code LocalTime}1362* objects in terms of a single {@code TemporalUnit}.1363* The start and end points are {@code this} and the specified time.1364* The result will be negative if the end is before the start.1365* The {@code Temporal} passed to this method is converted to a1366* {@code LocalTime} using {@link #from(TemporalAccessor)}.1367* For example, the amount in hours between two times can be calculated1368* using {@code startTime.until(endTime, HOURS)}.1369* <p>1370* The calculation returns a whole number, representing the number of1371* complete units between the two times.1372* For example, the amount in hours between 11:30 and 13:29 will only1373* be one hour as it is one minute short of two hours.1374* <p>1375* There are two equivalent ways of using this method.1376* The first is to invoke this method.1377* The second is to use {@link TemporalUnit#between(Temporal, Temporal)}:1378* <pre>1379* // these two lines are equivalent1380* amount = start.until(end, MINUTES);1381* amount = MINUTES.between(start, end);1382* </pre>1383* The choice should be made based on which makes the code more readable.1384* <p>1385* The calculation is implemented in this method for {@link ChronoUnit}.1386* The units {@code NANOS}, {@code MICROS}, {@code MILLIS}, {@code SECONDS},1387* {@code MINUTES}, {@code HOURS} and {@code HALF_DAYS} are supported.1388* Other {@code ChronoUnit} values will throw an exception.1389* <p>1390* If the unit is not a {@code ChronoUnit}, then the result of this method1391* is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}1392* passing {@code this} as the first argument and the converted input temporal1393* as the second argument.1394* <p>1395* This instance is immutable and unaffected by this method call.1396*1397* @param endExclusive the end time, exclusive, which is converted to a {@code LocalTime}, not null1398* @param unit the unit to measure the amount in, not null1399* @return the amount of time between this time and the end time1400* @throws DateTimeException if the amount cannot be calculated, or the end1401* temporal cannot be converted to a {@code LocalTime}1402* @throws UnsupportedTemporalTypeException if the unit is not supported1403* @throws ArithmeticException if numeric overflow occurs1404*/1405@Override1406public long until(Temporal endExclusive, TemporalUnit unit) {1407LocalTime end = LocalTime.from(endExclusive);1408if (unit instanceof ChronoUnit chronoUnit) {1409long nanosUntil = end.toNanoOfDay() - toNanoOfDay(); // no overflow1410switch (chronoUnit) {1411case NANOS: return nanosUntil;1412case MICROS: return nanosUntil / 1000;1413case MILLIS: return nanosUntil / 1000_000;1414case SECONDS: return nanosUntil / NANOS_PER_SECOND;1415case MINUTES: return nanosUntil / NANOS_PER_MINUTE;1416case HOURS: return nanosUntil / NANOS_PER_HOUR;1417case HALF_DAYS: return nanosUntil / (12 * NANOS_PER_HOUR);1418}1419throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit);1420}1421return unit.between(this, end);1422}14231424/**1425* Formats this time using the specified formatter.1426* <p>1427* This time will be passed to the formatter to produce a string.1428*1429* @param formatter the formatter to use, not null1430* @return the formatted time string, not null1431* @throws DateTimeException if an error occurs during printing1432*/1433public String format(DateTimeFormatter formatter) {1434Objects.requireNonNull(formatter, "formatter");1435return formatter.format(this);1436}14371438//-----------------------------------------------------------------------1439/**1440* Combines this time with a date to create a {@code LocalDateTime}.1441* <p>1442* This returns a {@code LocalDateTime} formed from this time at the specified date.1443* All possible combinations of date and time are valid.1444*1445* @param date the date to combine with, not null1446* @return the local date-time formed from this time and the specified date, not null1447*/1448public LocalDateTime atDate(LocalDate date) {1449return LocalDateTime.of(date, this);1450}14511452/**1453* Combines this time with an offset to create an {@code OffsetTime}.1454* <p>1455* This returns an {@code OffsetTime} formed from this time at the specified offset.1456* All possible combinations of time and offset are valid.1457*1458* @param offset the offset to combine with, not null1459* @return the offset time formed from this time and the specified offset, not null1460*/1461public OffsetTime atOffset(ZoneOffset offset) {1462return OffsetTime.of(this, offset);1463}14641465//-----------------------------------------------------------------------1466/**1467* Extracts the time as seconds of day,1468* from {@code 0} to {@code 24 * 60 * 60 - 1}.1469*1470* @return the second-of-day equivalent to this time1471*/1472public int toSecondOfDay() {1473int total = hour * SECONDS_PER_HOUR;1474total += minute * SECONDS_PER_MINUTE;1475total += second;1476return total;1477}14781479/**1480* Extracts the time as nanos of day,1481* from {@code 0} to {@code 24 * 60 * 60 * 1,000,000,000 - 1}.1482*1483* @return the nano of day equivalent to this time1484*/1485public long toNanoOfDay() {1486long total = hour * NANOS_PER_HOUR;1487total += minute * NANOS_PER_MINUTE;1488total += second * NANOS_PER_SECOND;1489total += nano;1490return total;1491}14921493/**1494* Converts this {@code LocalTime} to the number of seconds since the epoch1495* of 1970-01-01T00:00:00Z.1496* <p>1497* This combines this local time with the specified date and1498* offset to calculate the epoch-second value, which is the1499* number of elapsed seconds from 1970-01-01T00:00:00Z.1500* Instants on the time-line after the epoch are positive, earlier1501* are negative.1502*1503* @param date the local date, not null1504* @param offset the zone offset, not null1505* @return the number of seconds since the epoch of 1970-01-01T00:00:00Z, may be negative1506* @since 91507*/1508public long toEpochSecond(LocalDate date, ZoneOffset offset) {1509Objects.requireNonNull(date, "date");1510Objects.requireNonNull(offset, "offset");1511long epochDay = date.toEpochDay();1512long secs = epochDay * 86400 + toSecondOfDay();1513secs -= offset.getTotalSeconds();1514return secs;1515}15161517//-----------------------------------------------------------------------1518/**1519* Compares this time to another time.1520* <p>1521* The comparison is based on the time-line position of the local times within a day.1522* It is "consistent with equals", as defined by {@link Comparable}.1523*1524* @param other the other time to compare to, not null1525* @return the comparator value, negative if less, positive if greater1526*/1527@Override1528public int compareTo(LocalTime other) {1529int cmp = Integer.compare(hour, other.hour);1530if (cmp == 0) {1531cmp = Integer.compare(minute, other.minute);1532if (cmp == 0) {1533cmp = Integer.compare(second, other.second);1534if (cmp == 0) {1535cmp = Integer.compare(nano, other.nano);1536}1537}1538}1539return cmp;1540}15411542/**1543* Checks if this time is after the specified time.1544* <p>1545* The comparison is based on the time-line position of the time within a day.1546*1547* @param other the other time to compare to, not null1548* @return true if this is after the specified time1549*/1550public boolean isAfter(LocalTime other) {1551return compareTo(other) > 0;1552}15531554/**1555* Checks if this time is before the specified time.1556* <p>1557* The comparison is based on the time-line position of the time within a day.1558*1559* @param other the other time to compare to, not null1560* @return true if this point is before the specified time1561*/1562public boolean isBefore(LocalTime other) {1563return compareTo(other) < 0;1564}15651566//-----------------------------------------------------------------------1567/**1568* Checks if this time is equal to another time.1569* <p>1570* The comparison is based on the time-line position of the time within a day.1571* <p>1572* Only objects of type {@code LocalTime} are compared, other types return false.1573* To compare the date of two {@code TemporalAccessor} instances, use1574* {@link ChronoField#NANO_OF_DAY} as a comparator.1575*1576* @param obj the object to check, null returns false1577* @return true if this is equal to the other time1578*/1579@Override1580public boolean equals(Object obj) {1581if (this == obj) {1582return true;1583}1584return (obj instanceof LocalTime other)1585&& hour == other.hour1586&& minute == other.minute1587&& second == other.second1588&& nano == other.nano;1589}15901591/**1592* A hash code for this time.1593*1594* @return a suitable hash code1595*/1596@Override1597public int hashCode() {1598long nod = toNanoOfDay();1599return (int) (nod ^ (nod >>> 32));1600}16011602//-----------------------------------------------------------------------1603/**1604* Outputs this time as a {@code String}, such as {@code 10:15}.1605* <p>1606* The output will be one of the following ISO-8601 formats:1607* <ul>1608* <li>{@code HH:mm}</li>1609* <li>{@code HH:mm:ss}</li>1610* <li>{@code HH:mm:ss.SSS}</li>1611* <li>{@code HH:mm:ss.SSSSSS}</li>1612* <li>{@code HH:mm:ss.SSSSSSSSS}</li>1613* </ul>1614* The format used will be the shortest that outputs the full value of1615* the time where the omitted parts are implied to be zero.1616*1617* @return a string representation of this time, not null1618*/1619@Override1620public String toString() {1621StringBuilder buf = new StringBuilder(18);1622int hourValue = hour;1623int minuteValue = minute;1624int secondValue = second;1625int nanoValue = nano;1626buf.append(hourValue < 10 ? "0" : "").append(hourValue)1627.append(minuteValue < 10 ? ":0" : ":").append(minuteValue);1628if (secondValue > 0 || nanoValue > 0) {1629buf.append(secondValue < 10 ? ":0" : ":").append(secondValue);1630if (nanoValue > 0) {1631buf.append('.');1632if (nanoValue % 1000_000 == 0) {1633buf.append(Integer.toString((nanoValue / 1000_000) + 1000).substring(1));1634} else if (nanoValue % 1000 == 0) {1635buf.append(Integer.toString((nanoValue / 1000) + 1000_000).substring(1));1636} else {1637buf.append(Integer.toString((nanoValue) + 1000_000_000).substring(1));1638}1639}1640}1641return buf.toString();1642}16431644//-----------------------------------------------------------------------1645/**1646* Writes the object using a1647* <a href="{@docRoot}/serialized-form.html#java.time.Ser">dedicated serialized form</a>.1648* @serialData1649* A twos-complement value indicates the remaining values are not in the stream1650* and should be set to zero.1651* <pre>1652* out.writeByte(4); // identifies a LocalTime1653* if (nano == 0) {1654* if (second == 0) {1655* if (minute == 0) {1656* out.writeByte(~hour);1657* } else {1658* out.writeByte(hour);1659* out.writeByte(~minute);1660* }1661* } else {1662* out.writeByte(hour);1663* out.writeByte(minute);1664* out.writeByte(~second);1665* }1666* } else {1667* out.writeByte(hour);1668* out.writeByte(minute);1669* out.writeByte(second);1670* out.writeInt(nano);1671* }1672* </pre>1673*1674* @return the instance of {@code Ser}, not null1675*/1676@java.io.Serial1677private Object writeReplace() {1678return new Ser(Ser.LOCAL_TIME_TYPE, this);1679}16801681/**1682* Defend against malicious streams.1683*1684* @param s the stream to read1685* @throws InvalidObjectException always1686*/1687@java.io.Serial1688private void readObject(ObjectInputStream s) throws InvalidObjectException {1689throw new InvalidObjectException("Deserialization via serialization delegate");1690}16911692void writeExternal(DataOutput out) throws IOException {1693if (nano == 0) {1694if (second == 0) {1695if (minute == 0) {1696out.writeByte(~hour);1697} else {1698out.writeByte(hour);1699out.writeByte(~minute);1700}1701} else {1702out.writeByte(hour);1703out.writeByte(minute);1704out.writeByte(~second);1705}1706} else {1707out.writeByte(hour);1708out.writeByte(minute);1709out.writeByte(second);1710out.writeInt(nano);1711}1712}17131714static LocalTime readExternal(DataInput in) throws IOException {1715int hour = in.readByte();1716int minute = 0;1717int second = 0;1718int nano = 0;1719if (hour < 0) {1720hour = ~hour;1721} else {1722minute = in.readByte();1723if (minute < 0) {1724minute = ~minute;1725} else {1726second = in.readByte();1727if (second < 0) {1728second = ~second;1729} else {1730nano = in.readInt();1731}1732}1733}1734return LocalTime.of(hour, minute, second, nano);1735}17361737}173817391740