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);
-    }
 }