001/*
002 * Copyright (c) 2007-2013, Stephen Colebourne & Michael Nascimento Santos
003 *
004 * All rights reserved.
005 *
006 * Redistribution and use in source and binary forms, with or without
007 * modification, are permitted provided that the following conditions are met:
008 *
009 *  * Redistributions of source code must retain the above copyright notice,
010 *    this list of conditions and the following disclaimer.
011 *
012 *  * Redistributions in binary form must reproduce the above copyright notice,
013 *    this list of conditions and the following disclaimer in the documentation
014 *    and/or other materials provided with the distribution.
015 *
016 *  * Neither the name of JSR-310 nor the names of its contributors
017 *    may be used to endorse or promote products derived from this software
018 *    without specific prior written permission.
019 *
020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
024 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031 */
032package org.threeten.bp.temporal;
033
034import org.threeten.bp.DateTimeException;
035import org.threeten.bp.Duration;
036import org.threeten.bp.Period;
037import org.threeten.bp.ZoneId;
038
039/**
040 * Framework-level interface defining read-write access to a temporal object,
041 * such as a date, time, offset or some combination of these.
042 * <p>
043 * This is the base interface type for date, time and offset objects that
044 * are complete enough to be manipulated using plus and minus.
045 * It is implemented by those classes that can provide and manipulate information
046 * as {@link TemporalField fields} or {@link TemporalQuery queries}.
047 * See {@link TemporalAccessor} for the read-only version of this interface.
048 * <p>
049 * Most date and time information can be represented as a number.
050 * These are modeled using {@code TemporalField} with the number held using
051 * a {@code long} to handle large values. Year, month and day-of-month are
052 * simple examples of fields, but they also include instant and offsets.
053 * See {@link ChronoField} for the standard set of fields.
054 * <p>
055 * Two pieces of date/time information cannot be represented by numbers,
056 * the {@link Chrono chronology} and the {@link ZoneId time-zone}.
057 * These can be accessed via {@link #query(TemporalQuery) queries} using
058 * the static methods defined on {@link TemporalQueries}.
059 * <p>
060 * This interface is a framework-level interface that should not be widely
061 * used in application code. Instead, applications should create and pass
062 * around instances of concrete types, such as {@code LocalDate}.
063 * There are many reasons for this, part of which is that implementations
064 * of this interface may be in calendar systems other than ISO.
065 * See {@link ChronoLocalDate} for a fuller discussion of the issues.
066 *
067 * <h3>When to implement</h3>
068 * <p>
069 * A class should implement this interface if it meets three criteria:
070 * <p><ul>
071 * <li>it provides access to date/time/offset information, as per {@code TemporalAccessor}
072 * <li>the set of fields are contiguous from the largest to the smallest
073 * <li>the set of fields are complete, such that no other field is needed to define the
074 *  valid range of values for the fields that are represented
075 * </ul><p>
076 * <p>
077 * Four examples make this clear:
078 * <p><ul>
079 * <li>{@code LocalDate} implements this interface as it represents a set of fields
080 *  that are contiguous from days to forever and require no external information to determine
081 *  the validity of each date. It is therefore able to implement plus/minus correctly.
082 * <li>{@code LocalTime} implements this interface as it represents a set of fields
083 *  that are contiguous from nanos to within days and require no external information to determine
084 *  validity. It is able to implement plus/minus correctly, by wrapping around the day.
085 * <li>{@code MonthDay}, the combination of month-of-year and day-of-month, does not implement
086 *  this interface.  While the combination is contiguous, from days to months within years,
087 *  the combination does not have sufficient information to define the valid range of values
088 *  for day-of-month.  As such, it is unable to implement plus/minus correctly.
089 * <li>The combination day-of-week and day-of-month ("Friday the 13th") should not implement
090 *  this interface. It does not represent a contiguous set of fields, as days to weeks overlaps
091 *  days to months.
092 * </ul><p>
093 *
094 * <h3>Specification for implementors</h3>
095 * This interface places no restrictions on the mutability of implementations,
096 * however immutability is strongly recommended.
097 * All implementations must be {@link Comparable}.
098 */
099public interface Temporal extends TemporalAccessor {
100
101    /**
102     * Returns an adjusted object of the same type as this object with the adjustment made.
103     * <p>
104     * This adjusts this date-time according to the rules of the specified adjuster.
105     * A simple adjuster might simply set the one of the fields, such as the year field.
106     * A more complex adjuster might set the date to the last day of the month.
107     * A selection of common adjustments is provided in {@link TemporalAdjusters}.
108     * These include finding the "last day of the month" and "next Wednesday".
109     * The adjuster is responsible for handling special cases, such as the varying
110     * lengths of month and leap years.
111     * <p>
112     * Some example code indicating how and why this method is used:
113     * <pre>
114     *  date = date.with(Month.JULY);        // most key classes implement TemporalAdjuster
115     *  date = date.with(lastDayOfMonth());  // static import from TemporalAdjusters
116     *  date = date.with(next(WEDNESDAY));   // static import from TemporalAdjusters and DayOfWeek
117     * </pre>
118     *
119     * <h3>Specification for implementors</h3>
120     * Implementations must not alter either this object.
121     * Instead, an adjusted copy of the original must be returned.
122     * This provides equivalent, safe behavior for immutable and mutable implementations.
123     *
124     * @param adjuster  the adjuster to use, not null
125     * @return an object of the same type with the specified adjustment made, not null
126     * @throws DateTimeException if unable to make the adjustment
127     * @throws ArithmeticException if numeric overflow occurs
128     */
129    Temporal with(TemporalAdjuster adjuster);
130
131    /**
132     * Returns an object of the same type as this object with the specified field altered.
133     * <p>
134     * This returns a new object based on this one with the value for the specified field changed.
135     * For example, on a {@code LocalDate}, this could be used to set the year, month or day-of-month.
136     * The returned object will have the same observable type as this object.
137     * <p>
138     * In some cases, changing a field is not fully defined. For example, if the target object is
139     * a date representing the 31st January, then changing the month to February would be unclear.
140     * In cases like this, the field is responsible for resolving the result. Typically it will choose
141     * the previous valid date, which would be the last valid day of February in this example.
142     *
143     * <h3>Specification for implementors</h3>
144     * Implementations must check and handle all fields defined in {@link ChronoField}.
145     * If the field is supported, then the adjustment must be performed.
146     * If unsupported, then a {@code DateTimeException} must be thrown.
147     * <p>
148     * If the field is not a {@code ChronoField}, then the result of this method
149     * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
150     * passing {@code this} as the first argument.
151     * <p>
152     * Implementations must not alter either this object or the specified temporal object.
153     * Instead, an adjusted copy of the original must be returned.
154     * This provides equivalent, safe behavior for immutable and mutable implementations.
155     *
156     * @param field  the field to set in the result, not null
157     * @param newValue  the new value of the field in the result
158     * @return an object of the same type with the specified field set, not null
159     * @throws DateTimeException if the field cannot be set
160     * @throws ArithmeticException if numeric overflow occurs
161     */
162    Temporal with(TemporalField field, long newValue);
163
164    //-----------------------------------------------------------------------
165    /**
166     * Returns an object of the same type as this object with an amount added.
167     * <p>
168     * This adjusts this temporal, adding according to the rules of the specified adder.
169     * The adder is typically a {@link Period} but may be any other type implementing
170     * the {@link TemporalAdder} interface, such as {@link Duration}.
171     * <p>
172     * Some example code indicating how and why this method is used:
173     * <pre>
174     *  date = date.plus(period);                      // add a Period instance
175     *  date = date.plus(duration);                    // add a Duration instance
176     *  date = date.plus(MONTHS.between(start, end));  // static import of MONTHS field
177     *  date = date.plus(workingDays(6));              // example user-written workingDays method
178     * </pre>
179     * <p>
180     * Note that calling {@code plus} followed by {@code minus} is not guaranteed to
181     * return the same date-time.
182     *
183     * <h3>Specification for implementors</h3>
184     * Implementations must not alter either this object.
185     * Instead, an adjusted copy of the original must be returned.
186     * This provides equivalent, safe behavior for immutable and mutable implementations.
187     *
188     * @param adder  the adder to use, not null
189     * @return an object of the same type with the specified adjustment made, not null
190     * @throws DateTimeException if the addition cannot be made
191     * @throws ArithmeticException if numeric overflow occurs
192     */
193    Temporal plus(TemporalAdder adder);
194
195    /**
196     * Returns an object of the same type as this object with the specified period added.
197     * <p>
198     * This method returns a new object based on this one with the specified period added.
199     * For example, on a {@code LocalDate}, this could be used to add a number of years, months or days.
200     * The returned object will have the same observable type as this object.
201     * <p>
202     * In some cases, changing a field is not fully defined. For example, if the target object is
203     * a date representing the 31st January, then adding one month would be unclear.
204     * In cases like this, the field is responsible for resolving the result. Typically it will choose
205     * the previous valid date, which would be the last valid day of February in this example.
206     * <p>
207     * If the implementation represents a date-time that has boundaries, such as {@code LocalTime},
208     * then the permitted units must include the boundary unit, but no multiples of the boundary unit.
209     * For example, {@code LocalTime} must accept {@code DAYS} but not {@code WEEKS} or {@code MONTHS}.
210     *
211     * <h3>Specification for implementors</h3>
212     * Implementations must check and handle all units defined in {@link ChronoUnit}.
213     * If the unit is supported, then the addition must be performed.
214     * If unsupported, then a {@code DateTimeException} must be thrown.
215     * <p>
216     * If the unit is not a {@code ChronoUnit}, then the result of this method
217     * is obtained by invoking {@code TemporalUnit.doPlus(Temporal, long)}
218     * passing {@code this} as the first argument.
219     * <p>
220     * Implementations must not alter either this object or the specified temporal object.
221     * Instead, an adjusted copy of the original must be returned.
222     * This provides equivalent, safe behavior for immutable and mutable implementations.
223     *
224     * @param amountToAdd  the amount of the specified unit to add, may be negative
225     * @param unit  the unit of the period to add, not null
226     * @return an object of the same type with the specified period added, not null
227     * @throws DateTimeException if the unit cannot be added
228     * @throws ArithmeticException if numeric overflow occurs
229     */
230    Temporal plus(long amountToAdd, TemporalUnit unit);
231
232    //-----------------------------------------------------------------------
233    /**
234     * Returns an object of the same type as this object with an amount subtracted.
235     * <p>
236     * This adjusts this temporal, subtracting according to the rules of the specified subtractor.
237     * The subtractor is typically a {@link Period} but may be any other type implementing
238     * the {@link TemporalSubtractor} interface, such as {@link Duration}.
239     * <p>
240     * Some example code indicating how and why this method is used:
241     * <pre>
242     *  date = date.minus(period);                      // subtract a Period instance
243     *  date = date.minus(duration);                    // subtract a Duration instance
244     *  date = date.minus(MONTHS.between(start, end));  // static import of MONTHS field
245     *  date = date.minus(workingDays(6));              // example user-written workingDays method
246     * </pre>
247     * <p>
248     * Note that calling {@code plus} followed by {@code minus} is not guaranteed to
249     * return the same date-time.
250     *
251     * <h3>Specification for implementors</h3>
252     * Implementations must not alter either this object.
253     * Instead, an adjusted copy of the original must be returned.
254     * This provides equivalent, safe behavior for immutable and mutable implementations.
255     *
256     * @param subtractor  the subtractor to use, not null
257     * @return an object of the same type with the specified adjustment made, not null
258     * @throws DateTimeException if the subtraction cannot be made
259     * @throws ArithmeticException if numeric overflow occurs
260     */
261    Temporal minus(TemporalSubtractor subtractor);
262
263    /**
264     * Returns an object of the same type as this object with the specified period subtracted.
265     * <p>
266     * This method returns a new object based on this one with the specified period subtracted.
267     * For example, on a {@code LocalDate}, this could be used to subtract a number of years, months or days.
268     * The returned object will have the same observable type as this object.
269     * <p>
270     * In some cases, changing a field is not fully defined. For example, if the target object is
271     * a date representing the 31st March, then subtracting one month would be unclear.
272     * In cases like this, the field is responsible for resolving the result. Typically it will choose
273     * the previous valid date, which would be the last valid day of February in this example.
274     * <p>
275     * If the implementation represents a date-time that has boundaries, such as {@code LocalTime},
276     * then the permitted units must include the boundary unit, but no multiples of the boundary unit.
277     * For example, {@code LocalTime} must accept {@code DAYS} but not {@code WEEKS} or {@code MONTHS}.
278     *
279     * <h3>Specification for implementors</h3>
280     * Implementations must behave in a manor equivalent to the default method behavior.
281     * <p>
282     * Implementations must not alter either this object or the specified temporal object.
283     * Instead, an adjusted copy of the original must be returned.
284     * This provides equivalent, safe behavior for immutable and mutable implementations.
285     *
286     * @param amountToSubtract  the amount of the specified unit to subtract, may be negative
287     * @param unit  the unit of the period to subtract, not null
288     * @return an object of the same type with the specified period subtracted, not null
289     * @throws DateTimeException if the unit cannot be subtracted
290     * @throws ArithmeticException if numeric overflow occurs
291     */
292    Temporal minus(long amountToSubtract, TemporalUnit unit);
293
294    //-----------------------------------------------------------------------
295    /**
296     * Calculates the period between this temporal and another temporal in
297     * terms of the specified unit.
298     * <p>
299     * This calculates the period between two temporals in terms of a single unit.
300     * The start and end points are {@code this} and the specified temporal.
301     * The result will be negative if the end is before the start.
302     * For example, the period in hours between two temporal objects can be
303     * calculated using {@code startTime.periodUntil(endTime, HOURS)}.
304     * <p>
305     * The calculation returns a whole number, representing the number of
306     * complete units between the two temporals.
307     * For example, the period in hours between the times 11:30 and 13:29
308     * will only be one hour as it is one minute short of two hours.
309     * <p>
310     * This method operates in association with {@link TemporalUnit#between}.
311     * The result of this method is a {@code long} representing the amount of
312     * the specified unit. By contrast, the result of {@code between} is an
313     * object that can be used directly in addition/subtraction:
314     * <pre>
315     *   long period = start.periodUntil(end, HOURS);   // this method
316     *   dateTime.plus(HOURS.between(start, end));      // use in plus/minus
317     * </pre>
318     *
319     * <h3>Specification for implementors</h3>
320     * Implementations must begin by checking to ensure that the input temporal
321     * object is of the same observable type as the implementation.
322     * They must then perform the calculation for all instances of {@link ChronoUnit}.
323     * A {@code DateTimeException} must be thrown for {@code ChronoUnit}
324     * instances that are unsupported.
325     * <p>
326     * If the unit is not a {@code ChronoUnit}, then the result of this method
327     * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
328     * passing {@code this} as the first argument and the input temporal as
329     * the second argument.
330     * <p>
331     * In summary, implementations must behave in a manner equivalent to this code:
332     * <pre>
333     *  // check input temporal is the same type as this class
334     *  if (unit instanceof ChronoUnit) {
335     *    // if unit is supported, then calculate and return result
336     *    // else throw DateTimeException for unsupported units
337     *  }
338     *  return unit.between(this, endTime).getAmount();
339     * </pre>
340     * <p>
341     * The target object must not be altered by this method.
342     *
343     * @param endTemporal  the end temporal, of the same type as this object, not null
344     * @param unit  the unit to measure the period in, not null
345     * @return the amount of the period between this and the end
346     * @throws DateTimeException if the period cannot be calculated
347     * @throws ArithmeticException if numeric overflow occurs
348     */
349    long periodUntil(Temporal endTemporal, TemporalUnit unit);
350
351}