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 java.util.Comparator;
035
036import org.threeten.bp.DateTimeException;
037import org.threeten.bp.Instant;
038import org.threeten.bp.LocalDateTime;
039import org.threeten.bp.LocalTime;
040import org.threeten.bp.ZoneId;
041import org.threeten.bp.ZoneOffset;
042import org.threeten.bp.format.DateTimeFormatter;
043import org.threeten.bp.zone.ZoneRules;
044
045/**
046 * A date-time without a time-zone in an arbitrary chronology, intended
047 * for advanced globalization use cases.
048 * <p>
049 * <b>Most applications should declare method signatures, fields and variables
050 * as {@link LocalDateTime}, not this interface.</b>
051 * <p>
052 * A {@code ChronoLocalDateTime} is the abstract representation of a local date-time
053 * where the {@code Chrono chronology}, or calendar system, is pluggable.
054 * The date-time is defined in terms of fields expressed by {@link TemporalField},
055 * where most common implementations are defined in {@link ChronoField}.
056 * The chronology defines how the calendar system operates and the meaning of
057 * the standard fields.
058 *
059 * <h4>When to use this interface</h4>
060 * The design of the API encourages the use of {@code LocalDateTime} rather than this
061 * interface, even in the case where the application needs to deal with multiple
062 * calendar systems. The rationale for this is explored in detail in {@link ChronoLocalDate}.
063 * <p>
064 * Ensure that the discussion in {@code ChronoLocalDate} has been read and understood
065 * before using this interface.
066 *
067 * <h3>Specification for implementors</h3>
068 * This interface must be implemented with care to ensure other classes operate correctly.
069 * All implementations that can be instantiated must be final, immutable and thread-safe.
070 * Subclasses should be Serializable wherever possible.
071 *
072 * @param <C> the chronology of this date-time
073 */
074public interface ChronoLocalDateTime<C extends Chrono<C>>
075        extends  Temporal, TemporalAdjuster, Comparable<ChronoLocalDateTime<?>> {
076
077   /**
078     * Comparator for two {@code ChronoLocalDateTime} instances ignoring the chronology.
079     * <p>
080     * This method differs from the comparison in {@link #compareTo} in that it
081     * only compares the underlying date and not the chronology.
082     * This allows dates in different calendar systems to be compared based
083     * on the time-line position.
084     *
085     * @see #isAfter
086     * @see #isBefore
087     * @see #isEqual
088     */
089    Comparator<ChronoLocalDateTime<?>> DATE_TIME_COMPARATOR =
090            new Comparator<ChronoLocalDateTime<?>>() {
091        @Override
092        public int compare(ChronoLocalDateTime<?> datetime1, ChronoLocalDateTime<?> datetime2) {
093            int cmp = Long.compare(datetime1.getDate().toEpochDay(), datetime2.getDate().toEpochDay());
094            if (cmp == 0) {
095                cmp = Long.compare(datetime1.getTime().toNanoOfDay(), datetime2.getTime().toNanoOfDay());
096            }
097            return cmp;
098        }
099    };
100
101    /**
102     * Gets the local date part of this date-time.
103     * <p>
104     * This returns a local date with the same year, month and day
105     * as this date-time.
106     *
107     * @return the date part of this date-time, not null
108     */
109    ChronoLocalDate<C> getDate() ;
110
111    /**
112     * Gets the local time part of this date-time.
113     * <p>
114     * This returns a local time with the same hour, minute, second and
115     * nanosecond as this date-time.
116     *
117     * @return the time part of this date-time, not null
118     */
119    LocalTime getTime();
120
121    //-------------------------------------------------------------------------
122    // override for covariant return type
123    @Override
124    ChronoLocalDateTime<C> with(TemporalAdjuster adjuster);
125
126    @Override
127    ChronoLocalDateTime<C> with(TemporalField field, long newValue);
128
129    @Override
130    ChronoLocalDateTime<C> plus(TemporalAdder adjuster);
131
132    @Override
133    ChronoLocalDateTime<C> plus(long amountToAdd, TemporalUnit unit);
134
135    @Override
136    ChronoLocalDateTime<C> minus(TemporalSubtractor adjuster);
137
138    @Override
139    ChronoLocalDateTime<C> minus(long amountToSubtract, TemporalUnit unit);
140
141    //-----------------------------------------------------------------------
142    /**
143     * Returns a zoned date-time formed from this date-time and the specified time-zone.
144     * <p>
145     * This creates a zoned date-time matching the input date-time as closely as possible.
146     * Time-zone rules, such as daylight savings, mean that not every local date-time
147     * is valid for the specified zone, thus the local date-time may be adjusted.
148     * <p>
149     * The local date-time is resolved to a single instant on the time-line.
150     * This is achieved by finding a valid offset from UTC/Greenwich for the local
151     * date-time as defined by the {@link ZoneRules rules} of the zone ID.
152     *<p>
153     * In most cases, there is only one valid offset for a local date-time.
154     * In the case of an overlap, where clocks are set back, there are two valid offsets.
155     * This method uses the earlier offset typically corresponding to "summer".
156     * <p>
157     * In the case of a gap, where clocks jump forward, there is no valid offset.
158     * Instead, the local date-time is adjusted to be later by the length of the gap.
159     * For a typical one hour daylight savings change, the local date-time will be
160     * moved one hour later into the offset typically corresponding to "summer".
161     * <p>
162     * To obtain the later offset during an overlap, call
163     * {@link ChronoZonedDateTime#withLaterOffsetAtOverlap()} on the result of this method.
164     * <p>
165     * This instance is immutable and unaffected by this method call.
166     *
167     * @param zone  the time-zone to use, not null
168     * @return the zoned date-time formed from this date-time, not null
169     */
170    ChronoZonedDateTime<C> atZone(ZoneId zone);
171
172    //-----------------------------------------------------------------------
173    /**
174     * Converts this date-time to an {@code Instant}.
175     * <p>
176     * This combines this local date-time and the specified offset to form
177     * an {@code Instant}.
178     *
179     * @param offset  the offset to use for the conversion, not null
180     * @return an {@code Instant} representing the same instant, not null
181     */
182    Instant toInstant(ZoneOffset offset);
183
184    /**
185     * Converts this date-time to the number of seconds from the epoch
186     * of 1970-01-01T00:00:00Z.
187     * <p>
188     * This combines this local date-time and the specified offset to calculate the
189     * epoch-second value, which is the number of elapsed seconds from 1970-01-01T00:00:00Z.
190     * Instants on the time-line after the epoch are positive, earlier are negative.
191     *
192     * @param offset  the offset to use for the conversion, not null
193     * @return the number of seconds from the epoch of 1970-01-01T00:00:00Z
194     */
195    long toEpochSecond(ZoneOffset offset);
196
197    //-----------------------------------------------------------------------
198    /**
199     * Compares this date-time to another date-time, including the chronology.
200     * <p>
201     * The comparison is based first on the underlying time-line date-time, then
202     * on the chronology.
203     * It is "consistent with equals", as defined by {@link Comparable}.
204     * <p>
205     * For example, the following is the comparator order:
206     * <ol>
207     * <li>{@code 2012-12-03T12:00 (ISO)}</li>
208     * <li>{@code 2012-12-04T12:00 (ISO)}</li>
209     * <li>{@code 2555-12-04T12:00 (ThaiBuddhist)}</li>
210     * <li>{@code 2012-12-05T12:00 (ISO)}</li>
211     * </ol>
212     * Values #2 and #3 represent the same date-time on the time-line.
213     * When two values represent the same date-time, the chronology ID is compared to distinguish them.
214     * This step is needed to make the ordering "consistent with equals".
215     * <p>
216     * If all the date-time objects being compared are in the same chronology, then the
217     * additional chronology stage is not required and only the local date-time is used.
218     *
219     * @param other  the other date-time to compare to, not null
220     * @return the comparator value, negative if less, positive if greater
221     */
222    @Override
223    int compareTo(ChronoLocalDateTime<?> other);
224
225    /**
226     * Checks if this date-time is after the specified date-time ignoring the chronology.
227     * <p>
228     * This method differs from the comparison in {@link #compareTo} in that it
229     * only compares the underlying date-time and not the chronology.
230     * This allows dates in different calendar systems to be compared based
231     * on the time-line position.
232     *
233     * @param other  the other date-time to compare to, not null
234     * @return true if this is after the specified date-time
235     */
236    boolean isAfter(ChronoLocalDateTime<?> other);
237
238    /**
239     * Checks if this date-time is before the specified date-time ignoring the chronology.
240     * <p>
241     * This method differs from the comparison in {@link #compareTo} in that it
242     * only compares the underlying date-time and not the chronology.
243     * This allows dates in different calendar systems to be compared based
244     * on the time-line position.
245     *
246     * @param other  the other date-time to compare to, not null
247     * @return true if this is before the specified date-time
248     */
249    boolean isBefore(ChronoLocalDateTime<?> other);
250
251    /**
252     * Checks if this date-time is equal to the specified date-time ignoring the chronology.
253     * <p>
254     * This method differs from the comparison in {@link #compareTo} in that it
255     * only compares the underlying date and time and not the chronology.
256     * This allows date-times in different calendar systems to be compared based
257     * on the time-line position.
258     *
259     * @param other  the other date-time to compare to, not null
260     * @return true if the underlying date-time is equal to the specified date-time on the timeline
261     */
262    boolean isEqual(ChronoLocalDateTime<?> other);
263
264    //-----------------------------------------------------------------------
265    /**
266     * Checks if this date-time is equal to another date-time, including the chronology.
267     * <p>
268     * Compares this date-time with another ensuring that the date-time and chronology are the same.
269     *
270     * @param obj  the object to check, null returns false
271     * @return true if this is equal to the other date
272     */
273    @Override
274    boolean equals(Object obj);
275
276    /**
277     * A hash code for this date-time.
278     *
279     * @return a suitable hash code
280     */
281    @Override
282    int hashCode();
283
284    //-----------------------------------------------------------------------
285    /**
286     * Outputs this date-time as a {@code String}.
287     * <p>
288     * The output will include the full local date-time and the chronology ID.
289     *
290     * @return a string representation of this date-time, not null
291     */
292    @Override
293    String toString();
294
295    /**
296     * Outputs this date-time as a {@code String} using the formatter.
297     *
298     * @param formatter  the formatter to use, not null
299     * @return the formatted date-time string, not null
300     * @throws DateTimeException if an error occurs during printing
301     */
302    String toString(DateTimeFormatter formatter);
303
304}