jdk/src/share/classes/java/time/temporal/Queries.java
changeset 15658 55b829ca2334
parent 15289 3ac550392e43
equal deleted inserted replaced
15657:c588664d547e 15658:55b829ca2334
    59  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    59  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    60  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    60  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    61  */
    61  */
    62 package java.time.temporal;
    62 package java.time.temporal;
    63 
    63 
       
    64 import static java.time.temporal.ChronoField.EPOCH_DAY;
       
    65 import static java.time.temporal.ChronoField.NANO_OF_DAY;
    64 import static java.time.temporal.ChronoField.OFFSET_SECONDS;
    66 import static java.time.temporal.ChronoField.OFFSET_SECONDS;
    65 
    67 
       
    68 import java.time.LocalDate;
       
    69 import java.time.LocalTime;
       
    70 import java.time.OffsetDateTime;
    66 import java.time.ZoneId;
    71 import java.time.ZoneId;
    67 import java.time.ZoneOffset;
    72 import java.time.ZoneOffset;
       
    73 import java.time.ZonedDateTime;
       
    74 import java.time.chrono.Chronology;
    68 
    75 
    69 /**
    76 /**
    70  * Common implementations of {@code TemporalQuery}.
    77  * Common implementations of {@code TemporalQuery}.
    71  * <p>
    78  * <p>
    72  * This class provides common implementations of {@link TemporalQuery}.
    79  * This class provides common implementations of {@link TemporalQuery}.
   114      * A strict query for the {@code ZoneId}.
   121      * A strict query for the {@code ZoneId}.
   115      * <p>
   122      * <p>
   116      * This queries a {@code TemporalAccessor} for the zone.
   123      * This queries a {@code TemporalAccessor} for the zone.
   117      * The zone is only returned if the date-time conceptually contains a {@code ZoneId}.
   124      * The zone is only returned if the date-time conceptually contains a {@code ZoneId}.
   118      * It will not be returned if the date-time only conceptually has an {@code ZoneOffset}.
   125      * It will not be returned if the date-time only conceptually has an {@code ZoneOffset}.
   119      * Thus a {@link java.time.ZonedDateTime ZonedDateTime} will return the result of
   126      * Thus a {@link ZonedDateTime} will return the result of {@code getZone()},
   120      * {@code getZone()}, but an {@link java.time.temporal.OffsetDateTime OffsetDateTime} will
   127      * but an {@link OffsetDateTime} will return null.
   121      * return null.
       
   122      * <p>
   128      * <p>
   123      * In most cases, applications should use {@link #ZONE} as this query is too strict.
   129      * In most cases, applications should use {@link #ZONE} as this query is too strict.
   124      * <p>
   130      * <p>
   125      * The result from JDK classes implementing {@code TemporalAccessor} is as follows:<br>
   131      * The result from JDK classes implementing {@code TemporalAccessor} is as follows:<br>
   126      * {@code LocalDate} returns null<br>
   132      * {@code LocalDate} returns null<br>
   127      * {@code LocalTime} returns null<br>
   133      * {@code LocalTime} returns null<br>
   128      * {@code LocalDateTime} returns null<br>
   134      * {@code LocalDateTime} returns null<br>
   129      * {@code ZonedDateTime} returns the associated zone<br>
   135      * {@code ZonedDateTime} returns the associated zone<br>
   130      * {@code OffsetDate} returns null<br>
       
   131      * {@code OffsetTime} returns null<br>
   136      * {@code OffsetTime} returns null<br>
   132      * {@code OffsetDateTime} returns null<br>
   137      * {@code OffsetDateTime} returns null<br>
   133      * {@code ChronoLocalDate} returns null<br>
   138      * {@code ChronoLocalDate} returns null<br>
   134      * {@code ChronoLocalDateTime} returns null<br>
   139      * {@code ChronoLocalDateTime} returns null<br>
   135      * {@code ChronoZonedDateTime} returns the associated zone<br>
   140      * {@code ChronoZonedDateTime} returns the associated zone<br>
   139      * {@code Year} returns null<br>
   144      * {@code Year} returns null<br>
   140      * {@code YearMonth} returns null<br>
   145      * {@code YearMonth} returns null<br>
   141      * {@code MonthDay} returns null<br>
   146      * {@code MonthDay} returns null<br>
   142      * {@code ZoneOffset} returns null<br>
   147      * {@code ZoneOffset} returns null<br>
   143      * {@code Instant} returns null<br>
   148      * {@code Instant} returns null<br>
   144      * @return a ZoneId, may be null
   149      *
       
   150      * @return a query that can obtain the zone ID of a temporal, not null
   145      */
   151      */
   146     public static final TemporalQuery<ZoneId> zoneId() {
   152     public static final TemporalQuery<ZoneId> zoneId() {
   147         return ZONE_ID;
   153         return ZONE_ID;
   148     }
   154     }
   149     static final TemporalQuery<ZoneId> ZONE_ID = new TemporalQuery<ZoneId>() {
   155     static final TemporalQuery<ZoneId> ZONE_ID = (temporal) -> {
   150         @Override
   156         return temporal.query(ZONE_ID);
   151         public ZoneId queryFrom(TemporalAccessor temporal) {
   157     };
   152             return temporal.query(this);
   158 
   153         }
   159     /**
   154     };
   160      * A query for the {@code Chronology}.
   155 
       
   156     /**
       
   157      * A query for the {@code Chrono}.
       
   158      * <p>
   161      * <p>
   159      * This queries a {@code TemporalAccessor} for the chronology.
   162      * This queries a {@code TemporalAccessor} for the chronology.
   160      * If the target {@code TemporalAccessor} represents a date, or part of a date,
   163      * If the target {@code TemporalAccessor} represents a date, or part of a date,
   161      * then it should return the chronology that the date is expressed in.
   164      * then it should return the chronology that the date is expressed in.
   162      * As a result of this definition, objects only representing time, such as
   165      * As a result of this definition, objects only representing time, such as
   163      * {@code LocalTime}, will return null.
   166      * {@code LocalTime}, will return null.
   164      * <p>
   167      * <p>
   165      * The result from JDK classes implementing {@code TemporalAccessor} is as follows:<br>
   168      * The result from JDK classes implementing {@code TemporalAccessor} is as follows:<br>
   166      * {@code LocalDate} returns {@code ISOChrono.INSTANCE}<br>
   169      * {@code LocalDate} returns {@code IsoChronology.INSTANCE}<br>
   167      * {@code LocalTime} returns null (does not represent a date)<br>
   170      * {@code LocalTime} returns null (does not represent a date)<br>
   168      * {@code LocalDateTime} returns {@code ISOChrono.INSTANCE}<br>
   171      * {@code LocalDateTime} returns {@code IsoChronology.INSTANCE}<br>
   169      * {@code ZonedDateTime} returns {@code ISOChrono.INSTANCE}<br>
   172      * {@code ZonedDateTime} returns {@code IsoChronology.INSTANCE}<br>
   170      * {@code OffsetDate} returns {@code ISOChrono.INSTANCE}<br>
       
   171      * {@code OffsetTime} returns null (does not represent a date)<br>
   173      * {@code OffsetTime} returns null (does not represent a date)<br>
   172      * {@code OffsetDateTime} returns {@code ISOChrono.INSTANCE}<br>
   174      * {@code OffsetDateTime} returns {@code IsoChronology.INSTANCE}<br>
   173      * {@code ChronoLocalDate} returns the associated chronology<br>
   175      * {@code ChronoLocalDate} returns the associated chronology<br>
   174      * {@code ChronoLocalDateTime} returns the associated chronology<br>
   176      * {@code ChronoLocalDateTime} returns the associated chronology<br>
   175      * {@code ChronoZonedDateTime} returns the associated chronology<br>
   177      * {@code ChronoZonedDateTime} returns the associated chronology<br>
   176      * {@code Era} returns the associated chronology<br>
   178      * {@code Era} returns the associated chronology<br>
   177      * {@code DayOfWeek} returns null (shared across chronologies)<br>
   179      * {@code DayOfWeek} returns null (shared across chronologies)<br>
   178      * {@code Month} returns {@code ISOChrono.INSTANCE}<br>
   180      * {@code Month} returns {@code IsoChronology.INSTANCE}<br>
   179      * {@code Year} returns {@code ISOChrono.INSTANCE}<br>
   181      * {@code Year} returns {@code IsoChronology.INSTANCE}<br>
   180      * {@code YearMonth} returns {@code ISOChrono.INSTANCE}<br>
   182      * {@code YearMonth} returns {@code IsoChronology.INSTANCE}<br>
   181      * {@code MonthDay} returns null {@code ISOChrono.INSTANCE}<br>
   183      * {@code MonthDay} returns null {@code IsoChronology.INSTANCE}<br>
   182      * {@code ZoneOffset} returns null (does not represent a date)<br>
   184      * {@code ZoneOffset} returns null (does not represent a date)<br>
   183      * {@code Instant} returns null (does not represent a date)<br>
   185      * {@code Instant} returns null (does not represent a date)<br>
   184      * <p>
   186      * <p>
   185      * The method {@link Chrono#from(TemporalAccessor)} can be used as a
   187      * The method {@link Chronology#from(TemporalAccessor)} can be used as a
   186      * {@code TemporalQuery} via a method reference, {@code Chrono::from}.
   188      * {@code TemporalQuery} via a method reference, {@code Chronology::from}.
   187      * That method is equivalent to this query, except that it throws an
   189      * That method is equivalent to this query, except that it throws an
   188      * exception if a chronology cannot be obtained.
   190      * exception if a chronology cannot be obtained.
   189      * @return a Chrono, may be null
   191      *
   190      */
   192      * @return a query that can obtain the chronology of a temporal, not null
   191     public static final TemporalQuery<Chrono<?>> chrono() {
   193      */
       
   194     public static final TemporalQuery<Chronology> chronology() {
   192         return CHRONO;
   195         return CHRONO;
   193     }
   196     }
   194     static final TemporalQuery<Chrono<?>> CHRONO = new TemporalQuery<Chrono<?>>() {
   197     static final TemporalQuery<Chronology> CHRONO = (temporal) -> {
   195         @Override
   198         return temporal.query(CHRONO);
   196         public Chrono<?> queryFrom(TemporalAccessor temporal) {
       
   197             return temporal.query(this);
       
   198         }
       
   199     };
   199     };
   200 
   200 
   201     /**
   201     /**
   202      * A query for the smallest supported unit.
   202      * A query for the smallest supported unit.
   203      * <p>
   203      * <p>
   213      * The result from JDK classes implementing {@code TemporalAccessor} is as follows:<br>
   213      * The result from JDK classes implementing {@code TemporalAccessor} is as follows:<br>
   214      * {@code LocalDate} returns {@code DAYS}<br>
   214      * {@code LocalDate} returns {@code DAYS}<br>
   215      * {@code LocalTime} returns {@code NANOS}<br>
   215      * {@code LocalTime} returns {@code NANOS}<br>
   216      * {@code LocalDateTime} returns {@code NANOS}<br>
   216      * {@code LocalDateTime} returns {@code NANOS}<br>
   217      * {@code ZonedDateTime} returns {@code NANOS}<br>
   217      * {@code ZonedDateTime} returns {@code NANOS}<br>
   218      * {@code OffsetDate} returns {@code DAYS}<br>
       
   219      * {@code OffsetTime} returns {@code NANOS}<br>
   218      * {@code OffsetTime} returns {@code NANOS}<br>
   220      * {@code OffsetDateTime} returns {@code NANOS}<br>
   219      * {@code OffsetDateTime} returns {@code NANOS}<br>
   221      * {@code ChronoLocalDate} returns {@code DAYS}<br>
   220      * {@code ChronoLocalDate} returns {@code DAYS}<br>
   222      * {@code ChronoLocalDateTime} returns {@code NANOS}<br>
   221      * {@code ChronoLocalDateTime} returns {@code NANOS}<br>
   223      * {@code ChronoZonedDateTime} returns {@code NANOS}<br>
   222      * {@code ChronoZonedDateTime} returns {@code NANOS}<br>
   227      * {@code Year} returns {@code YEARS}<br>
   226      * {@code Year} returns {@code YEARS}<br>
   228      * {@code YearMonth} returns {@code MONTHS}<br>
   227      * {@code YearMonth} returns {@code MONTHS}<br>
   229      * {@code MonthDay} returns null (does not represent a complete date or time)<br>
   228      * {@code MonthDay} returns null (does not represent a complete date or time)<br>
   230      * {@code ZoneOffset} returns null (does not represent a date or time)<br>
   229      * {@code ZoneOffset} returns null (does not represent a date or time)<br>
   231      * {@code Instant} returns {@code NANOS}<br>
   230      * {@code Instant} returns {@code NANOS}<br>
   232      * @return a ChronoUnit, may be null
   231      *
   233      */
   232      * @return a query that can obtain the precision of a temporal, not null
   234     public static final TemporalQuery<ChronoUnit> precision() {
   233      */
       
   234     public static final TemporalQuery<TemporalUnit> precision() {
   235         return PRECISION;
   235         return PRECISION;
   236     }
   236     }
   237     static final TemporalQuery<ChronoUnit> PRECISION = new TemporalQuery<ChronoUnit>() {
   237     static final TemporalQuery<TemporalUnit> PRECISION = (temporal) -> {
   238         @Override
   238         return temporal.query(PRECISION);
   239         public ChronoUnit queryFrom(TemporalAccessor temporal) {
       
   240             return temporal.query(this);
       
   241         }
       
   242     };
   239     };
   243 
   240 
   244     //-----------------------------------------------------------------------
   241     //-----------------------------------------------------------------------
   245     // non-special constants are standard queries that derive information from other information
   242     // non-special constants are standard queries that derive information from other information
   246     /**
   243     /**
   247      * A lenient query for the {@code ZoneId}, falling back to the {@code ZoneOffset}.
   244      * A lenient query for the {@code ZoneId}, falling back to the {@code ZoneOffset}.
   248      * <p>
   245      * <p>
   249      * This queries a {@code TemporalAccessor} for the zone.
   246      * This queries a {@code TemporalAccessor} for the zone.
   250      * It first tries to obtain the zone, using {@link #zoneId()}.
   247      * It first tries to obtain the zone, using {@link #zoneId()}.
   251      * If that is not found it tries to obtain the {@link #offset()}.
   248      * If that is not found it tries to obtain the {@link #offset()}.
       
   249      * Thus a {@link ZonedDateTime} will return the result of {@code getZone()},
       
   250      * while an {@link OffsetDateTime} will return the result of {@code getOffset()}.
   252      * <p>
   251      * <p>
   253      * In most cases, applications should use this query rather than {@code #zoneId()}.
   252      * In most cases, applications should use this query rather than {@code #zoneId()}.
   254      * <p>
       
   255      * This query examines the {@link java.time.temporal.ChronoField#OFFSET_SECONDS offset-seconds}
       
   256      * field and uses it to create a {@code ZoneOffset}.
       
   257      * <p>
   253      * <p>
   258      * The method {@link ZoneId#from(TemporalAccessor)} can be used as a
   254      * The method {@link ZoneId#from(TemporalAccessor)} can be used as a
   259      * {@code TemporalQuery} via a method reference, {@code ZoneId::from}.
   255      * {@code TemporalQuery} via a method reference, {@code ZoneId::from}.
   260      * That method is equivalent to this query, except that it throws an
   256      * That method is equivalent to this query, except that it throws an
   261      * exception if a zone cannot be obtained.
   257      * exception if a zone cannot be obtained.
   262      * @return a ZoneId, may be null
   258      *
       
   259      * @return a query that can obtain the zone ID or offset of a temporal, not null
   263      */
   260      */
   264     public static final TemporalQuery<ZoneId> zone() {
   261     public static final TemporalQuery<ZoneId> zone() {
   265         return ZONE;
   262         return ZONE;
   266     }
   263     }
   267     static final TemporalQuery<ZoneId> ZONE = new TemporalQuery<ZoneId>() {
   264     static final TemporalQuery<ZoneId> ZONE = (temporal) -> {
   268         @Override
   265         ZoneId zone = temporal.query(ZONE_ID);
   269         public ZoneId queryFrom(TemporalAccessor temporal) {
   266         return (zone != null ? zone : temporal.query(OFFSET));
   270             ZoneId zone = temporal.query(ZONE_ID);
   267     };
   271             return (zone != null ? zone : temporal.query(OFFSET));
   268 
   272         }
   269     /**
   273     };
   270      * A query for {@code ZoneOffset} returning null if not found.
   274 
   271      * <p>
   275     /**
   272      * This returns a {@code TemporalQuery} that can be used to query a temporal
   276      * A query for the {@code ZoneOffset}.
   273      * object for the offset. The query will return null if the temporal
   277      * <p>
   274      * object cannot supply an offset.
   278      * This queries a {@code TemporalAccessor} for the offset.
   275      * <p>
   279      * <p>
   276      * The query implementation examines the {@link ChronoField#OFFSET_SECONDS OFFSET_SECONDS}
   280      * This query examines the {@link java.time.temporal.ChronoField#OFFSET_SECONDS offset-seconds}
       
   281      * field and uses it to create a {@code ZoneOffset}.
   277      * field and uses it to create a {@code ZoneOffset}.
   282      * <p>
   278      * <p>
   283      * The method {@link ZoneOffset#from(TemporalAccessor)} can be used as a
   279      * The method {@link ZoneOffset#from(TemporalAccessor)} can be used as a
   284      * {@code TemporalQuery} via a method reference, {@code ZoneOffset::from}.
   280      * {@code TemporalQuery} via a method reference, {@code ZoneOffset::from}.
   285      * That method is equivalent to this query, except that it throws an
   281      * This query and {@code ZoneOffset::from} will return the same result if the
   286      * exception if an offset cannot be obtained.
   282      * temporal object contains an offset. If the temporal object does not contain
   287      * @return a ZoneOffset, may be null
   283      * an offset, then the method reference will throw an exception, whereas this
       
   284      * query will return null.
       
   285      *
       
   286      * @return a query that can obtain the offset of a temporal, not null
   288      */
   287      */
   289     public static final TemporalQuery<ZoneOffset> offset() {
   288     public static final TemporalQuery<ZoneOffset> offset() {
   290         return OFFSET;
   289         return OFFSET;
   291     }
   290     }
   292     static final TemporalQuery<ZoneOffset> OFFSET = new TemporalQuery<ZoneOffset>() {
   291     static final TemporalQuery<ZoneOffset> OFFSET = (temporal) -> {
   293         @Override
   292         if (temporal.isSupported(OFFSET_SECONDS)) {
   294         public ZoneOffset queryFrom(TemporalAccessor temporal) {
   293             return ZoneOffset.ofTotalSeconds(temporal.get(OFFSET_SECONDS));
   295             if (temporal.isSupported(OFFSET_SECONDS)) {
       
   296                 return ZoneOffset.ofTotalSeconds(temporal.get(OFFSET_SECONDS));
       
   297             }
       
   298             return null;
       
   299         }
   294         }
       
   295         return null;
       
   296     };
       
   297 
       
   298     /**
       
   299      * A query for {@code LocalDate} returning null if not found.
       
   300      * <p>
       
   301      * This returns a {@code TemporalQuery} that can be used to query a temporal
       
   302      * object for the local date. The query will return null if the temporal
       
   303      * object cannot supply a local date.
       
   304      * <p>
       
   305      * The query implementation examines the {@link ChronoField#EPOCH_DAY EPOCH_DAY}
       
   306      * field and uses it to create a {@code LocalDate}.
       
   307      * <p>
       
   308      * The method {@link ZoneOffset#from(TemporalAccessor)} can be used as a
       
   309      * {@code TemporalQuery} via a method reference, {@code LocalDate::from}.
       
   310      * This query and {@code LocalDate::from} will return the same result if the
       
   311      * temporal object contains a date. If the temporal object does not contain
       
   312      * a date, then the method reference will throw an exception, whereas this
       
   313      * query will return null.
       
   314      *
       
   315      * @return a query that can obtain the date of a temporal, not null
       
   316      */
       
   317     public static final TemporalQuery<LocalDate> localDate() {
       
   318         return LOCAL_DATE;
       
   319     }
       
   320     static final TemporalQuery<LocalDate> LOCAL_DATE = (temporal) -> {
       
   321         if (temporal.isSupported(EPOCH_DAY)) {
       
   322             return LocalDate.ofEpochDay(temporal.getLong(EPOCH_DAY));
       
   323         }
       
   324         return null;
       
   325     };
       
   326 
       
   327     /**
       
   328      * A query for {@code LocalTime} returning null if not found.
       
   329      * <p>
       
   330      * This returns a {@code TemporalQuery} that can be used to query a temporal
       
   331      * object for the local time. The query will return null if the temporal
       
   332      * object cannot supply a local time.
       
   333      * <p>
       
   334      * The query implementation examines the {@link ChronoField#NANO_OF_DAY NANO_OF_DAY}
       
   335      * field and uses it to create a {@code LocalTime}.
       
   336      * <p>
       
   337      * The method {@link ZoneOffset#from(TemporalAccessor)} can be used as a
       
   338      * {@code TemporalQuery} via a method reference, {@code LocalTime::from}.
       
   339      * This query and {@code LocalTime::from} will return the same result if the
       
   340      * temporal object contains a time. If the temporal object does not contain
       
   341      * a time, then the method reference will throw an exception, whereas this
       
   342      * query will return null.
       
   343      *
       
   344      * @return a query that can obtain the time of a temporal, not null
       
   345      */
       
   346     public static final TemporalQuery<LocalTime> localTime() {
       
   347         return LOCAL_TIME;
       
   348     }
       
   349     static final TemporalQuery<LocalTime> LOCAL_TIME = (temporal) -> {
       
   350         if (temporal.isSupported(NANO_OF_DAY)) {
       
   351             return LocalTime.ofNanoOfDay(temporal.getLong(NANO_OF_DAY));
       
   352         }
       
   353         return null;
   300     };
   354     };
   301 
   355 
   302 }
   356 }