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.ObjectStreamException;
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.Queries;
84 import java.time.temporal.Temporal;
85 import java.time.temporal.TemporalAccessor;
86 import java.time.temporal.TemporalAdjuster;
87 import java.time.temporal.TemporalAmount;
88 import java.time.temporal.TemporalField;
89 import java.time.temporal.TemporalQuery;
90 import java.time.temporal.TemporalUnit;
91 import java.time.temporal.ValueRange;
92 import java.util.Objects;
93
94 /**
95 * A time without 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 * It 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 information
106 * such as an offset or time-zone.
107 * <p>
108 * The ISO-8601 calendar system is the modern civil calendar system used today
109 * in most of the world. This API assumes that all calendar systems use the same
110 * representation, this class, for time-of-day.
366 */
367 public static LocalTime ofNanoOfDay(long nanoOfDay) {
368 NANO_OF_DAY.checkValidValue(nanoOfDay);
369 int hours = (int) (nanoOfDay / NANOS_PER_HOUR);
370 nanoOfDay -= hours * NANOS_PER_HOUR;
371 int minutes = (int) (nanoOfDay / NANOS_PER_MINUTE);
372 nanoOfDay -= minutes * NANOS_PER_MINUTE;
373 int seconds = (int) (nanoOfDay / NANOS_PER_SECOND);
374 nanoOfDay -= seconds * NANOS_PER_SECOND;
375 return create(hours, minutes, seconds, (int) nanoOfDay);
376 }
377
378 //-----------------------------------------------------------------------
379 /**
380 * Obtains an instance of {@code LocalTime} from a temporal object.
381 * <p>
382 * This obtains a local time based on the specified temporal.
383 * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
384 * which this factory converts to an instance of {@code LocalTime}.
385 * <p>
386 * The conversion uses the {@link Queries#localTime()} query, which relies
387 * on extracting the {@link ChronoField#NANO_OF_DAY NANO_OF_DAY} field.
388 * <p>
389 * This method matches the signature of the functional interface {@link TemporalQuery}
390 * allowing it to be used in queries via method reference, {@code LocalTime::from}.
391 *
392 * @param temporal the temporal object to convert, not null
393 * @return the local time, not null
394 * @throws DateTimeException if unable to convert to a {@code LocalTime}
395 */
396 public static LocalTime from(TemporalAccessor temporal) {
397 LocalTime time = temporal.query(Queries.localTime());
398 if (time == null) {
399 throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: " + temporal.getClass());
400 }
401 return time;
402 }
403
404 //-----------------------------------------------------------------------
405 /**
406 * Obtains an instance of {@code LocalTime} from a text string such as {@code 10:15}.
407 * <p>
408 * The string must represent a valid time and is parsed using
409 * {@link java.time.format.DateTimeFormatter#ISO_LOCAL_TIME}.
410 *
411 * @param text the text to parse such as "10:15:30", not null
412 * @return the parsed local time, not null
413 * @throws DateTimeParseException if the text cannot be parsed
414 */
415 public static LocalTime parse(CharSequence text) {
416 return parse(text, DateTimeFormatter.ISO_LOCAL_TIME);
417 }
488 * <li>{@code MINUTE_OF_DAY}
489 * <li>{@code HOUR_OF_AMPM}
490 * <li>{@code CLOCK_HOUR_OF_AMPM}
491 * <li>{@code HOUR_OF_DAY}
492 * <li>{@code CLOCK_HOUR_OF_DAY}
493 * <li>{@code AMPM_OF_DAY}
494 * </ul>
495 * All other {@code ChronoField} instances will return false.
496 * <p>
497 * If the field is not a {@code ChronoField}, then the result of this method
498 * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
499 * passing {@code this} as the argument.
500 * Whether the field is supported is determined by the field.
501 *
502 * @param field the field to check, null returns false
503 * @return true if the field is supported on this time, false if not
504 */
505 @Override
506 public boolean isSupported(TemporalField field) {
507 if (field instanceof ChronoField) {
508 return ((ChronoField) field).isTimeField();
509 }
510 return field != null && field.isSupportedBy(this);
511 }
512
513 /**
514 * Gets the range of valid values for the specified field.
515 * <p>
516 * The range object expresses the minimum and maximum valid values for a field.
517 * This time is used to enhance the accuracy of the returned range.
518 * If it is not possible to return the range, because the field is not supported
519 * or for some other reason, an exception is thrown.
520 * <p>
521 * If the field is a {@link ChronoField} then the query is implemented here.
522 * The {@link #isSupported(TemporalField) supported fields} will return
523 * appropriate range instances.
524 * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
525 * <p>
526 * If the field is not a {@code ChronoField}, then the result of this method
527 * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
528 * passing {@code this} as the argument.
529 * Whether the range can be obtained is determined by the field.
530 *
531 * @param field the field to query the range for, not null
532 * @return the range of valid values for the field, not null
533 * @throws DateTimeException if the range for the field cannot be obtained
534 */
535 @Override // override for Javadoc
536 public ValueRange range(TemporalField field) {
537 return Temporal.super.range(field);
538 }
539
540 /**
541 * Gets the value of the specified field from this time as an {@code int}.
542 * <p>
543 * This queries this time for the value for the specified field.
544 * The returned value will always be within the valid range of values for the field.
545 * If it is not possible to return the value, because the field is not supported
546 * or for some other reason, an exception is thrown.
547 * <p>
548 * If the field is a {@link ChronoField} then the query is implemented here.
549 * The {@link #isSupported(TemporalField) supported fields} will return valid
550 * values based on this time, except {@code NANO_OF_DAY} and {@code MICRO_OF_DAY}
551 * which are too large to fit in an {@code int} and throw a {@code DateTimeException}.
552 * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
553 * <p>
554 * If the field is not a {@code ChronoField}, then the result of this method
555 * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
556 * passing {@code this} as the argument. Whether the value can be obtained,
557 * and what the value represents, is determined by the field.
558 *
559 * @param field the field to get, not null
560 * @return the value for the field
561 * @throws DateTimeException if a value for the field cannot be obtained
562 * @throws ArithmeticException if numeric overflow occurs
563 */
564 @Override // override for Javadoc and performance
565 public int get(TemporalField field) {
566 if (field instanceof ChronoField) {
567 return get0(field);
568 }
569 return Temporal.super.get(field);
570 }
571
572 /**
573 * Gets the value of the specified field from this time as a {@code long}.
574 * <p>
575 * This queries this time for the value for the specified field.
576 * If it is not possible to return the value, because the field is not supported
577 * or for some other reason, an exception is thrown.
578 * <p>
579 * If the field is a {@link ChronoField} then the query is implemented here.
580 * The {@link #isSupported(TemporalField) supported fields} will return valid
581 * values based on this time.
582 * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
583 * <p>
584 * If the field is not a {@code ChronoField}, then the result of this method
585 * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
586 * passing {@code this} as the argument. Whether the value can be obtained,
587 * and what the value represents, is determined by the field.
588 *
589 * @param field the field to get, not null
590 * @return the value for the field
591 * @throws DateTimeException if a value for the field cannot be obtained
592 * @throws ArithmeticException if numeric overflow occurs
593 */
594 @Override
595 public long getLong(TemporalField field) {
596 if (field instanceof ChronoField) {
597 if (field == NANO_OF_DAY) {
598 return toNanoOfDay();
599 }
600 if (field == MICRO_OF_DAY) {
601 return toNanoOfDay() / 1000;
602 }
603 return get0(field);
604 }
605 return field.getFrom(this);
606 }
607
608 private int get0(TemporalField field) {
609 switch ((ChronoField) field) {
610 case NANO_OF_SECOND: return nano;
611 case NANO_OF_DAY: throw new DateTimeException("Field too large for an int: " + field);
612 case MICRO_OF_SECOND: return nano / 1000;
613 case MICRO_OF_DAY: throw new DateTimeException("Field too large for an int: " + field);
614 case MILLI_OF_SECOND: return nano / 1000_000;
615 case MILLI_OF_DAY: return (int) (toNanoOfDay() / 1000_000);
616 case SECOND_OF_MINUTE: return second;
617 case SECOND_OF_DAY: return toSecondOfDay();
618 case MINUTE_OF_HOUR: return minute;
619 case MINUTE_OF_DAY: return hour * 60 + minute;
620 case HOUR_OF_AMPM: return hour % 12;
621 case CLOCK_HOUR_OF_AMPM: int ham = hour % 12; return (ham % 12 == 0 ? 12 : ham);
622 case HOUR_OF_DAY: return hour;
623 case CLOCK_HOUR_OF_DAY: return (hour == 0 ? 24 : hour);
624 case AMPM_OF_DAY: return hour / 12;
625 }
626 throw new DateTimeException("Unsupported field: " + field.getName());
627 }
628
629 //-----------------------------------------------------------------------
630 /**
631 * Gets the hour-of-day field.
632 *
633 * @return the hour-of-day, from 0 to 23
634 */
635 public int getHour() {
636 return hour;
637 }
638
639 /**
640 * Gets the minute-of-hour field.
641 *
642 * @return the minute-of-hour, from 0 to 59
643 */
644 public int getMinute() {
645 return minute;
646 }
743 * <li>{@code HOUR_OF_AMPM} -
744 * Returns a {@code LocalTime} with the specified hour-of-am-pm.
745 * The AM/PM, minute-of-hour, second-of-minute and nano-of-second will be unchanged.
746 * <li>{@code CLOCK_HOUR_OF_AMPM} -
747 * Returns a {@code LocalTime} with the specified clock-hour-of-am-pm.
748 * The AM/PM, minute-of-hour, second-of-minute and nano-of-second will be unchanged.
749 * <li>{@code HOUR_OF_DAY} -
750 * Returns a {@code LocalTime} with the specified hour-of-day.
751 * The minute-of-hour, second-of-minute and nano-of-second will be unchanged.
752 * <li>{@code CLOCK_HOUR_OF_DAY} -
753 * Returns a {@code LocalTime} with the specified clock-hour-of-day.
754 * The minute-of-hour, second-of-minute and nano-of-second will be unchanged.
755 * <li>{@code AMPM_OF_DAY} -
756 * Returns a {@code LocalTime} with the specified AM/PM.
757 * The hour-of-am-pm, minute-of-hour, second-of-minute and nano-of-second will be unchanged.
758 * </ul>
759 * <p>
760 * In all cases, if the new value is outside the valid range of values for the field
761 * then a {@code DateTimeException} will be thrown.
762 * <p>
763 * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
764 * <p>
765 * If the field is not a {@code ChronoField}, then the result of this method
766 * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
767 * passing {@code this} as the argument. In this case, the field determines
768 * whether and how to adjust the instant.
769 * <p>
770 * This instance is immutable and unaffected by this method call.
771 *
772 * @param field the field to set in the result, not null
773 * @param newValue the new value of the field in the result
774 * @return a {@code LocalTime} based on {@code this} with the specified field set, not null
775 * @throws DateTimeException if the field cannot be set
776 * @throws ArithmeticException if numeric overflow occurs
777 */
778 @Override
779 public LocalTime with(TemporalField field, long newValue) {
780 if (field instanceof ChronoField) {
781 ChronoField f = (ChronoField) field;
782 f.checkValidValue(newValue);
783 switch (f) {
784 case NANO_OF_SECOND: return withNano((int) newValue);
785 case NANO_OF_DAY: return LocalTime.ofNanoOfDay(newValue);
786 case MICRO_OF_SECOND: return withNano((int) newValue * 1000);
787 case MICRO_OF_DAY: return plusNanos((newValue - toNanoOfDay() / 1000) * 1000);
788 case MILLI_OF_SECOND: return withNano((int) newValue * 1000_000);
789 case MILLI_OF_DAY: return plusNanos((newValue - toNanoOfDay() / 1000_000) * 1000_000);
790 case SECOND_OF_MINUTE: return withSecond((int) newValue);
791 case SECOND_OF_DAY: return plusSeconds(newValue - toSecondOfDay());
792 case MINUTE_OF_HOUR: return withMinute((int) newValue);
793 case MINUTE_OF_DAY: return plusMinutes(newValue - (hour * 60 + minute));
794 case HOUR_OF_AMPM: return plusHours(newValue - (hour % 12));
795 case CLOCK_HOUR_OF_AMPM: return plusHours((newValue == 12 ? 0 : newValue) - (hour % 12));
796 case HOUR_OF_DAY: return withHour((int) newValue);
797 case CLOCK_HOUR_OF_DAY: return withHour((int) (newValue == 24 ? 0 : newValue));
798 case AMPM_OF_DAY: return plusHours((newValue - (hour / 12)) * 12);
799 }
800 throw new DateTimeException("Unsupported field: " + field.getName());
801 }
802 return field.adjustInto(this, newValue);
803 }
804
805 //-----------------------------------------------------------------------
806 /**
807 * Returns a copy of this {@code LocalTime} with the hour-of-day value altered.
808 * <p>
809 * This instance is immutable and unaffected by this method call.
810 *
811 * @param hour the hour-of-day to set in the result, from 0 to 23
812 * @return a {@code LocalTime} based on this time with the requested hour, not null
813 * @throws DateTimeException if the hour value is invalid
814 */
815 public LocalTime withHour(int hour) {
816 if (this.hour == hour) {
817 return this;
818 }
819 HOUR_OF_DAY.checkValidValue(hour);
820 return create(hour, minute, second, nano);
873
874 //-----------------------------------------------------------------------
875 /**
876 * Returns a copy of this {@code LocalTime} with the time truncated.
877 * <p>
878 * Truncating the time returns a copy of the original time with fields
879 * smaller than the specified unit set to zero.
880 * For example, truncating with the {@link ChronoUnit#MINUTES minutes} unit
881 * will set the second-of-minute and nano-of-second field to zero.
882 * <p>
883 * The unit must have a {@linkplain TemporalUnit#getDuration() duration}
884 * that divides into the length of a standard day without remainder.
885 * This includes all supplied time units on {@link ChronoUnit} and
886 * {@link ChronoUnit#DAYS DAYS}. Other units throw an exception.
887 * <p>
888 * This instance is immutable and unaffected by this method call.
889 *
890 * @param unit the unit to truncate to, not null
891 * @return a {@code LocalTime} based on this time with the time truncated, not null
892 * @throws DateTimeException if unable to truncate
893 */
894 public LocalTime truncatedTo(TemporalUnit unit) {
895 if (unit == ChronoUnit.NANOS) {
896 return this;
897 }
898 Duration unitDur = unit.getDuration();
899 if (unitDur.getSeconds() > SECONDS_PER_DAY) {
900 throw new DateTimeException("Unit is too large to be used for truncation");
901 }
902 long dur = unitDur.toNanos();
903 if ((NANOS_PER_DAY % dur) != 0) {
904 throw new DateTimeException("Unit must divide into a standard day without remainder");
905 }
906 long nod = toNanoOfDay();
907 return ofNanoOfDay((nod / dur) * dur);
908 }
909
910 //-----------------------------------------------------------------------
911 /**
912 * Returns a copy of this time with the specified amount added.
913 * <p>
914 * This returns a {@code LocalTime}, based on this one, with the specified amount added.
915 * The amount is typically {@link Duration} but may be any other type implementing
916 * the {@link TemporalAmount} interface.
917 * <p>
918 * The calculation is delegated to the amount object by calling
919 * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
920 * to implement the addition in any way it wishes, however it typically
921 * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
922 * of the amount implementation to determine if it can be successfully added.
923 * <p>
924 * This instance is immutable and unaffected by this method call.
955 * This is equivalent to {@link #plusNanos(long)} with the amount
956 * multiplied by 1,000,000.
957 * <li>{@code SECONDS} -
958 * Returns a {@code LocalTime} with the specified number of seconds added.
959 * This is equivalent to {@link #plusSeconds(long)}.
960 * <li>{@code MINUTES} -
961 * Returns a {@code LocalTime} with the specified number of minutes added.
962 * This is equivalent to {@link #plusMinutes(long)}.
963 * <li>{@code HOURS} -
964 * Returns a {@code LocalTime} with the specified number of hours added.
965 * This is equivalent to {@link #plusHours(long)}.
966 * <li>{@code HALF_DAYS} -
967 * Returns a {@code LocalTime} with the specified number of half-days added.
968 * This is equivalent to {@link #plusHours(long)} with the amount
969 * multiplied by 12.
970 * <li>{@code DAYS} -
971 * Returns a {@code LocalTime} with the specified number of days added.
972 * This returns {@code this} time.
973 * </ul>
974 * <p>
975 * All other {@code ChronoUnit} instances will throw a {@code DateTimeException}.
976 * <p>
977 * If the field is not a {@code ChronoUnit}, then the result of this method
978 * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
979 * passing {@code this} as the argument. In this case, the unit determines
980 * whether and how to perform the addition.
981 * <p>
982 * This instance is immutable and unaffected by this method call.
983 *
984 * @param amountToAdd the amount of the unit to add to the result, may be negative
985 * @param unit the unit of the amount to add, not null
986 * @return a {@code LocalTime} based on this time with the specified amount added, not null
987 * @throws DateTimeException if the addition cannot be made
988 * @throws ArithmeticException if numeric overflow occurs
989 */
990 @Override
991 public LocalTime plus(long amountToAdd, TemporalUnit unit) {
992 if (unit instanceof ChronoUnit) {
993 ChronoUnit f = (ChronoUnit) unit;
994 switch (f) {
995 case NANOS: return plusNanos(amountToAdd);
996 case MICROS: return plusNanos((amountToAdd % MICROS_PER_DAY) * 1000);
997 case MILLIS: return plusNanos((amountToAdd % MILLIS_PER_DAY) * 1000_000);
998 case SECONDS: return plusSeconds(amountToAdd);
999 case MINUTES: return plusMinutes(amountToAdd);
1000 case HOURS: return plusHours(amountToAdd);
1001 case HALF_DAYS: return plusHours((amountToAdd % 2) * 12);
1002 case DAYS: return this;
1003 }
1004 throw new DateTimeException("Unsupported unit: " + unit.getName());
1005 }
1006 return unit.addTo(this, amountToAdd);
1007 }
1008
1009 //-----------------------------------------------------------------------
1010 /**
1011 * Returns a copy of this {@code LocalTime} with the specified period in hours added.
1012 * <p>
1013 * This adds the specified number of hours to this time, returning a new time.
1014 * The calculation wraps around midnight.
1015 * <p>
1016 * This instance is immutable and unaffected by this method call.
1017 *
1018 * @param hoursToAdd the hours to add, may be negative
1019 * @return a {@code LocalTime} based on this time with the hours added, not null
1020 */
1021 public LocalTime plusHours(long hoursToAdd) {
1022 if (hoursToAdd == 0) {
1023 return this;
1024 }
1130 public LocalTime minus(TemporalAmount amountToSubtract) {
1131 return (LocalTime) amountToSubtract.subtractFrom(this);
1132 }
1133
1134 /**
1135 * Returns a copy of this time with the specified amount subtracted.
1136 * <p>
1137 * This returns a {@code LocalTime}, based on this one, with the amount
1138 * in terms of the unit subtracted. If it is not possible to subtract the amount,
1139 * because the unit is not supported or for some other reason, an exception is thrown.
1140 * <p>
1141 * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
1142 * See that method for a full description of how addition, and thus subtraction, works.
1143 * <p>
1144 * This instance is immutable and unaffected by this method call.
1145 *
1146 * @param amountToSubtract the amount of the unit to subtract from the result, may be negative
1147 * @param unit the unit of the amount to subtract, not null
1148 * @return a {@code LocalTime} based on this time with the specified amount subtracted, not null
1149 * @throws DateTimeException if the subtraction cannot be made
1150 * @throws ArithmeticException if numeric overflow occurs
1151 */
1152 @Override
1153 public LocalTime minus(long amountToSubtract, TemporalUnit unit) {
1154 return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
1155 }
1156
1157 //-----------------------------------------------------------------------
1158 /**
1159 * Returns a copy of this {@code LocalTime} with the specified period in hours subtracted.
1160 * <p>
1161 * This subtracts the specified number of hours from this time, returning a new time.
1162 * The calculation wraps around midnight.
1163 * <p>
1164 * This instance is immutable and unaffected by this method call.
1165 *
1166 * @param hoursToSubtract the hours to subtract, may be negative
1167 * @return a {@code LocalTime} based on this time with the hours subtracted, not null
1168 */
1169 public LocalTime minusHours(long hoursToSubtract) {
1220 * Queries this time using the specified query.
1221 * <p>
1222 * This queries this time using the specified query strategy object.
1223 * The {@code TemporalQuery} object defines the logic to be used to
1224 * obtain the result. Read the documentation of the query to understand
1225 * what the result of this method will be.
1226 * <p>
1227 * The result of this method is obtained by invoking the
1228 * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the
1229 * specified query passing {@code this} as the argument.
1230 *
1231 * @param <R> the type of the result
1232 * @param query the query to invoke, not null
1233 * @return the query result, null may be returned (defined by the query)
1234 * @throws DateTimeException if unable to query (defined by the query)
1235 * @throws ArithmeticException if numeric overflow occurs (defined by the query)
1236 */
1237 @SuppressWarnings("unchecked")
1238 @Override
1239 public <R> R query(TemporalQuery<R> query) {
1240 if (query == Queries.chronology() || query == Queries.zoneId() || query == Queries.zone() || query == Queries.offset()) {
1241 return null;
1242 } else if (query == Queries.localTime()) {
1243 return (R) this;
1244 } else if (query == Queries.localDate()) {
1245 return null;
1246 } else if (query == Queries.precision()) {
1247 return (R) NANOS;
1248 }
1249 // inline TemporalAccessor.super.query(query) as an optimization
1250 // non-JDK classes are not permitted to make this optimization
1251 return query.queryFrom(this);
1252 }
1253
1254 /**
1255 * Adjusts the specified temporal object to have the same time as this object.
1256 * <p>
1257 * This returns a temporal object of the same observable type as the input
1258 * with the time changed to be the same as this.
1259 * <p>
1260 * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)}
1261 * passing {@link ChronoField#NANO_OF_DAY} as the field.
1262 * <p>
1263 * In most cases, it is clearer to reverse the calling pattern by using
1264 * {@link Temporal#with(TemporalAdjuster)}:
1265 * <pre>
1266 * // these two lines are equivalent, but the second approach is recommended
1305 * amount = MINUTES.between(start, end);
1306 * </pre>
1307 * The choice should be made based on which makes the code more readable.
1308 * <p>
1309 * The calculation is implemented in this method for {@link ChronoUnit}.
1310 * The units {@code NANOS}, {@code MICROS}, {@code MILLIS}, {@code SECONDS},
1311 * {@code MINUTES}, {@code HOURS} and {@code HALF_DAYS} are supported.
1312 * Other {@code ChronoUnit} values will throw an exception.
1313 * <p>
1314 * If the unit is not a {@code ChronoUnit}, then the result of this method
1315 * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
1316 * passing {@code this} as the first argument and the input temporal as
1317 * the second argument.
1318 * <p>
1319 * This instance is immutable and unaffected by this method call.
1320 *
1321 * @param endTime the end time, which must be a {@code LocalTime}, not null
1322 * @param unit the unit to measure the period in, not null
1323 * @return the amount of the period between this time and the end time
1324 * @throws DateTimeException if the period cannot be calculated
1325 * @throws ArithmeticException if numeric overflow occurs
1326 */
1327 @Override
1328 public long periodUntil(Temporal endTime, TemporalUnit unit) {
1329 if (endTime instanceof LocalTime == false) {
1330 Objects.requireNonNull(endTime, "endTime");
1331 throw new DateTimeException("Unable to calculate period between objects of two different types");
1332 }
1333 LocalTime end = (LocalTime) endTime;
1334 if (unit instanceof ChronoUnit) {
1335 long nanosUntil = end.toNanoOfDay() - toNanoOfDay(); // no overflow
1336 switch ((ChronoUnit) unit) {
1337 case NANOS: return nanosUntil;
1338 case MICROS: return nanosUntil / 1000;
1339 case MILLIS: return nanosUntil / 1000_000;
1340 case SECONDS: return nanosUntil / NANOS_PER_SECOND;
1341 case MINUTES: return nanosUntil / NANOS_PER_MINUTE;
1342 case HOURS: return nanosUntil / NANOS_PER_HOUR;
1343 case HALF_DAYS: return nanosUntil / (12 * NANOS_PER_HOUR);
1344 }
1345 throw new DateTimeException("Unsupported unit: " + unit.getName());
1346 }
1347 return unit.between(this, endTime);
1348 }
1349
1350 //-----------------------------------------------------------------------
1351 /**
1352 * Combines this time with a date to create a {@code LocalDateTime}.
1353 * <p>
1354 * This returns a {@code LocalDateTime} formed from this time at the specified date.
1355 * All possible combinations of date and time are valid.
1356 *
1357 * @param date the date to combine with, not null
1358 * @return the local date-time formed from this time and the specified date, not null
1359 */
1360 public LocalDateTime atDate(LocalDate date) {
1361 return LocalDateTime.of(date, this);
1362 }
1363
1364 /**
1365 * Combines this time with a date to create an {@code OffsetTime}.
1366 * <p>
1367 * This returns an {@code OffsetTime} formed from this time at the specified offset.
1368 * All possible combinations of time and offset are valid.
1369 *
1370 * @param offset the offset to combine with, not null
1371 * @return the offset time formed from this time and the specified offset, not null
1372 */
1373 public OffsetTime atOffset(ZoneOffset offset) {
1374 return OffsetTime.of(this, offset);
1375 }
1376
1377 //-----------------------------------------------------------------------
1378 /**
1379 * Extracts the time as seconds of day,
1380 * from {@code 0} to {@code 24 * 60 * 60 - 1}.
1381 *
1382 * @return the second-of-day equivalent to this time
1383 */
1384 public int toSecondOfDay() {
1385 int total = hour * SECONDS_PER_HOUR;
1516 int secondValue = second;
1517 int nanoValue = nano;
1518 buf.append(hourValue < 10 ? "0" : "").append(hourValue)
1519 .append(minuteValue < 10 ? ":0" : ":").append(minuteValue);
1520 if (secondValue > 0 || nanoValue > 0) {
1521 buf.append(secondValue < 10 ? ":0" : ":").append(secondValue);
1522 if (nanoValue > 0) {
1523 buf.append('.');
1524 if (nanoValue % 1000_000 == 0) {
1525 buf.append(Integer.toString((nanoValue / 1000_000) + 1000).substring(1));
1526 } else if (nanoValue % 1000 == 0) {
1527 buf.append(Integer.toString((nanoValue / 1000) + 1000_000).substring(1));
1528 } else {
1529 buf.append(Integer.toString((nanoValue) + 1000_000_000).substring(1));
1530 }
1531 }
1532 }
1533 return buf.toString();
1534 }
1535
1536 /**
1537 * Outputs this time as a {@code String} using the formatter.
1538 * <p>
1539 * This time will be passed to the formatter
1540 * {@link DateTimeFormatter#format(TemporalAccessor) format method}.
1541 *
1542 * @param formatter the formatter to use, not null
1543 * @return the formatted time string, not null
1544 * @throws DateTimeException if an error occurs during printing
1545 */
1546 public String toString(DateTimeFormatter formatter) {
1547 Objects.requireNonNull(formatter, "formatter");
1548 return formatter.format(this);
1549 }
1550
1551 //-----------------------------------------------------------------------
1552 /**
1553 * Writes the object using a
1554 * <a href="../../serialized-form.html#java.time.Ser">dedicated serialized form</a>.
1555 * <pre>
1556 * out.writeByte(4); // identifies this as a LocalTime
1557 * if (nano == 0) {
1558 * if (second == 0) {
1559 * if (minute == 0) {
1560 * out.writeByte(~hour);
1561 * } else {
1562 * out.writeByte(hour);
1563 * out.writeByte(~minute);
1564 * }
1565 * } else {
1566 * out.writeByte(hour);
1567 * out.writeByte(minute);
1568 * out.writeByte(~second);
1569 * }
1570 * } else {
|
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.ObjectStreamException;
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.TemporalQuery;
89 import java.time.temporal.TemporalUnit;
90 import java.time.temporal.UnsupportedTemporalTypeException;
91 import java.time.temporal.ValueRange;
92 import java.util.Objects;
93
94 /**
95 * A time without 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 * It 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 information
106 * such as an offset or time-zone.
107 * <p>
108 * The ISO-8601 calendar system is the modern civil calendar system used today
109 * in most of the world. This API assumes that all calendar systems use the same
110 * representation, this class, for time-of-day.
366 */
367 public static LocalTime ofNanoOfDay(long nanoOfDay) {
368 NANO_OF_DAY.checkValidValue(nanoOfDay);
369 int hours = (int) (nanoOfDay / NANOS_PER_HOUR);
370 nanoOfDay -= hours * NANOS_PER_HOUR;
371 int minutes = (int) (nanoOfDay / NANOS_PER_MINUTE);
372 nanoOfDay -= minutes * NANOS_PER_MINUTE;
373 int seconds = (int) (nanoOfDay / NANOS_PER_SECOND);
374 nanoOfDay -= seconds * NANOS_PER_SECOND;
375 return create(hours, minutes, seconds, (int) nanoOfDay);
376 }
377
378 //-----------------------------------------------------------------------
379 /**
380 * Obtains an instance of {@code LocalTime} from a temporal object.
381 * <p>
382 * This obtains a local time based on the specified temporal.
383 * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
384 * which this factory converts to an instance of {@code LocalTime}.
385 * <p>
386 * The conversion uses the {@link TemporalQuery#localTime()} query, which relies
387 * on extracting the {@link ChronoField#NANO_OF_DAY NANO_OF_DAY} field.
388 * <p>
389 * This method matches the signature of the functional interface {@link TemporalQuery}
390 * allowing it to be used in queries via method reference, {@code LocalTime::from}.
391 *
392 * @param temporal the temporal object to convert, not null
393 * @return the local time, not null
394 * @throws DateTimeException if unable to convert to a {@code LocalTime}
395 */
396 public static LocalTime from(TemporalAccessor temporal) {
397 LocalTime time = temporal.query(TemporalQuery.localTime());
398 if (time == null) {
399 throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: " + temporal.getClass());
400 }
401 return time;
402 }
403
404 //-----------------------------------------------------------------------
405 /**
406 * Obtains an instance of {@code LocalTime} from a text string such as {@code 10:15}.
407 * <p>
408 * The string must represent a valid time and is parsed using
409 * {@link java.time.format.DateTimeFormatter#ISO_LOCAL_TIME}.
410 *
411 * @param text the text to parse such as "10:15:30", not null
412 * @return the parsed local time, not null
413 * @throws DateTimeParseException if the text cannot be parsed
414 */
415 public static LocalTime parse(CharSequence text) {
416 return parse(text, DateTimeFormatter.ISO_LOCAL_TIME);
417 }
488 * <li>{@code MINUTE_OF_DAY}
489 * <li>{@code HOUR_OF_AMPM}
490 * <li>{@code CLOCK_HOUR_OF_AMPM}
491 * <li>{@code HOUR_OF_DAY}
492 * <li>{@code CLOCK_HOUR_OF_DAY}
493 * <li>{@code AMPM_OF_DAY}
494 * </ul>
495 * All other {@code ChronoField} instances will return false.
496 * <p>
497 * If the field is not a {@code ChronoField}, then the result of this method
498 * is obtained by invoking {@code TemporalField.isSupportedBy(TemporalAccessor)}
499 * passing {@code this} as the argument.
500 * Whether the field is supported is determined by the field.
501 *
502 * @param field the field to check, null returns false
503 * @return true if the field is supported on this time, false if not
504 */
505 @Override
506 public boolean isSupported(TemporalField field) {
507 if (field instanceof ChronoField) {
508 return field.isTimeBased();
509 }
510 return field != null && field.isSupportedBy(this);
511 }
512
513 /**
514 * Gets the range of valid values for the specified field.
515 * <p>
516 * The range object expresses the minimum and maximum valid values for a field.
517 * This time is used to enhance the accuracy of the returned range.
518 * If it is not possible to return the range, because the field is not supported
519 * or for some other reason, an exception is thrown.
520 * <p>
521 * If the field is a {@link ChronoField} then the query is implemented here.
522 * The {@link #isSupported(TemporalField) supported fields} will return
523 * appropriate range instances.
524 * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
525 * <p>
526 * If the field is not a {@code ChronoField}, then the result of this method
527 * is obtained by invoking {@code TemporalField.rangeRefinedBy(TemporalAccessor)}
528 * passing {@code this} as the argument.
529 * Whether the range can be obtained is determined by the field.
530 *
531 * @param field the field to query the range for, not null
532 * @return the range of valid values for the field, not null
533 * @throws DateTimeException if the range for the field cannot be obtained
534 * @throws UnsupportedTemporalTypeException if the field is not supported
535 */
536 @Override // override for Javadoc
537 public ValueRange range(TemporalField field) {
538 return Temporal.super.range(field);
539 }
540
541 /**
542 * Gets the value of the specified field from this time as an {@code int}.
543 * <p>
544 * This queries this time for the value for the specified field.
545 * The returned value will always be within the valid range of values for the field.
546 * If it is not possible to return the value, because the field is not supported
547 * or for some other reason, an exception is thrown.
548 * <p>
549 * If the field is a {@link ChronoField} then the query is implemented here.
550 * The {@link #isSupported(TemporalField) supported fields} will return valid
551 * values based on this time, except {@code NANO_OF_DAY} and {@code MICRO_OF_DAY}
552 * which are too large to fit in an {@code int} and throw a {@code DateTimeException}.
553 * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
554 * <p>
555 * If the field is not a {@code ChronoField}, then the result of this method
556 * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
557 * passing {@code this} as the argument. Whether the value can be obtained,
558 * and what the value represents, is determined by the field.
559 *
560 * @param field the field to get, not null
561 * @return the value for the field
562 * @throws DateTimeException if a value for the field cannot be obtained or
563 * the value is outside the range of valid values for the field
564 * @throws UnsupportedTemporalTypeException if the field is not supported or
565 * the range of values exceeds an {@code int}
566 * @throws ArithmeticException if numeric overflow occurs
567 */
568 @Override // override for Javadoc and performance
569 public int get(TemporalField field) {
570 if (field instanceof ChronoField) {
571 return get0(field);
572 }
573 return Temporal.super.get(field);
574 }
575
576 /**
577 * Gets the value of the specified field from this time as a {@code long}.
578 * <p>
579 * This queries this time for the value for the specified field.
580 * If it is not possible to return the value, because the field is not supported
581 * or for some other reason, an exception is thrown.
582 * <p>
583 * If the field is a {@link ChronoField} then the query is implemented here.
584 * The {@link #isSupported(TemporalField) supported fields} will return valid
585 * values based on this time.
586 * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
587 * <p>
588 * If the field is not a {@code ChronoField}, then the result of this method
589 * is obtained by invoking {@code TemporalField.getFrom(TemporalAccessor)}
590 * passing {@code this} as the argument. Whether the value can be obtained,
591 * and what the value represents, is determined by the field.
592 *
593 * @param field the field to get, not null
594 * @return the value for the field
595 * @throws DateTimeException if a value for the field cannot be obtained
596 * @throws UnsupportedTemporalTypeException if the field is not supported
597 * @throws ArithmeticException if numeric overflow occurs
598 */
599 @Override
600 public long getLong(TemporalField field) {
601 if (field instanceof ChronoField) {
602 if (field == NANO_OF_DAY) {
603 return toNanoOfDay();
604 }
605 if (field == MICRO_OF_DAY) {
606 return toNanoOfDay() / 1000;
607 }
608 return get0(field);
609 }
610 return field.getFrom(this);
611 }
612
613 private int get0(TemporalField field) {
614 switch ((ChronoField) field) {
615 case NANO_OF_SECOND: return nano;
616 case NANO_OF_DAY: throw new UnsupportedTemporalTypeException("Invalid field 'NanoOfDay' for get() method, use getLong() instead");
617 case MICRO_OF_SECOND: return nano / 1000;
618 case MICRO_OF_DAY: throw new UnsupportedTemporalTypeException("Invalid field 'MicroOfDay' for get() method, use getLong() instead");
619 case MILLI_OF_SECOND: return nano / 1000_000;
620 case MILLI_OF_DAY: return (int) (toNanoOfDay() / 1000_000);
621 case SECOND_OF_MINUTE: return second;
622 case SECOND_OF_DAY: return toSecondOfDay();
623 case MINUTE_OF_HOUR: return minute;
624 case MINUTE_OF_DAY: return hour * 60 + minute;
625 case HOUR_OF_AMPM: return hour % 12;
626 case CLOCK_HOUR_OF_AMPM: int ham = hour % 12; return (ham % 12 == 0 ? 12 : ham);
627 case HOUR_OF_DAY: return hour;
628 case CLOCK_HOUR_OF_DAY: return (hour == 0 ? 24 : hour);
629 case AMPM_OF_DAY: return hour / 12;
630 }
631 throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName());
632 }
633
634 //-----------------------------------------------------------------------
635 /**
636 * Gets the hour-of-day field.
637 *
638 * @return the hour-of-day, from 0 to 23
639 */
640 public int getHour() {
641 return hour;
642 }
643
644 /**
645 * Gets the minute-of-hour field.
646 *
647 * @return the minute-of-hour, from 0 to 59
648 */
649 public int getMinute() {
650 return minute;
651 }
748 * <li>{@code HOUR_OF_AMPM} -
749 * Returns a {@code LocalTime} with the specified hour-of-am-pm.
750 * The AM/PM, minute-of-hour, second-of-minute and nano-of-second will be unchanged.
751 * <li>{@code CLOCK_HOUR_OF_AMPM} -
752 * Returns a {@code LocalTime} with the specified clock-hour-of-am-pm.
753 * The AM/PM, minute-of-hour, second-of-minute and nano-of-second will be unchanged.
754 * <li>{@code HOUR_OF_DAY} -
755 * Returns a {@code LocalTime} with the specified hour-of-day.
756 * The minute-of-hour, second-of-minute and nano-of-second will be unchanged.
757 * <li>{@code CLOCK_HOUR_OF_DAY} -
758 * Returns a {@code LocalTime} with the specified clock-hour-of-day.
759 * The minute-of-hour, second-of-minute and nano-of-second will be unchanged.
760 * <li>{@code AMPM_OF_DAY} -
761 * Returns a {@code LocalTime} with the specified AM/PM.
762 * The hour-of-am-pm, minute-of-hour, second-of-minute and nano-of-second will be unchanged.
763 * </ul>
764 * <p>
765 * In all cases, if the new value is outside the valid range of values for the field
766 * then a {@code DateTimeException} will be thrown.
767 * <p>
768 * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
769 * <p>
770 * If the field is not a {@code ChronoField}, then the result of this method
771 * is obtained by invoking {@code TemporalField.adjustInto(Temporal, long)}
772 * passing {@code this} as the argument. In this case, the field determines
773 * whether and how to adjust the instant.
774 * <p>
775 * This instance is immutable and unaffected by this method call.
776 *
777 * @param field the field to set in the result, not null
778 * @param newValue the new value of the field in the result
779 * @return a {@code LocalTime} based on {@code this} with the specified field set, not null
780 * @throws DateTimeException if the field cannot be set
781 * @throws UnsupportedTemporalTypeException if the field is not supported
782 * @throws ArithmeticException if numeric overflow occurs
783 */
784 @Override
785 public LocalTime with(TemporalField field, long newValue) {
786 if (field instanceof ChronoField) {
787 ChronoField f = (ChronoField) field;
788 f.checkValidValue(newValue);
789 switch (f) {
790 case NANO_OF_SECOND: return withNano((int) newValue);
791 case NANO_OF_DAY: return LocalTime.ofNanoOfDay(newValue);
792 case MICRO_OF_SECOND: return withNano((int) newValue * 1000);
793 case MICRO_OF_DAY: return plusNanos((newValue - toNanoOfDay() / 1000) * 1000);
794 case MILLI_OF_SECOND: return withNano((int) newValue * 1000_000);
795 case MILLI_OF_DAY: return plusNanos((newValue - toNanoOfDay() / 1000_000) * 1000_000);
796 case SECOND_OF_MINUTE: return withSecond((int) newValue);
797 case SECOND_OF_DAY: return plusSeconds(newValue - toSecondOfDay());
798 case MINUTE_OF_HOUR: return withMinute((int) newValue);
799 case MINUTE_OF_DAY: return plusMinutes(newValue - (hour * 60 + minute));
800 case HOUR_OF_AMPM: return plusHours(newValue - (hour % 12));
801 case CLOCK_HOUR_OF_AMPM: return plusHours((newValue == 12 ? 0 : newValue) - (hour % 12));
802 case HOUR_OF_DAY: return withHour((int) newValue);
803 case CLOCK_HOUR_OF_DAY: return withHour((int) (newValue == 24 ? 0 : newValue));
804 case AMPM_OF_DAY: return plusHours((newValue - (hour / 12)) * 12);
805 }
806 throw new UnsupportedTemporalTypeException("Unsupported field: " + field.getName());
807 }
808 return field.adjustInto(this, newValue);
809 }
810
811 //-----------------------------------------------------------------------
812 /**
813 * Returns a copy of this {@code LocalTime} with the hour-of-day value altered.
814 * <p>
815 * This instance is immutable and unaffected by this method call.
816 *
817 * @param hour the hour-of-day to set in the result, from 0 to 23
818 * @return a {@code LocalTime} based on this time with the requested hour, not null
819 * @throws DateTimeException if the hour value is invalid
820 */
821 public LocalTime withHour(int hour) {
822 if (this.hour == hour) {
823 return this;
824 }
825 HOUR_OF_DAY.checkValidValue(hour);
826 return create(hour, minute, second, nano);
879
880 //-----------------------------------------------------------------------
881 /**
882 * Returns a copy of this {@code LocalTime} with the time truncated.
883 * <p>
884 * Truncating the time returns a copy of the original time with fields
885 * smaller than the specified unit set to zero.
886 * For example, truncating with the {@link ChronoUnit#MINUTES minutes} unit
887 * will set the second-of-minute and nano-of-second field to zero.
888 * <p>
889 * The unit must have a {@linkplain TemporalUnit#getDuration() duration}
890 * that divides into the length of a standard day without remainder.
891 * This includes all supplied time units on {@link ChronoUnit} and
892 * {@link ChronoUnit#DAYS DAYS}. Other units throw an exception.
893 * <p>
894 * This instance is immutable and unaffected by this method call.
895 *
896 * @param unit the unit to truncate to, not null
897 * @return a {@code LocalTime} based on this time with the time truncated, not null
898 * @throws DateTimeException if unable to truncate
899 * @throws UnsupportedTemporalTypeException if the unit is not supported
900 */
901 public LocalTime truncatedTo(TemporalUnit unit) {
902 if (unit == ChronoUnit.NANOS) {
903 return this;
904 }
905 Duration unitDur = unit.getDuration();
906 if (unitDur.getSeconds() > SECONDS_PER_DAY) {
907 throw new UnsupportedTemporalTypeException("Unit is too large to be used for truncation");
908 }
909 long dur = unitDur.toNanos();
910 if ((NANOS_PER_DAY % dur) != 0) {
911 throw new UnsupportedTemporalTypeException("Unit must divide into a standard day without remainder");
912 }
913 long nod = toNanoOfDay();
914 return ofNanoOfDay((nod / dur) * dur);
915 }
916
917 //-----------------------------------------------------------------------
918 /**
919 * Returns a copy of this time with the specified amount added.
920 * <p>
921 * This returns a {@code LocalTime}, based on this one, with the specified amount added.
922 * The amount is typically {@link Duration} but may be any other type implementing
923 * the {@link TemporalAmount} interface.
924 * <p>
925 * The calculation is delegated to the amount object by calling
926 * {@link TemporalAmount#addTo(Temporal)}. The amount implementation is free
927 * to implement the addition in any way it wishes, however it typically
928 * calls back to {@link #plus(long, TemporalUnit)}. Consult the documentation
929 * of the amount implementation to determine if it can be successfully added.
930 * <p>
931 * This instance is immutable and unaffected by this method call.
962 * This is equivalent to {@link #plusNanos(long)} with the amount
963 * multiplied by 1,000,000.
964 * <li>{@code SECONDS} -
965 * Returns a {@code LocalTime} with the specified number of seconds added.
966 * This is equivalent to {@link #plusSeconds(long)}.
967 * <li>{@code MINUTES} -
968 * Returns a {@code LocalTime} with the specified number of minutes added.
969 * This is equivalent to {@link #plusMinutes(long)}.
970 * <li>{@code HOURS} -
971 * Returns a {@code LocalTime} with the specified number of hours added.
972 * This is equivalent to {@link #plusHours(long)}.
973 * <li>{@code HALF_DAYS} -
974 * Returns a {@code LocalTime} with the specified number of half-days added.
975 * This is equivalent to {@link #plusHours(long)} with the amount
976 * multiplied by 12.
977 * <li>{@code DAYS} -
978 * Returns a {@code LocalTime} with the specified number of days added.
979 * This returns {@code this} time.
980 * </ul>
981 * <p>
982 * All other {@code ChronoUnit} instances will throw an {@code UnsupportedTemporalTypeException}.
983 * <p>
984 * If the field is not a {@code ChronoUnit}, then the result of this method
985 * is obtained by invoking {@code TemporalUnit.addTo(Temporal, long)}
986 * passing {@code this} as the argument. In this case, the unit determines
987 * whether and how to perform the addition.
988 * <p>
989 * This instance is immutable and unaffected by this method call.
990 *
991 * @param amountToAdd the amount of the unit to add to the result, may be negative
992 * @param unit the unit of the amount to add, not null
993 * @return a {@code LocalTime} based on this time with the specified amount added, not null
994 * @throws DateTimeException if the addition cannot be made
995 * @throws UnsupportedTemporalTypeException if the unit is not supported
996 * @throws ArithmeticException if numeric overflow occurs
997 */
998 @Override
999 public LocalTime plus(long amountToAdd, TemporalUnit unit) {
1000 if (unit instanceof ChronoUnit) {
1001 ChronoUnit f = (ChronoUnit) unit;
1002 switch (f) {
1003 case NANOS: return plusNanos(amountToAdd);
1004 case MICROS: return plusNanos((amountToAdd % MICROS_PER_DAY) * 1000);
1005 case MILLIS: return plusNanos((amountToAdd % MILLIS_PER_DAY) * 1000_000);
1006 case SECONDS: return plusSeconds(amountToAdd);
1007 case MINUTES: return plusMinutes(amountToAdd);
1008 case HOURS: return plusHours(amountToAdd);
1009 case HALF_DAYS: return plusHours((amountToAdd % 2) * 12);
1010 case DAYS: return this;
1011 }
1012 throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName());
1013 }
1014 return unit.addTo(this, amountToAdd);
1015 }
1016
1017 //-----------------------------------------------------------------------
1018 /**
1019 * Returns a copy of this {@code LocalTime} with the specified period in hours added.
1020 * <p>
1021 * This adds the specified number of hours to this time, returning a new time.
1022 * The calculation wraps around midnight.
1023 * <p>
1024 * This instance is immutable and unaffected by this method call.
1025 *
1026 * @param hoursToAdd the hours to add, may be negative
1027 * @return a {@code LocalTime} based on this time with the hours added, not null
1028 */
1029 public LocalTime plusHours(long hoursToAdd) {
1030 if (hoursToAdd == 0) {
1031 return this;
1032 }
1138 public LocalTime minus(TemporalAmount amountToSubtract) {
1139 return (LocalTime) amountToSubtract.subtractFrom(this);
1140 }
1141
1142 /**
1143 * Returns a copy of this time with the specified amount subtracted.
1144 * <p>
1145 * This returns a {@code LocalTime}, based on this one, with the amount
1146 * in terms of the unit subtracted. If it is not possible to subtract the amount,
1147 * because the unit is not supported or for some other reason, an exception is thrown.
1148 * <p>
1149 * This method is equivalent to {@link #plus(long, TemporalUnit)} with the amount negated.
1150 * See that method for a full description of how addition, and thus subtraction, works.
1151 * <p>
1152 * This instance is immutable and unaffected by this method call.
1153 *
1154 * @param amountToSubtract the amount of the unit to subtract from the result, may be negative
1155 * @param unit the unit of the amount to subtract, not null
1156 * @return a {@code LocalTime} based on this time with the specified amount subtracted, not null
1157 * @throws DateTimeException if the subtraction cannot be made
1158 * @throws UnsupportedTemporalTypeException if the unit is not supported
1159 * @throws ArithmeticException if numeric overflow occurs
1160 */
1161 @Override
1162 public LocalTime minus(long amountToSubtract, TemporalUnit unit) {
1163 return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
1164 }
1165
1166 //-----------------------------------------------------------------------
1167 /**
1168 * Returns a copy of this {@code LocalTime} with the specified period in hours subtracted.
1169 * <p>
1170 * This subtracts the specified number of hours from this time, returning a new time.
1171 * The calculation wraps around midnight.
1172 * <p>
1173 * This instance is immutable and unaffected by this method call.
1174 *
1175 * @param hoursToSubtract the hours to subtract, may be negative
1176 * @return a {@code LocalTime} based on this time with the hours subtracted, not null
1177 */
1178 public LocalTime minusHours(long hoursToSubtract) {
1229 * Queries this time using the specified query.
1230 * <p>
1231 * This queries this time using the specified query strategy object.
1232 * The {@code TemporalQuery} object defines the logic to be used to
1233 * obtain the result. Read the documentation of the query to understand
1234 * what the result of this method will be.
1235 * <p>
1236 * The result of this method is obtained by invoking the
1237 * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the
1238 * specified query passing {@code this} as the argument.
1239 *
1240 * @param <R> the type of the result
1241 * @param query the query to invoke, not null
1242 * @return the query result, null may be returned (defined by the query)
1243 * @throws DateTimeException if unable to query (defined by the query)
1244 * @throws ArithmeticException if numeric overflow occurs (defined by the query)
1245 */
1246 @SuppressWarnings("unchecked")
1247 @Override
1248 public <R> R query(TemporalQuery<R> query) {
1249 if (query == TemporalQuery.chronology() || query == TemporalQuery.zoneId() ||
1250 query == TemporalQuery.zone() || query == TemporalQuery.offset()) {
1251 return null;
1252 } else if (query == TemporalQuery.localTime()) {
1253 return (R) this;
1254 } else if (query == TemporalQuery.localDate()) {
1255 return null;
1256 } else if (query == TemporalQuery.precision()) {
1257 return (R) NANOS;
1258 }
1259 // inline TemporalAccessor.super.query(query) as an optimization
1260 // non-JDK classes are not permitted to make this optimization
1261 return query.queryFrom(this);
1262 }
1263
1264 /**
1265 * Adjusts the specified temporal object to have the same time as this object.
1266 * <p>
1267 * This returns a temporal object of the same observable type as the input
1268 * with the time changed to be the same as this.
1269 * <p>
1270 * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)}
1271 * passing {@link ChronoField#NANO_OF_DAY} as the field.
1272 * <p>
1273 * In most cases, it is clearer to reverse the calling pattern by using
1274 * {@link Temporal#with(TemporalAdjuster)}:
1275 * <pre>
1276 * // these two lines are equivalent, but the second approach is recommended
1315 * amount = MINUTES.between(start, end);
1316 * </pre>
1317 * The choice should be made based on which makes the code more readable.
1318 * <p>
1319 * The calculation is implemented in this method for {@link ChronoUnit}.
1320 * The units {@code NANOS}, {@code MICROS}, {@code MILLIS}, {@code SECONDS},
1321 * {@code MINUTES}, {@code HOURS} and {@code HALF_DAYS} are supported.
1322 * Other {@code ChronoUnit} values will throw an exception.
1323 * <p>
1324 * If the unit is not a {@code ChronoUnit}, then the result of this method
1325 * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
1326 * passing {@code this} as the first argument and the input temporal as
1327 * the second argument.
1328 * <p>
1329 * This instance is immutable and unaffected by this method call.
1330 *
1331 * @param endTime the end time, which must be a {@code LocalTime}, not null
1332 * @param unit the unit to measure the period in, not null
1333 * @return the amount of the period between this time and the end time
1334 * @throws DateTimeException if the period cannot be calculated
1335 * @throws UnsupportedTemporalTypeException if the unit is not supported
1336 * @throws ArithmeticException if numeric overflow occurs
1337 */
1338 @Override
1339 public long periodUntil(Temporal endTime, TemporalUnit unit) {
1340 if (endTime instanceof LocalTime == false) {
1341 Objects.requireNonNull(endTime, "endTime");
1342 throw new DateTimeException("Unable to calculate period between objects of two different types");
1343 }
1344 LocalTime end = (LocalTime) endTime;
1345 if (unit instanceof ChronoUnit) {
1346 long nanosUntil = end.toNanoOfDay() - toNanoOfDay(); // no overflow
1347 switch ((ChronoUnit) unit) {
1348 case NANOS: return nanosUntil;
1349 case MICROS: return nanosUntil / 1000;
1350 case MILLIS: return nanosUntil / 1000_000;
1351 case SECONDS: return nanosUntil / NANOS_PER_SECOND;
1352 case MINUTES: return nanosUntil / NANOS_PER_MINUTE;
1353 case HOURS: return nanosUntil / NANOS_PER_HOUR;
1354 case HALF_DAYS: return nanosUntil / (12 * NANOS_PER_HOUR);
1355 }
1356 throw new UnsupportedTemporalTypeException("Unsupported unit: " + unit.getName());
1357 }
1358 return unit.between(this, endTime);
1359 }
1360
1361 /**
1362 * Formats this time using the specified formatter.
1363 * <p>
1364 * This time will be passed to the formatter to produce a string.
1365 *
1366 * @param formatter the formatter to use, not null
1367 * @return the formatted time string, not null
1368 * @throws DateTimeException if an error occurs during printing
1369 */
1370 public String format(DateTimeFormatter formatter) {
1371 Objects.requireNonNull(formatter, "formatter");
1372 return formatter.format(this);
1373 }
1374
1375 //-----------------------------------------------------------------------
1376 /**
1377 * Combines this time with a date to create a {@code LocalDateTime}.
1378 * <p>
1379 * This returns a {@code LocalDateTime} formed from this time at the specified date.
1380 * All possible combinations of date and time are valid.
1381 *
1382 * @param date the date to combine with, not null
1383 * @return the local date-time formed from this time and the specified date, not null
1384 */
1385 public LocalDateTime atDate(LocalDate date) {
1386 return LocalDateTime.of(date, this);
1387 }
1388
1389 /**
1390 * Combines this time with an offset to create an {@code OffsetTime}.
1391 * <p>
1392 * This returns an {@code OffsetTime} formed from this time at the specified offset.
1393 * All possible combinations of time and offset are valid.
1394 *
1395 * @param offset the offset to combine with, not null
1396 * @return the offset time formed from this time and the specified offset, not null
1397 */
1398 public OffsetTime atOffset(ZoneOffset offset) {
1399 return OffsetTime.of(this, offset);
1400 }
1401
1402 //-----------------------------------------------------------------------
1403 /**
1404 * Extracts the time as seconds of day,
1405 * from {@code 0} to {@code 24 * 60 * 60 - 1}.
1406 *
1407 * @return the second-of-day equivalent to this time
1408 */
1409 public int toSecondOfDay() {
1410 int total = hour * SECONDS_PER_HOUR;
1541 int secondValue = second;
1542 int nanoValue = nano;
1543 buf.append(hourValue < 10 ? "0" : "").append(hourValue)
1544 .append(minuteValue < 10 ? ":0" : ":").append(minuteValue);
1545 if (secondValue > 0 || nanoValue > 0) {
1546 buf.append(secondValue < 10 ? ":0" : ":").append(secondValue);
1547 if (nanoValue > 0) {
1548 buf.append('.');
1549 if (nanoValue % 1000_000 == 0) {
1550 buf.append(Integer.toString((nanoValue / 1000_000) + 1000).substring(1));
1551 } else if (nanoValue % 1000 == 0) {
1552 buf.append(Integer.toString((nanoValue / 1000) + 1000_000).substring(1));
1553 } else {
1554 buf.append(Integer.toString((nanoValue) + 1000_000_000).substring(1));
1555 }
1556 }
1557 }
1558 return buf.toString();
1559 }
1560
1561 //-----------------------------------------------------------------------
1562 /**
1563 * Writes the object using a
1564 * <a href="../../serialized-form.html#java.time.Ser">dedicated serialized form</a>.
1565 * <pre>
1566 * out.writeByte(4); // identifies this as a LocalTime
1567 * if (nano == 0) {
1568 * if (second == 0) {
1569 * if (minute == 0) {
1570 * out.writeByte(~hour);
1571 * } else {
1572 * out.writeByte(hour);
1573 * out.writeByte(~minute);
1574 * }
1575 * } else {
1576 * out.writeByte(hour);
1577 * out.writeByte(minute);
1578 * out.writeByte(~second);
1579 * }
1580 * } else {
|