View Javadoc
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.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      */
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 period unit defining the base unit of the field, not null
120      */
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 period unit defining the range of the field, not null
134      */
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      */
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      */
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      */
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, the 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      */
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      */
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      */
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      */
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      */
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
391     String toString();
392 
393 
394 }