--- /dev/null 2013-01-18 16:17:08.886776012 -0800 +++ new/src/share/classes/java/time/temporal/Temporal.java 2013-01-22 16:58:16.000000000 -0800 @@ -0,0 +1,410 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file: + * + * Copyright (c) 2012, Stephen Colebourne & Michael Nascimento Santos + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of JSR-310 nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package java.time.temporal; + +import java.time.DateTimeException; +import java.time.ZoneId; + +/** + * Framework-level interface defining read-write access to a temporal object, + * such as a date, time, offset or some combination of these. + *
+ * This is the base interface type for date, time and offset objects that + * are complete enough to be manipulated using plus and minus. + * It is implemented by those classes that can provide and manipulate information + * as {@linkplain TemporalField fields} or {@linkplain TemporalQuery queries}. + * See {@link TemporalAccessor} for the read-only version of this interface. + *
+ * Most date and time information can be represented as a number. + * These are modeled using {@code TemporalField} with the number held using + * a {@code long} to handle large values. Year, month and day-of-month are + * simple examples of fields, but they also include instant and offsets. + * See {@link ChronoField} for the standard set of fields. + *
+ * Two pieces of date/time information cannot be represented by numbers, + * the {@linkplain Chrono chronology} and the {@linkplain ZoneId time-zone}. + * These can be accessed via {@link #query(TemporalQuery) queries} using + * the static methods defined on {@link Queries}. + *
+ * This interface is a framework-level interface that should not be widely + * used in application code. Instead, applications should create and pass + * around instances of concrete types, such as {@code LocalDate}. + * There are many reasons for this, part of which is that implementations + * of this interface may be in calendar systems other than ISO. + * See {@link ChronoLocalDate} for a fuller discussion of the issues. + * + *
+ * A class should implement this interface if it meets three criteria: + *
+ *
+ * Four examples make this clear: + *
+ * + *
+ * This adjusts this date-time according to the rules of the specified adjuster. + * A simple adjuster might simply set the one of the fields, such as the year field. + * A more complex adjuster might set the date to the last day of the month. + * A selection of common adjustments is provided in {@link Adjusters}. + * These include finding the "last day of the month" and "next Wednesday". + * The adjuster is responsible for handling special cases, such as the varying + * lengths of month and leap years. + *
+ * Some example code indicating how and why this method is used: + *
+ * date = date.with(Month.JULY); // most key classes implement TemporalAdjuster + * date = date.with(lastDayOfMonth()); // static import from Adjusters + * date = date.with(next(WEDNESDAY)); // static import from Adjusters and DayOfWeek + *+ * + *
+ * The default implementation must behave equivalent to this code: + *
+ * return adjuster.adjustInto(this); + *+ * + * @param adjuster the adjuster to use, not null + * @return an object of the same type with the specified adjustment made, not null + * @throws DateTimeException if unable to make the adjustment + * @throws ArithmeticException if numeric overflow occurs + */ + public default Temporal with(TemporalAdjuster adjuster) { + return adjuster.adjustInto(this); + } + + /** + * Returns an object of the same type as this object with the specified field altered. + *
+ * This returns a new object based on this one with the value for the specified field changed. + * For example, on a {@code LocalDate}, this could be used to set the year, month or day-of-month. + * The returned object will have the same observable type as this object. + *
+ * In some cases, changing a field is not fully defined. For example, if the target object is + * a date representing the 31st January, then changing the month to February would be unclear. + * In cases like this, the field is responsible for resolving the result. Typically it will choose + * the previous valid date, which would be the last valid day of February in this example. + * + *
+ * If the field is not a {@code ChronoField}, then the result of this method + * is obtained by invoking {@code TemporalField.doWith(Temporal, long)} + * passing {@code this} as the first argument. + *
+ * Implementations must not alter either this object or the specified temporal object. + * Instead, an adjusted copy of the original must be returned. + * This provides equivalent, safe behavior for immutable and mutable implementations. + * + * @param field the field to set in the result, not null + * @param newValue the new value of the field in the result + * @return an object of the same type with the specified field set, not null + * @throws DateTimeException if the field cannot be set + * @throws ArithmeticException if numeric overflow occurs + */ + Temporal with(TemporalField field, long newValue); + + //----------------------------------------------------------------------- + /** + * Returns an object of the same type as this object with an amount added. + *
+ * This adjusts this temporal, adding according to the rules of the specified adder. + * The adder is typically a {@link java.time.Period} but may be any other type implementing + * the {@link TemporalAdder} interface, such as {@link java.time.Duration}. + *
+ * Some example code indicating how and why this method is used: + *
+ * date = date.plus(period); // add a Period instance + * date = date.plus(duration); // add a Duration instance + * date = date.plus(MONTHS.between(start, end)); // static import of MONTHS field + * date = date.plus(workingDays(6)); // example user-written workingDays method + *+ *
+ * Note that calling {@code plus} followed by {@code minus} is not guaranteed to + * return the same date-time. + * + *
+ * The default implementation must behave equivalent to this code: + *
+ * return adder.addTo(this); + *+ * + * @param adder the adder to use, not null + * @return an object of the same type with the specified adjustment made, not null + * @throws DateTimeException if the addition cannot be made + * @throws ArithmeticException if numeric overflow occurs + */ + public default Temporal plus(TemporalAdder adder) { + return adder.addTo(this); + } + + /** + * Returns an object of the same type as this object with the specified period added. + *
+ * This method returns a new object based on this one with the specified period added. + * For example, on a {@code LocalDate}, this could be used to add a number of years, months or days. + * The returned object will have the same observable type as this object. + *
+ * In some cases, changing a field is not fully defined. For example, if the target object is + * a date representing the 31st January, then adding one month would be unclear. + * In cases like this, the field is responsible for resolving the result. Typically it will choose + * the previous valid date, which would be the last valid day of February in this example. + *
+ * If the implementation represents a date-time that has boundaries, such as {@code LocalTime}, + * then the permitted units must include the boundary unit, but no multiples of the boundary unit. + * For example, {@code LocalTime} must accept {@code DAYS} but not {@code WEEKS} or {@code MONTHS}. + * + *
+ * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.doPlus(Temporal, long)} + * passing {@code this} as the first argument. + *
+ * Implementations must not alter either this object or the specified temporal object. + * Instead, an adjusted copy of the original must be returned. + * This provides equivalent, safe behavior for immutable and mutable implementations. + * + * @param amountToAdd the amount of the specified unit to add, may be negative + * @param unit the unit of the period to add, not null + * @return an object of the same type with the specified period added, not null + * @throws DateTimeException if the unit cannot be added + * @throws ArithmeticException if numeric overflow occurs + */ + Temporal plus(long amountToAdd, TemporalUnit unit); + + //----------------------------------------------------------------------- + /** + * Returns an object of the same type as this object with an amount subtracted. + *
+ * This adjusts this temporal, subtracting according to the rules of the specified subtractor. + * The subtractor is typically a {@link java.time.Period} but may be any other type implementing + * the {@link TemporalSubtractor} interface, such as {@link java.time.Duration}. + *
+ * Some example code indicating how and why this method is used: + *
+ * date = date.minus(period); // subtract a Period instance + * date = date.minus(duration); // subtract a Duration instance + * date = date.minus(MONTHS.between(start, end)); // static import of MONTHS field + * date = date.minus(workingDays(6)); // example user-written workingDays method + *+ *
+ * Note that calling {@code plus} followed by {@code minus} is not guaranteed to + * return the same date-time. + * + *
+ * The default implementation must behave equivalent to this code: + *
+ * return subtractor.subtractFrom(this); + *+ * + * @param subtractor the subtractor to use, not null + * @return an object of the same type with the specified adjustment made, not null + * @throws DateTimeException if the subtraction cannot be made + * @throws ArithmeticException if numeric overflow occurs + */ + public default Temporal minus(TemporalSubtractor subtractor) { + return subtractor.subtractFrom(this); + } + + /** + * Returns an object of the same type as this object with the specified period subtracted. + *
+ * This method returns a new object based on this one with the specified period subtracted. + * For example, on a {@code LocalDate}, this could be used to subtract a number of years, months or days. + * The returned object will have the same observable type as this object. + *
+ * In some cases, changing a field is not fully defined. For example, if the target object is + * a date representing the 31st March, then subtracting one month would be unclear. + * In cases like this, the field is responsible for resolving the result. Typically it will choose + * the previous valid date, which would be the last valid day of February in this example. + *
+ * If the implementation represents a date-time that has boundaries, such as {@code LocalTime}, + * then the permitted units must include the boundary unit, but no multiples of the boundary unit. + * For example, {@code LocalTime} must accept {@code DAYS} but not {@code WEEKS} or {@code MONTHS}. + * + *
+ * Implementations must not alter either this object or the specified temporal object. + * Instead, an adjusted copy of the original must be returned. + * This provides equivalent, safe behavior for immutable and mutable implementations. + *
+ * The default implementation must behave equivalent to this code: + *
+ * return (amountToSubtract == Long.MIN_VALUE ? + * plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); + *+ * + * @param amountToSubtract the amount of the specified unit to subtract, may be negative + * @param unit the unit of the period to subtract, not null + * @return an object of the same type with the specified period subtracted, not null + * @throws DateTimeException if the unit cannot be subtracted + * @throws ArithmeticException if numeric overflow occurs + */ + public default Temporal minus(long amountToSubtract, TemporalUnit unit) { + return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit)); + } + + //----------------------------------------------------------------------- + /** + * Calculates the period between this temporal and another temporal in + * terms of the specified unit. + *
+ * This calculates the period between two temporals in terms of a single unit. + * The start and end points are {@code this} and the specified temporal. + * The result will be negative if the end is before the start. + * For example, the period in hours between two temporal objects can be + * calculated using {@code startTime.periodUntil(endTime, HOURS)}. + *
+ * The calculation returns a whole number, representing the number of + * complete units between the two temporals. + * For example, the period in hours between the times 11:30 and 13:29 + * will only be one hour as it is one minute short of two hours. + *
+ * This method operates in association with {@link TemporalUnit#between}. + * The result of this method is a {@code long} representing the amount of + * the specified unit. By contrast, the result of {@code between} is an + * object that can be used directly in addition/subtraction: + *
+ * long period = start.periodUntil(end, HOURS); // this method + * dateTime.plus(HOURS.between(start, end)); // use in plus/minus + *+ * + *
+ * If the unit is not a {@code ChronoUnit}, then the result of this method + * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)} + * passing {@code this} as the first argument and the input temporal as + * the second argument. + *
+ * In summary, implementations must behave in a manner equivalent to this code: + *
+ * // check input temporal is the same type as this class + * if (unit instanceof ChronoUnit) { + * // if unit is supported, then calculate and return result + * // else throw DateTimeException for unsupported units + * } + * return unit.between(this, endTime).getAmount(); + *+ *
+ * The target object must not be altered by this method. + * + * @param endTemporal the end temporal, of the same type as this object, not null + * @param unit the unit to measure the period in, not null + * @return the amount of the period between this and the end + * @throws DateTimeException if the period cannot be calculated + * @throws ArithmeticException if numeric overflow occurs + */ + long periodUntil(Temporal endTemporal, TemporalUnit unit); + +}