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