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