jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java
changeset 16852 60207b2b4b42
parent 15658 55b829ca2334
child 17474 8c100beabcc0
--- a/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java	Thu Apr 11 19:15:24 2013 -0700
+++ b/jdk/src/share/classes/java/time/chrono/ChronoZonedDateTime.java	Fri Apr 12 07:57:35 2013 -0700
@@ -73,7 +73,6 @@
 import java.time.ZonedDateTime;
 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;
@@ -81,6 +80,7 @@
 import java.time.temporal.TemporalField;
 import java.time.temporal.TemporalQuery;
 import java.time.temporal.TemporalUnit;
+import java.time.temporal.UnsupportedTemporalTypeException;
 import java.time.temporal.ValueRange;
 import java.util.Comparator;
 import java.util.Objects;
@@ -119,30 +119,59 @@
         extends Temporal, Comparable<ChronoZonedDateTime<?>> {
 
     /**
-     * Comparator for two {@code ChronoZonedDateTime} instances ignoring the chronology.
+     * Gets a comparator that compares {@code ChronoZonedDateTime} 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 instant 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 instant time-line.
+     * The underlying comparison is equivalent to comparing the epoch-second and nano-of-second.
      *
      * @see #isAfter
      * @see #isBefore
      * @see #isEqual
      */
-    Comparator<ChronoZonedDateTime<?>> INSTANT_COMPARATOR = new Comparator<ChronoZonedDateTime<?>>() {
-        @Override
-        public int compare(ChronoZonedDateTime<?> datetime1, ChronoZonedDateTime<?> datetime2) {
-            int cmp = Long.compare(datetime1.toEpochSecond(), datetime2.toEpochSecond());
-            if (cmp == 0) {
-                cmp = Long.compare(datetime1.toLocalTime().toNanoOfDay(), datetime2.toLocalTime().toNanoOfDay());
-            }
-            return cmp;
+    static Comparator<ChronoZonedDateTime<?>> timeLineOrder() {
+        return Chronology.INSTANT_ORDER;
+    }
+
+    //-----------------------------------------------------------------------
+    /**
+     * Obtains an instance of {@code ChronoZonedDateTime} from a temporal object.
+     * <p>
+     * This creates a zoned 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 ChronoZonedDateTime}.
+     * <p>
+     * The conversion extracts and combines the chronology, date, time and zone
+     * from the temporal object. The behavior is equivalent to using
+     * {@link Chronology#zonedDateTime(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 ChronoZonedDateTime::from}.
+     *
+     * @param temporal  the temporal objec t to convert, not null
+     * @return the date-time, not null
+     * @throws DateTimeException if unable to convert to a {@code ChronoZonedDateTime}
+     * @see Chronology#zonedDateTime(TemporalAccessor)
+     */
+    static ChronoZonedDateTime<?> from(TemporalAccessor temporal) {
+        if (temporal instanceof ChronoZonedDateTime) {
+            return (ChronoZonedDateTime<?>) temporal;
         }
-    };
+        Chronology chrono = temporal.query(TemporalQuery.chronology());
+        if (chrono == null) {
+            throw new DateTimeException("Unable to obtain ChronoZonedDateTime from TemporalAccessor: " + temporal.getClass());
+        }
+        return chrono.zonedDateTime(temporal);
+    }
 
+    //-----------------------------------------------------------------------
     @Override
-    public default ValueRange range(TemporalField field) {
+    default ValueRange range(TemporalField field) {
         if (field instanceof ChronoField) {
             if (field == INSTANT_SECONDS || field == OFFSET_SECONDS) {
                 return field.range();
@@ -153,11 +182,13 @@
     }
 
     @Override
-    public default int get(TemporalField field) {
+    default int get(TemporalField field) {
         if (field instanceof ChronoField) {
             switch ((ChronoField) field) {
-                case INSTANT_SECONDS: throw new DateTimeException("Field too large for an int: " + field);
-                case OFFSET_SECONDS: return getOffset().getTotalSeconds();
+                case INSTANT_SECONDS:
+                    throw new UnsupportedTemporalTypeException("Invalid field 'InstantSeconds' for get() method, use getLong() instead");
+                case OFFSET_SECONDS:
+                    return getOffset().getTotalSeconds();
             }
             return toLocalDateTime().get(field);
         }
@@ -165,7 +196,7 @@
     }
 
     @Override
-    public default long getLong(TemporalField field) {
+    default long getLong(TemporalField field) {
         if (field instanceof ChronoField) {
             switch ((ChronoField) field) {
                 case INSTANT_SECONDS: return toEpochSecond();
@@ -184,7 +215,7 @@
      *
      * @return the date part of this date-time, not null
      */
-    public default D toLocalDate() {
+    default D toLocalDate() {
         return toLocalDateTime().toLocalDate();
     }
 
@@ -196,7 +227,7 @@
      *
      * @return the time part of this date-time, not null
      */
-    public default LocalTime toLocalTime() {
+    default LocalTime toLocalTime() {
         return toLocalDateTime().toLocalTime();
     }
 
@@ -306,7 +337,7 @@
     ChronoZonedDateTime<D> withZoneSameInstant(ZoneId zone);
 
     @Override   // Override to provide javadoc
-    public boolean isSupported(TemporalField field);
+    boolean isSupported(TemporalField field);
 
     //-----------------------------------------------------------------------
     // override for covariant return type
@@ -316,7 +347,7 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoZonedDateTime<D> with(TemporalAdjuster adjuster) {
+    default ChronoZonedDateTime<D> with(TemporalAdjuster adjuster) {
         return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(Temporal.super.with(adjuster)));
     }
 
@@ -334,7 +365,7 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoZonedDateTime<D> plus(TemporalAmount amount) {
+    default ChronoZonedDateTime<D> plus(TemporalAmount amount) {
         return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(Temporal.super.plus(amount)));
     }
 
@@ -352,7 +383,7 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoZonedDateTime<D> minus(TemporalAmount amount) {
+    default ChronoZonedDateTime<D> minus(TemporalAmount amount) {
         return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(Temporal.super.minus(amount)));
     }
 
@@ -362,7 +393,7 @@
      * @throws ArithmeticException {@inheritDoc}
      */
     @Override
-    public default ChronoZonedDateTime<D> minus(long amountToSubtract, TemporalUnit unit) {
+    default ChronoZonedDateTime<D> minus(long amountToSubtract, TemporalUnit unit) {
         return (ChronoZonedDateTime<D>)(toLocalDate().getChronology().ensureChronoZonedDateTime(Temporal.super.minus(amountToSubtract, unit)));
     }
 
@@ -387,16 +418,16 @@
      */
     @SuppressWarnings("unchecked")
     @Override
-    public default <R> R query(TemporalQuery<R> query) {
-        if (query == Queries.zone() || query == Queries.zoneId()) {
+    default <R> R query(TemporalQuery<R> query) {
+        if (query == TemporalQuery.zone() || query == TemporalQuery.zoneId()) {
             return (R) getZone();
-        } else if (query == Queries.offset()) {
+        } else if (query == TemporalQuery.offset()) {
             return (R) getOffset();
-        } 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
@@ -404,6 +435,25 @@
         return query.queryFrom(this);
     }
 
+    /**
+     * 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);
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Converts this date-time to an {@code Instant}.
@@ -415,7 +465,7 @@
      *
      * @return an {@code Instant} representing the same instant, not null
      */
-    public default Instant toInstant() {
+    default Instant toInstant() {
         return Instant.ofEpochSecond(toEpochSecond(), toLocalTime().getNano());
     }
 
@@ -430,7 +480,7 @@
      *
      * @return the number of seconds from the epoch of 1970-01-01T00:00:00Z
      */
-    public default long toEpochSecond() {
+    default long toEpochSecond() {
         long epochDay = toLocalDate().toEpochDay();
         long secs = epochDay * 86400 + toLocalTime().toSecondOfDay();
         secs -= getOffset().getTotalSeconds();
@@ -454,7 +504,7 @@
      * @return the comparator value, negative if less, positive if greater
      */
     @Override
-    public default int compareTo(ChronoZonedDateTime<?> other) {
+    default int compareTo(ChronoZonedDateTime<?> other) {
         int cmp = Long.compare(toEpochSecond(), other.toEpochSecond());
         if (cmp == 0) {
             cmp = toLocalTime().getNano() - other.toLocalTime().getNano();
@@ -484,7 +534,7 @@
      * @param other  the other date-time to compare to, not null
      * @return true if this point is before the specified date-time
      */
-    public default boolean isBefore(ChronoZonedDateTime<?> other) {
+    default boolean isBefore(ChronoZonedDateTime<?> other) {
         long thisEpochSec = toEpochSecond();
         long otherEpochSec = other.toEpochSecond();
         return thisEpochSec < otherEpochSec ||
@@ -504,7 +554,7 @@
      * @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(ChronoZonedDateTime<?> other) {
+    default boolean isAfter(ChronoZonedDateTime<?> other) {
         long thisEpochSec = toEpochSecond();
         long otherEpochSec = other.toEpochSecond();
         return thisEpochSec > otherEpochSec ||
@@ -524,7 +574,7 @@
      * @param other  the other date-time to compare to, not null
      * @return true if the instant equals the instant of the specified date-time
      */
-    public default boolean isEqual(ChronoZonedDateTime<?> other) {
+    default boolean isEqual(ChronoZonedDateTime<?> other) {
         return toEpochSecond() == other.toEpochSecond() &&
                 toLocalTime().getNano() == other.toLocalTime().getNano();
     }
@@ -555,28 +605,11 @@
     /**
      * Outputs this date-time as a {@code String}.
      * <p>
-     * The output will include the full zoned date-time and the chronology ID.
+     * The output will include the full zoned 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);
-    }
-
 }