45 * 46 * * Neither the name of JSR-310 nor the names of its contributors 47 * may be used to endorse or promote products derived from this software 48 * without specific prior written permission. 49 * 50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 54 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 55 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 56 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 57 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 58 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 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. 61 */ 62 package java.time.temporal; 63 64 import java.time.DateTimeException; 65 66 /** 67 * Strategy for querying a temporal object. 68 * <p> 69 * Queries are a key tool for extracting information from temporal objects. 70 * They exist to externalize the process of querying, permitting different 71 * approaches, as per the strategy design pattern. 72 * Examples might be a query that checks if the date is the day before February 29th 73 * in a leap year, or calculates the number of days to your next birthday. 74 * <p> 75 * The {@link TemporalField} interface provides another mechanism for querying 76 * temporal objects. That interface is limited to returning a {@code long}. 77 * By contrast, queries can return any type. 78 * <p> 79 * There are two equivalent ways of using a {@code TemporalQuery}. 80 * The first is to invoke the method on this interface directly. 81 * The second is to use {@link TemporalAccessor#query(TemporalQuery)}: 82 * <pre> 83 * // these two lines are equivalent, but the second approach is recommended 84 * temporal = thisQuery.queryFrom(temporal); 85 * temporal = temporal.query(thisQuery); 86 * </pre> 87 * It is recommended to use the second approach, {@code query(TemporalQuery)}, 88 * as it is a lot clearer to read in code. 89 * <p> 90 * The most common implementations are method references, such as 91 * {@code LocalDate::from} and {@code ZoneId::from}. 92 * Further implementations are on {@link Queries}. 93 * Queries may also be defined by applications. 94 * 95 * <h3>Specification for implementors</h3> 96 * This interface places no restrictions on the mutability of implementations, 97 * however immutability is strongly recommended. 98 * 99 * @since 1.8 100 */ 101 @FunctionalInterface 102 public interface TemporalQuery<R> { 103 104 /** 105 * Queries the specified temporal object. 106 * <p> 107 * This queries the specified temporal object to return an object using the logic 108 * encapsulated in the implementing class. 109 * Examples might be a query that checks if the date is the day before February 29th 110 * in a leap year, or calculates the number of days to your next birthday. 111 * <p> 112 * There are two equivalent ways of using this method. 113 * The first is to invoke this method directly. 114 * The second is to use {@link TemporalAccessor#query(TemporalQuery)}: 115 * <pre> 116 * // these two lines are equivalent, but the second approach is recommended 117 * temporal = thisQuery.queryFrom(temporal); 118 * temporal = temporal.query(thisQuery); 119 * </pre> 120 * It is recommended to use the second approach, {@code query(TemporalQuery)}, 121 * as it is a lot clearer to read in code. 122 * 123 * <h3>Specification for implementors</h3> 124 * The implementation must take the input object and query it. 125 * The implementation defines the logic of the query and is responsible for 126 * documenting that logic. 127 * It may use any method on {@code TemporalAccessor} to determine the result. 128 * The input object must not be altered. 129 * <p> 130 * The input temporal object may be in a calendar system other than ISO. 131 * Implementations may choose to document compatibility with other calendar systems, 132 * or reject non-ISO temporal objects by {@link Queries#chronology() querying the chronology}. 133 * <p> 134 * This method may be called from multiple threads in parallel. 135 * It must be thread-safe when invoked. 136 * 137 * @param temporal the temporal object to query, not null 138 * @return the queried value, may return null to indicate not found 139 * @throws DateTimeException if unable to query 140 * @throws ArithmeticException if numeric overflow occurs 141 */ 142 R queryFrom(TemporalAccessor temporal); 143 144 } | 45 * 46 * * Neither the name of JSR-310 nor the names of its contributors 47 * may be used to endorse or promote products derived from this software 48 * without specific prior written permission. 49 * 50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 54 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 55 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 56 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 57 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 58 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 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. 61 */ 62 package java.time.temporal; 63 64 import java.time.DateTimeException; 65 import java.time.LocalDate; 66 import java.time.LocalTime; 67 import java.time.ZoneId; 68 import java.time.ZoneOffset; 69 import java.time.chrono.Chronology; 70 71 /** 72 * Strategy for querying a temporal object. 73 * <p> 74 * Queries are a key tool for extracting information from temporal objects. 75 * They exist to externalize the process of querying, permitting different 76 * approaches, as per the strategy design pattern. 77 * Examples might be a query that checks if the date is the day before February 29th 78 * in a leap year, or calculates the number of days to your next birthday. 79 * <p> 80 * The {@link TemporalField} interface provides another mechanism for querying 81 * temporal objects. That interface is limited to returning a {@code long}. 82 * By contrast, queries can return any type. 83 * <p> 84 * There are two equivalent ways of using a {@code TemporalQuery}. 85 * The first is to invoke the method on this interface directly. 86 * The second is to use {@link TemporalAccessor#query(TemporalQuery)}: 87 * <pre> 88 * // these two lines are equivalent, but the second approach is recommended 89 * temporal = thisQuery.queryFrom(temporal); 90 * temporal = temporal.query(thisQuery); 91 * </pre> 92 * It is recommended to use the second approach, {@code query(TemporalQuery)}, 93 * as it is a lot clearer to read in code. 94 * <p> 95 * The most common implementations are method references, such as 96 * {@code LocalDate::from} and {@code ZoneId::from}. 97 * Additional common implementations are provided on this interface as static methods. 98 * 99 * <h3>Specification for implementors</h3> 100 * This interface places no restrictions on the mutability of implementations, 101 * however immutability is strongly recommended. 102 * 103 * @since 1.8 104 */ 105 @FunctionalInterface 106 public interface TemporalQuery<R> { 107 108 /** 109 * Queries the specified temporal object. 110 * <p> 111 * This queries the specified temporal object to return an object using the logic 112 * encapsulated in the implementing class. 113 * Examples might be a query that checks if the date is the day before February 29th 114 * in a leap year, or calculates the number of days to your next birthday. 115 * <p> 116 * There are two equivalent ways of using this method. 117 * The first is to invoke this method directly. 118 * The second is to use {@link TemporalAccessor#query(TemporalQuery)}: 119 * <pre> 120 * // these two lines are equivalent, but the second approach is recommended 121 * temporal = thisQuery.queryFrom(temporal); 122 * temporal = temporal.query(thisQuery); 123 * </pre> 124 * It is recommended to use the second approach, {@code query(TemporalQuery)}, 125 * as it is a lot clearer to read in code. 126 * 127 * <h3>Specification for implementors</h3> 128 * The implementation must take the input object and query it. 129 * The implementation defines the logic of the query and is responsible for 130 * documenting that logic. 131 * It may use any method on {@code TemporalAccessor} to determine the result. 132 * The input object must not be altered. 133 * <p> 134 * The input temporal object may be in a calendar system other than ISO. 135 * Implementations may choose to document compatibility with other calendar systems, 136 * or reject non-ISO temporal objects by {@link TemporalQuery#chronology() querying the chronology}. 137 * <p> 138 * This method may be called from multiple threads in parallel. 139 * It must be thread-safe when invoked. 140 * 141 * @param temporal the temporal object to query, not null 142 * @return the queried value, may return null to indicate not found 143 * @throws DateTimeException if unable to query 144 * @throws ArithmeticException if numeric overflow occurs 145 */ 146 R queryFrom(TemporalAccessor temporal); 147 148 //----------------------------------------------------------------------- 149 // special constants should be used to extract information from a TemporalAccessor 150 // that cannot be derived in other ways 151 // Javadoc added here, so as to pretend they are more normal than they really are 152 153 /** 154 * A strict query for the {@code ZoneId}. 155 * <p> 156 * This queries a {@code TemporalAccessor} for the zone. 157 * The zone is only returned if the date-time conceptually contains a {@code ZoneId}. 158 * It will not be returned if the date-time only conceptually has an {@code ZoneOffset}. 159 * Thus a {@link java.time.ZonedDateTime} will return the result of {@code getZone()}, 160 * but an {@link java.time.OffsetDateTime} will return null. 161 * <p> 162 * In most cases, applications should use {@link #zone()} as this query is too strict. 163 * <p> 164 * The result from JDK classes implementing {@code TemporalAccessor} is as follows:<br> 165 * {@code LocalDate} returns null<br> 166 * {@code LocalTime} returns null<br> 167 * {@code LocalDateTime} returns null<br> 168 * {@code ZonedDateTime} returns the associated zone<br> 169 * {@code OffsetTime} returns null<br> 170 * {@code OffsetDateTime} returns null<br> 171 * {@code ChronoLocalDate} returns null<br> 172 * {@code ChronoLocalDateTime} returns null<br> 173 * {@code ChronoZonedDateTime} returns the associated zone<br> 174 * {@code Era} returns null<br> 175 * {@code DayOfWeek} returns null<br> 176 * {@code Month} returns null<br> 177 * {@code Year} returns null<br> 178 * {@code YearMonth} returns null<br> 179 * {@code MonthDay} returns null<br> 180 * {@code ZoneOffset} returns null<br> 181 * {@code Instant} returns null<br> 182 * 183 * @return a query that can obtain the zone ID of a temporal, not null 184 */ 185 static TemporalQuery<ZoneId> zoneId() { 186 return TemporalQueries.ZONE_ID; 187 } 188 189 /** 190 * A query for the {@code Chronology}. 191 * <p> 192 * This queries a {@code TemporalAccessor} for the chronology. 193 * If the target {@code TemporalAccessor} represents a date, or part of a date, 194 * then it should return the chronology that the date is expressed in. 195 * As a result of this definition, objects only representing time, such as 196 * {@code LocalTime}, will return null. 197 * <p> 198 * The result from JDK classes implementing {@code TemporalAccessor} is as follows:<br> 199 * {@code LocalDate} returns {@code IsoChronology.INSTANCE}<br> 200 * {@code LocalTime} returns null (does not represent a date)<br> 201 * {@code LocalDateTime} returns {@code IsoChronology.INSTANCE}<br> 202 * {@code ZonedDateTime} returns {@code IsoChronology.INSTANCE}<br> 203 * {@code OffsetTime} returns null (does not represent a date)<br> 204 * {@code OffsetDateTime} returns {@code IsoChronology.INSTANCE}<br> 205 * {@code ChronoLocalDate} returns the associated chronology<br> 206 * {@code ChronoLocalDateTime} returns the associated chronology<br> 207 * {@code ChronoZonedDateTime} returns the associated chronology<br> 208 * {@code Era} returns the associated chronology<br> 209 * {@code DayOfWeek} returns null (shared across chronologies)<br> 210 * {@code Month} returns {@code IsoChronology.INSTANCE}<br> 211 * {@code Year} returns {@code IsoChronology.INSTANCE}<br> 212 * {@code YearMonth} returns {@code IsoChronology.INSTANCE}<br> 213 * {@code MonthDay} returns null {@code IsoChronology.INSTANCE}<br> 214 * {@code ZoneOffset} returns null (does not represent a date)<br> 215 * {@code Instant} returns null (does not represent a date)<br> 216 * <p> 217 * The method {@link java.time.chrono.Chronology#from(TemporalAccessor)} can be used as a 218 * {@code TemporalQuery} via a method reference, {@code Chronology::from}. 219 * That method is equivalent to this query, except that it throws an 220 * exception if a chronology cannot be obtained. 221 * 222 * @return a query that can obtain the chronology of a temporal, not null 223 */ 224 static TemporalQuery<Chronology> chronology() { 225 return TemporalQueries.CHRONO; 226 } 227 228 /** 229 * A query for the smallest supported unit. 230 * <p> 231 * This queries a {@code TemporalAccessor} for the time precision. 232 * If the target {@code TemporalAccessor} represents a consistent or complete date-time, 233 * date or time then this must return the smallest precision actually supported. 234 * Note that fields such as {@code NANO_OF_DAY} and {@code NANO_OF_SECOND} 235 * are defined to always return ignoring the precision, thus this is the only 236 * way to find the actual smallest supported unit. 237 * For example, were {@code GregorianCalendar} to implement {@code TemporalAccessor} 238 * it would return a precision of {@code MILLIS}. 239 * <p> 240 * The result from JDK classes implementing {@code TemporalAccessor} is as follows:<br> 241 * {@code LocalDate} returns {@code DAYS}<br> 242 * {@code LocalTime} returns {@code NANOS}<br> 243 * {@code LocalDateTime} returns {@code NANOS}<br> 244 * {@code ZonedDateTime} returns {@code NANOS}<br> 245 * {@code OffsetTime} returns {@code NANOS}<br> 246 * {@code OffsetDateTime} returns {@code NANOS}<br> 247 * {@code ChronoLocalDate} returns {@code DAYS}<br> 248 * {@code ChronoLocalDateTime} returns {@code NANOS}<br> 249 * {@code ChronoZonedDateTime} returns {@code NANOS}<br> 250 * {@code Era} returns {@code ERAS}<br> 251 * {@code DayOfWeek} returns {@code DAYS}<br> 252 * {@code Month} returns {@code MONTHS}<br> 253 * {@code Year} returns {@code YEARS}<br> 254 * {@code YearMonth} returns {@code MONTHS}<br> 255 * {@code MonthDay} returns null (does not represent a complete date or time)<br> 256 * {@code ZoneOffset} returns null (does not represent a date or time)<br> 257 * {@code Instant} returns {@code NANOS}<br> 258 * 259 * @return a query that can obtain the precision of a temporal, not null 260 */ 261 static TemporalQuery<TemporalUnit> precision() { 262 return TemporalQueries.PRECISION; 263 } 264 265 //----------------------------------------------------------------------- 266 // non-special constants are standard queries that derive information from other information 267 /** 268 * A lenient query for the {@code ZoneId}, falling back to the {@code ZoneOffset}. 269 * <p> 270 * This queries a {@code TemporalAccessor} for the zone. 271 * It first tries to obtain the zone, using {@link #zoneId()}. 272 * If that is not found it tries to obtain the {@link #offset()}. 273 * Thus a {@link java.time.ZonedDateTime} will return the result of {@code getZone()}, 274 * while an {@link java.time.OffsetDateTime} will return the result of {@code getOffset()}. 275 * <p> 276 * In most cases, applications should use this query rather than {@code #zoneId()}. 277 * <p> 278 * The method {@link ZoneId#from(TemporalAccessor)} can be used as a 279 * {@code TemporalQuery} via a method reference, {@code ZoneId::from}. 280 * That method is equivalent to this query, except that it throws an 281 * exception if a zone cannot be obtained. 282 * 283 * @return a query that can obtain the zone ID or offset of a temporal, not null 284 */ 285 static TemporalQuery<ZoneId> zone() { 286 return TemporalQueries.ZONE; 287 } 288 289 /** 290 * A query for {@code ZoneOffset} returning null if not found. 291 * <p> 292 * This returns a {@code TemporalQuery} that can be used to query a temporal 293 * object for the offset. The query will return null if the temporal 294 * object cannot supply an offset. 295 * <p> 296 * The query implementation examines the {@link ChronoField#OFFSET_SECONDS OFFSET_SECONDS} 297 * field and uses it to create a {@code ZoneOffset}. 298 * <p> 299 * The method {@link java.time.ZoneOffset#from(TemporalAccessor)} can be used as a 300 * {@code TemporalQuery} via a method reference, {@code ZoneOffset::from}. 301 * This query and {@code ZoneOffset::from} will return the same result if the 302 * temporal object contains an offset. If the temporal object does not contain 303 * an offset, then the method reference will throw an exception, whereas this 304 * query will return null. 305 * 306 * @return a query that can obtain the offset of a temporal, not null 307 */ 308 static TemporalQuery<ZoneOffset> offset() { 309 return TemporalQueries.OFFSET; 310 } 311 312 /** 313 * A query for {@code LocalDate} returning null if not found. 314 * <p> 315 * This returns a {@code TemporalQuery} that can be used to query a temporal 316 * object for the local date. The query will return null if the temporal 317 * object cannot supply a local date. 318 * <p> 319 * The query implementation examines the {@link ChronoField#EPOCH_DAY EPOCH_DAY} 320 * field and uses it to create a {@code LocalDate}. 321 * <p> 322 * The method {@link ZoneOffset#from(TemporalAccessor)} can be used as a 323 * {@code TemporalQuery} via a method reference, {@code LocalDate::from}. 324 * This query and {@code LocalDate::from} will return the same result if the 325 * temporal object contains a date. If the temporal object does not contain 326 * a date, then the method reference will throw an exception, whereas this 327 * query will return null. 328 * 329 * @return a query that can obtain the date of a temporal, not null 330 */ 331 static TemporalQuery<LocalDate> localDate() { 332 return TemporalQueries.LOCAL_DATE; 333 } 334 335 /** 336 * A query for {@code LocalTime} returning null if not found. 337 * <p> 338 * This returns a {@code TemporalQuery} that can be used to query a temporal 339 * object for the local time. The query will return null if the temporal 340 * object cannot supply a local time. 341 * <p> 342 * The query implementation examines the {@link ChronoField#NANO_OF_DAY NANO_OF_DAY} 343 * field and uses it to create a {@code LocalTime}. 344 * <p> 345 * The method {@link ZoneOffset#from(TemporalAccessor)} can be used as a 346 * {@code TemporalQuery} via a method reference, {@code LocalTime::from}. 347 * This query and {@code LocalTime::from} will return the same result if the 348 * temporal object contains a time. If the temporal object does not contain 349 * a time, then the method reference will throw an exception, whereas this 350 * query will return null. 351 * 352 * @return a query that can obtain the time of a temporal, not null 353 */ 354 static TemporalQuery<LocalTime> localTime() { 355 return TemporalQueries.LOCAL_TIME; 356 } 357 358 } |