src/share/classes/java/time/chrono/ChronoLocalDateTime.java
Print this page
@@ -71,11 +71,10 @@
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
-import java.time.temporal.Queries;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalField;
@@ -117,33 +116,61 @@
*/
public interface ChronoLocalDateTime<D extends ChronoLocalDate<D>>
extends Temporal, TemporalAdjuster, Comparable<ChronoLocalDateTime<?>> {
/**
- * Comparator for two {@code ChronoLocalDateTime} instances ignoring the chronology.
+ * Gets a comparator that compares {@code ChronoLocalDateTime} in
+ * time-line order ignoring the chronology.
* <p>
- * This method differs from the comparison in {@link #compareTo} in that it
- * only compares the underlying date and not the chronology.
+ * This comparator differs from the comparison in {@link #compareTo} in that it
+ * only compares the underlying date-time and not the chronology.
* This allows dates in different calendar systems to be compared based
- * on the time-line position.
+ * on the position of the date-time on the local time-line.
+ * The underlying comparison is equivalent to comparing the epoch-day and nano-of-day.
*
* @see #isAfter
* @see #isBefore
* @see #isEqual
*/
- Comparator<ChronoLocalDateTime<?>> DATE_TIME_COMPARATOR =
- new Comparator<ChronoLocalDateTime<?>>() {
- @Override
- public int compare(ChronoLocalDateTime<?> datetime1, ChronoLocalDateTime<?> datetime2) {
- int cmp = Long.compare(datetime1.toLocalDate().toEpochDay(), datetime2.toLocalDate().toEpochDay());
- if (cmp == 0) {
- cmp = Long.compare(datetime1.toLocalTime().toNanoOfDay(), datetime2.toLocalTime().toNanoOfDay());
+ static Comparator<ChronoLocalDateTime<?>> timeLineOrder() {
+ return Chronology.DATE_TIME_ORDER;
}
- return cmp;
+
+ //-----------------------------------------------------------------------
+ /**
+ * Obtains an instance of {@code ChronoLocalDateTime} from a temporal object.
+ * <p>
+ * This obtains a local date-time based on the specified temporal.
+ * A {@code TemporalAccessor} represents an arbitrary set of date and time information,
+ * which this factory converts to an instance of {@code ChronoLocalDateTime}.
+ * <p>
+ * The conversion extracts and combines the chronology and the date-time
+ * from the temporal object. The behavior is equivalent to using
+ * {@link Chronology#localDateTime(TemporalAccessor)} with the extracted chronology.
+ * Implementations are permitted to perform optimizations such as accessing
+ * those fields that are equivalent to the relevant objects.
+ * <p>
+ * This method matches the signature of the functional interface {@link TemporalQuery}
+ * allowing it to be used as a query via method reference, {@code ChronoLocalDateTime::from}.
+ *
+ * @param temporal the temporal object to convert, not null
+ * @return the date-time, not null
+ * @throws DateTimeException if unable to convert to a {@code ChronoLocalDateTime}
+ * @see Chronology#localDateTime(TemporalAccessor)
+ */
+ static ChronoLocalDateTime<?> from(TemporalAccessor temporal) {
+ if (temporal instanceof ChronoLocalDateTime) {
+ return (ChronoLocalDateTime<?>) temporal;
+ }
+ Chronology chrono = temporal.query(TemporalQuery.chronology());
+ if (chrono == null) {
+ throw new DateTimeException("Unable to obtain ChronoLocalDateTime from TemporalAccessor: " + temporal.getClass());
+ }
+ return chrono.localDateTime(temporal);
}
- };
+ //-----------------------------------------------------------------------
/**
* Gets the local date part of this date-time.
* <p>
* This returns a local date with the same year, month and day
* as this date-time.
@@ -161,21 +188,21 @@
* @return the time part of this date-time, not null
*/
LocalTime toLocalTime();
@Override // Override to provide javadoc
- public boolean isSupported(TemporalField field);
+ boolean isSupported(TemporalField field);
//-----------------------------------------------------------------------
// override for covariant return type
/**
* {@inheritDoc}
* @throws DateTimeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
- public default ChronoLocalDateTime<D> with(TemporalAdjuster adjuster) {
+ default ChronoLocalDateTime<D> with(TemporalAdjuster adjuster) {
return (ChronoLocalDateTime<D>)(toLocalDate().getChronology().ensureChronoLocalDateTime(Temporal.super.with(adjuster)));
}
/**
* {@inheritDoc}
@@ -189,11 +216,11 @@
* {@inheritDoc}
* @throws DateTimeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
- public default ChronoLocalDateTime<D> plus(TemporalAmount amount) {
+ default ChronoLocalDateTime<D> plus(TemporalAmount amount) {
return (ChronoLocalDateTime<D>)(toLocalDate().getChronology().ensureChronoLocalDateTime(Temporal.super.plus(amount)));
}
/**
* {@inheritDoc}
@@ -207,21 +234,21 @@
* {@inheritDoc}
* @throws DateTimeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
- public default ChronoLocalDateTime<D> minus(TemporalAmount amount) {
+ default ChronoLocalDateTime<D> minus(TemporalAmount amount) {
return (ChronoLocalDateTime<D>)(toLocalDate().getChronology().ensureChronoLocalDateTime(Temporal.super.minus(amount)));
}
/**
* {@inheritDoc}
* @throws DateTimeException {@inheritDoc}
* @throws ArithmeticException {@inheritDoc}
*/
@Override
- public default ChronoLocalDateTime<D> minus(long amountToSubtract, TemporalUnit unit) {
+ default ChronoLocalDateTime<D> minus(long amountToSubtract, TemporalUnit unit) {
return (ChronoLocalDateTime<D>)(toLocalDate().getChronology().ensureChronoLocalDateTime(Temporal.super.minus(amountToSubtract, unit)));
}
//-----------------------------------------------------------------------
/**
@@ -242,18 +269,18 @@
* @throws DateTimeException if unable to query (defined by the query)
* @throws ArithmeticException if numeric overflow occurs (defined by the query)
*/
@SuppressWarnings("unchecked")
@Override
- public default <R> R query(TemporalQuery<R> query) {
- if (query == Queries.zoneId() || query == Queries.zone() || query == Queries.offset()) {
+ default <R> R query(TemporalQuery<R> query) {
+ if (query == TemporalQuery.zoneId() || query == TemporalQuery.zone() || query == TemporalQuery.offset()) {
return null;
- } else if (query == Queries.localTime()) {
+ } else if (query == TemporalQuery.localTime()) {
return (R) toLocalTime();
- } else if (query == Queries.chronology()) {
+ } else if (query == TemporalQuery.chronology()) {
return (R) toLocalDate().getChronology();
- } else if (query == Queries.precision()) {
+ } else if (query == TemporalQuery.precision()) {
return (R) NANOS;
}
// inline TemporalAccessor.super.query(query) as an optimization
// non-JDK classes are not permitted to make this optimization
return query.queryFrom(this);
@@ -283,16 +310,35 @@
* @return the adjusted object, not null
* @throws DateTimeException if unable to make the adjustment
* @throws ArithmeticException if numeric overflow occurs
*/
@Override
- public default Temporal adjustInto(Temporal temporal) {
+ default Temporal adjustInto(Temporal temporal) {
return temporal
.with(EPOCH_DAY, toLocalDate().toEpochDay())
.with(NANO_OF_DAY, toLocalTime().toNanoOfDay());
}
+ /**
+ * Formats this date-time using the specified formatter.
+ * <p>
+ * This date-time will be passed to the formatter to produce a string.
+ * <p>
+ * The default implementation must behave as follows:
+ * <pre>
+ * return formatter.format(this);
+ * </pre>
+ *
+ * @param formatter the formatter to use, not null
+ * @return the formatted date-time string, not null
+ * @throws DateTimeException if an error occurs during printing
+ */
+ default String format(DateTimeFormatter formatter) {
+ Objects.requireNonNull(formatter, "formatter");
+ return formatter.format(this);
+ }
+
//-----------------------------------------------------------------------
/**
* Combines this time with a time-zone to create a {@code ChronoZonedDateTime}.
* <p>
* This returns a {@code ChronoZonedDateTime} formed from this date-time at the
@@ -332,11 +378,11 @@
* second-of-day of the time.
*
* @param offset the offset to use for the conversion, not null
* @return an {@code Instant} representing the same instant, not null
*/
- public default Instant toInstant(ZoneOffset offset) {
+ default Instant toInstant(ZoneOffset offset) {
return Instant.ofEpochSecond(toEpochSecond(offset), toLocalTime().getNano());
}
/**
* Converts this date-time to the number of seconds from the epoch
@@ -350,11 +396,11 @@
* second-of-day of the time.
*
* @param offset the offset to use for the conversion, not null
* @return the number of seconds from the epoch of 1970-01-01T00:00:00Z
*/
- public default long toEpochSecond(ZoneOffset offset) {
+ default long toEpochSecond(ZoneOffset offset) {
Objects.requireNonNull(offset, "offset");
long epochDay = toLocalDate().toEpochDay();
long secs = epochDay * 86400 + toLocalTime().toSecondOfDay();
secs -= offset.getTotalSeconds();
return secs;
@@ -386,11 +432,11 @@
*
* @param other the other date-time to compare to, not null
* @return the comparator value, negative if less, positive if greater
*/
@Override
- public default int compareTo(ChronoLocalDateTime<?> other) {
+ default int compareTo(ChronoLocalDateTime<?> other) {
int cmp = toLocalDate().compareTo(other.toLocalDate());
if (cmp == 0) {
cmp = toLocalTime().compareTo(other.toLocalTime());
if (cmp == 0) {
cmp = toLocalDate().getChronology().compareTo(other.toLocalDate().getChronology());
@@ -411,11 +457,11 @@
* and nano-of-day.
*
* @param other the other date-time to compare to, not null
* @return true if this is after the specified date-time
*/
- public default boolean isAfter(ChronoLocalDateTime<?> other) {
+ default boolean isAfter(ChronoLocalDateTime<?> other) {
long thisEpDay = this.toLocalDate().toEpochDay();
long otherEpDay = other.toLocalDate().toEpochDay();
return thisEpDay > otherEpDay ||
(thisEpDay == otherEpDay && this.toLocalTime().toNanoOfDay() > other.toLocalTime().toNanoOfDay());
}
@@ -432,11 +478,11 @@
* and nano-of-day.
*
* @param other the other date-time to compare to, not null
* @return true if this is before the specified date-time
*/
- public default boolean isBefore(ChronoLocalDateTime<?> other) {
+ default boolean isBefore(ChronoLocalDateTime<?> other) {
long thisEpDay = this.toLocalDate().toEpochDay();
long otherEpDay = other.toLocalDate().toEpochDay();
return thisEpDay < otherEpDay ||
(thisEpDay == otherEpDay && this.toLocalTime().toNanoOfDay() < other.toLocalTime().toNanoOfDay());
}
@@ -453,11 +499,11 @@
* and nano-of-day.
*
* @param other the other date-time to compare to, not null
* @return true if the underlying date-time is equal to the specified date-time on the timeline
*/
- public default boolean isEqual(ChronoLocalDateTime<?> other) {
+ default boolean isEqual(ChronoLocalDateTime<?> other) {
// Do the time check first, it is cheaper than computing EPOCH day.
return this.toLocalTime().toNanoOfDay() == other.toLocalTime().toNanoOfDay() &&
this.toLocalDate().toEpochDay() == other.toLocalDate().toEpochDay();
}
@@ -482,29 +528,13 @@
//-----------------------------------------------------------------------
/**
* Outputs this date-time as a {@code String}.
* <p>
- * The output will include the full local date-time and the chronology ID.
+ * The output will include the full local date-time.
*
* @return a string representation of this date-time, not null
*/
@Override
String toString();
- /**
- * Outputs this date-time as a {@code String} using the formatter.
- * <p>
- * The default implementation must behave as follows:
- * <pre>
- * return formatter.format(this);
- * </pre>
- *
- * @param formatter the formatter to use, not null
- * @return the formatted date-time string, not null
- * @throws DateTimeException if an error occurs during printing
- */
- public default String toString(DateTimeFormatter formatter) {
- Objects.requireNonNull(formatter, "formatter");
- return formatter.format(this);
- }
}