1 /* 2 * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * This file is available under and governed by the GNU General Public 28 * License version 2 only, as published by the Free Software Foundation. 29 * However, the following notice accompanied the original version of this 30 * file: 31 * 32 * Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos 33 * 34 * All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions are met: 38 * 39 * * Redistributions of source code must retain the above copyright notice, 40 * this list of conditions and the following disclaimer. 41 * 42 * * Redistributions in binary form must reproduce the above copyright notice, 43 * this list of conditions and the following disclaimer in the documentation 44 * and/or other materials provided with the distribution. 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.chrono.Chronology; 66 import java.time.format.ResolverStyle; 67 import java.util.Locale; 68 import java.util.Map; 69 import java.util.Objects; 70 71 /** 72 * A field of date-time, such as month-of-year or hour-of-minute. 73 * <p> 74 * Date and time is expressed using fields which partition the time-line into something 75 * meaningful for humans. Implementations of this interface represent those fields. 76 * <p> 77 * The most commonly used units are defined in {@link ChronoField}. 78 * Further fields are supplied in {@link IsoFields}, {@link WeekFields} and {@link JulianFields}. 79 * Fields can also be written by application code by implementing this interface. 80 * <p> 81 * The field works using double dispatch. Client code calls methods on a date-time like 82 * {@code LocalDateTime} which check if the field is a {@code ChronoField}. 83 * If it is, then the date-time must handle it. 84 * Otherwise, the method call is re-dispatched to the matching method in this interface. 85 * 86 * @implSpec 87 * This interface must be implemented with care to ensure other classes operate correctly. 88 * All implementations that can be instantiated must be final, immutable and thread-safe. 89 * Implementations should be {@code Serializable} where possible. 90 * An enum is as effective implementation choice. 91 * 92 * @since 1.8 93 */ 94 public interface TemporalField { 95 96 /** 97 * Gets the display name for the field in the requested locale. 98 * <p> 99 * If there is no display name for the locale then a suitable default must be returned. 100 * <p> 101 * The default implementation must check the locale is not null 102 * and return {@code toString()}. 103 * 104 * @param locale the locale to use, not null 105 * @return the display name for the locale or a suitable default, not null 106 */ getDisplayName(Locale locale)107 default String getDisplayName(Locale locale) { 108 Objects.requireNonNull(locale, "locale"); 109 return toString(); 110 } 111 112 /** 113 * Gets the unit that the field is measured in. 114 * <p> 115 * The unit of the field is the period that varies within the range. 116 * For example, in the field 'MonthOfYear', the unit is 'Months'. 117 * See also {@link #getRangeUnit()}. 118 * 119 * @return the unit defining the base unit of the field, not null 120 */ getBaseUnit()121 TemporalUnit getBaseUnit(); 122 123 /** 124 * Gets the range that the field is bound by. 125 * <p> 126 * The range of the field is the period that the field varies within. 127 * For example, in the field 'MonthOfYear', the range is 'Years'. 128 * See also {@link #getBaseUnit()}. 129 * <p> 130 * The range is never null. For example, the 'Year' field is shorthand for 131 * 'YearOfForever'. It therefore has a unit of 'Years' and a range of 'Forever'. 132 * 133 * @return the unit defining the range of the field, not null 134 */ getRangeUnit()135 TemporalUnit getRangeUnit(); 136 137 /** 138 * Gets the range of valid values for the field. 139 * <p> 140 * All fields can be expressed as a {@code long} integer. 141 * This method returns an object that describes the valid range for that value. 142 * This method is generally only applicable to the ISO-8601 calendar system. 143 * <p> 144 * Note that the result only describes the minimum and maximum valid values 145 * and it is important not to read too much into them. For example, there 146 * could be values within the range that are invalid for the field. 147 * 148 * @return the range of valid values for the field, not null 149 */ range()150 ValueRange range(); 151 152 //----------------------------------------------------------------------- 153 /** 154 * Checks if this field represents a component of a date. 155 * <p> 156 * A field is date-based if it can be derived from 157 * {@link ChronoField#EPOCH_DAY EPOCH_DAY}. 158 * Note that it is valid for both {@code isDateBased()} and {@code isTimeBased()} 159 * to return false, such as when representing a field like minute-of-week. 160 * 161 * @return true if this field is a component of a date 162 */ isDateBased()163 boolean isDateBased(); 164 165 /** 166 * Checks if this field represents a component of a time. 167 * <p> 168 * A field is time-based if it can be derived from 169 * {@link ChronoField#NANO_OF_DAY NANO_OF_DAY}. 170 * Note that it is valid for both {@code isDateBased()} and {@code isTimeBased()} 171 * to return false, such as when representing a field like minute-of-week. 172 * 173 * @return true if this field is a component of a time 174 */ isTimeBased()175 boolean isTimeBased(); 176 177 //----------------------------------------------------------------------- 178 /** 179 * Checks if this field is supported by the temporal object. 180 * <p> 181 * This determines whether the temporal accessor supports this field. 182 * If this returns false, then the temporal cannot be queried for this field. 183 * <p> 184 * There are two equivalent ways of using this method. 185 * The first is to invoke this method directly. 186 * The second is to use {@link TemporalAccessor#isSupported(TemporalField)}: 187 * <pre> 188 * // these two lines are equivalent, but the second approach is recommended 189 * temporal = thisField.isSupportedBy(temporal); 190 * temporal = temporal.isSupported(thisField); 191 * </pre> 192 * It is recommended to use the second approach, {@code isSupported(TemporalField)}, 193 * as it is a lot clearer to read in code. 194 * <p> 195 * Implementations should determine whether they are supported using the fields 196 * available in {@link ChronoField}. 197 * 198 * @param temporal the temporal object to query, not null 199 * @return true if the date-time can be queried for this field, false if not 200 */ isSupportedBy(TemporalAccessor temporal)201 boolean isSupportedBy(TemporalAccessor temporal); 202 203 /** 204 * Get the range of valid values for this field using the temporal object to 205 * refine the result. 206 * <p> 207 * This uses the temporal object to find the range of valid values for the field. 208 * This is similar to {@link #range()}, however this method refines the result 209 * using the temporal. For example, if the field is {@code DAY_OF_MONTH} the 210 * {@code range} method is not accurate as there are four possible month lengths, 211 * 28, 29, 30 and 31 days. Using this method with a date allows the range to be 212 * accurate, returning just one of those four options. 213 * <p> 214 * There are two equivalent ways of using this method. 215 * The first is to invoke this method directly. 216 * The second is to use {@link TemporalAccessor#range(TemporalField)}: 217 * <pre> 218 * // these two lines are equivalent, but the second approach is recommended 219 * temporal = thisField.rangeRefinedBy(temporal); 220 * temporal = temporal.range(thisField); 221 * </pre> 222 * It is recommended to use the second approach, {@code range(TemporalField)}, 223 * as it is a lot clearer to read in code. 224 * <p> 225 * Implementations should perform any queries or calculations using the fields 226 * available in {@link ChronoField}. 227 * If the field is not supported an {@code UnsupportedTemporalTypeException} must be thrown. 228 * 229 * @param temporal the temporal object used to refine the result, not null 230 * @return the range of valid values for this field, not null 231 * @throws DateTimeException if the range for the field cannot be obtained 232 * @throws UnsupportedTemporalTypeException if the field is not supported by the temporal 233 */ rangeRefinedBy(TemporalAccessor temporal)234 ValueRange rangeRefinedBy(TemporalAccessor temporal); 235 236 /** 237 * Gets the value of this field from the specified temporal object. 238 * <p> 239 * This queries the temporal object for the value of this field. 240 * <p> 241 * There are two equivalent ways of using this method. 242 * The first is to invoke this method directly. 243 * The second is to use {@link TemporalAccessor#getLong(TemporalField)} 244 * (or {@link TemporalAccessor#get(TemporalField)}): 245 * <pre> 246 * // these two lines are equivalent, but the second approach is recommended 247 * temporal = thisField.getFrom(temporal); 248 * temporal = temporal.getLong(thisField); 249 * </pre> 250 * It is recommended to use the second approach, {@code getLong(TemporalField)}, 251 * as it is a lot clearer to read in code. 252 * <p> 253 * Implementations should perform any queries or calculations using the fields 254 * available in {@link ChronoField}. 255 * If the field is not supported an {@code UnsupportedTemporalTypeException} must be thrown. 256 * 257 * @param temporal the temporal object to query, not null 258 * @return the value of this field, not null 259 * @throws DateTimeException if a value for the field cannot be obtained 260 * @throws UnsupportedTemporalTypeException if the field is not supported by the temporal 261 * @throws ArithmeticException if numeric overflow occurs 262 */ getFrom(TemporalAccessor temporal)263 long getFrom(TemporalAccessor temporal); 264 265 /** 266 * Returns a copy of the specified temporal object with the value of this field set. 267 * <p> 268 * This returns a new temporal object based on the specified one with the value for 269 * this field changed. For example, on a {@code LocalDate}, this could be used to 270 * set the year, month or day-of-month. 271 * The returned object has the same observable type as the specified object. 272 * <p> 273 * In some cases, changing a field is not fully defined. For example, if the target object is 274 * a date representing the 31st January, then changing the month to February would be unclear. 275 * In cases like this, the implementation is responsible for resolving the result. 276 * Typically it will choose the previous valid date, which would be the last valid 277 * day of February in this example. 278 * <p> 279 * There are two equivalent ways of using this method. 280 * The first is to invoke this method directly. 281 * The second is to use {@link Temporal#with(TemporalField, long)}: 282 * <pre> 283 * // these two lines are equivalent, but the second approach is recommended 284 * temporal = thisField.adjustInto(temporal); 285 * temporal = temporal.with(thisField); 286 * </pre> 287 * It is recommended to use the second approach, {@code with(TemporalField)}, 288 * as it is a lot clearer to read in code. 289 * <p> 290 * Implementations should perform any queries or calculations using the fields 291 * available in {@link ChronoField}. 292 * If the field is not supported an {@code UnsupportedTemporalTypeException} must be thrown. 293 * <p> 294 * Implementations must not alter the specified temporal object. 295 * Instead, an adjusted copy of the original must be returned. 296 * This provides equivalent, safe behavior for immutable and mutable implementations. 297 * 298 * @param <R> the type of the Temporal object 299 * @param temporal the temporal object to adjust, not null 300 * @param newValue the new value of the field 301 * @return the adjusted temporal object, not null 302 * @throws DateTimeException if the field cannot be set 303 * @throws UnsupportedTemporalTypeException if the field is not supported by the temporal 304 * @throws ArithmeticException if numeric overflow occurs 305 */ adjustInto(R temporal, long newValue)306 <R extends Temporal> R adjustInto(R temporal, long newValue); 307 308 /** 309 * Resolves this field to provide a simpler alternative or a date. 310 * <p> 311 * This method is invoked during the resolve phase of parsing. 312 * It is designed to allow application defined fields to be simplified into 313 * more standard fields, such as those on {@code ChronoField}, or into a date. 314 * <p> 315 * Applications should not normally invoke this method directly. 316 * 317 * @implSpec 318 * If an implementation represents a field that can be simplified, or 319 * combined with others, then this method must be implemented. 320 * <p> 321 * The specified map contains the current state of the parse. 322 * The map is mutable and must be mutated to resolve the field and 323 * any related fields. This method will only be invoked during parsing 324 * if the map contains this field, and implementations should therefore 325 * assume this field is present. 326 * <p> 327 * Resolving a field will consist of looking at the value of this field, 328 * and potentially other fields, and either updating the map with a 329 * simpler value, such as a {@code ChronoField}, or returning a 330 * complete {@code ChronoLocalDate}. If a resolve is successful, 331 * the code must remove all the fields that were resolved from the map, 332 * including this field. 333 * <p> 334 * For example, the {@code IsoFields} class contains the quarter-of-year 335 * and day-of-quarter fields. The implementation of this method in that class 336 * resolves the two fields plus the {@link ChronoField#YEAR YEAR} into a 337 * complete {@code LocalDate}. The resolve method will remove all three 338 * fields from the map before returning the {@code LocalDate}. 339 * <p> 340 * A partially complete temporal is used to allow the chronology and zone 341 * to be queried. In general, only the chronology will be needed. 342 * Querying items other than the zone or chronology is undefined and 343 * must not be relied on. 344 * The behavior of other methods such as {@code get}, {@code getLong}, 345 * {@code range} and {@code isSupported} is unpredictable and the results undefined. 346 * <p> 347 * If resolution should be possible, but the data is invalid, the resolver 348 * style should be used to determine an appropriate level of leniency, which 349 * may require throwing a {@code DateTimeException} or {@code ArithmeticException}. 350 * If no resolution is possible, the resolve method must return null. 351 * <p> 352 * When resolving time fields, the map will be altered and null returned. 353 * When resolving date fields, the date is normally returned from the method, 354 * with the map altered to remove the resolved fields. However, it would also 355 * be acceptable for the date fields to be resolved into other {@code ChronoField} 356 * instances that can produce a date, such as {@code EPOCH_DAY}. 357 * <p> 358 * Not all {@code TemporalAccessor} implementations are accepted as return values. 359 * Implementations that call this method must accept {@code ChronoLocalDate}, 360 * {@code ChronoLocalDateTime}, {@code ChronoZonedDateTime} and {@code LocalTime}. 361 * <p> 362 * The default implementation must return null. 363 * 364 * @param fieldValues the map of fields to values, which can be updated, not null 365 * @param partialTemporal the partially complete temporal to query for zone and 366 * chronology; querying for other things is undefined and not recommended, not null 367 * @param resolverStyle the requested type of resolve, not null 368 * @return the resolved temporal object; null if resolving only 369 * changed the map, or no resolve occurred 370 * @throws ArithmeticException if numeric overflow occurs 371 * @throws DateTimeException if resolving results in an error. This must not be thrown 372 * by querying a field on the temporal without first checking if it is supported 373 */ resolve( Map<TemporalField, Long> fieldValues, TemporalAccessor partialTemporal, ResolverStyle resolverStyle)374 default TemporalAccessor resolve( 375 Map<TemporalField, Long> fieldValues, 376 TemporalAccessor partialTemporal, 377 ResolverStyle resolverStyle) { 378 return null; 379 } 380 381 /** 382 * Gets a descriptive name for the field. 383 * <p> 384 * The should be of the format 'BaseOfRange', such as 'MonthOfYear', 385 * unless the field has a range of {@code FOREVER}, when only 386 * the base unit is mentioned, such as 'Year' or 'Era'. 387 * 388 * @return the name of the field, not null 389 */ 390 @Override toString()391 String toString(); 392 393 394 } 395