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;
033
034import static org.threeten.bp.LocalTime.HOURS_PER_DAY;
035import static org.threeten.bp.LocalTime.MICROS_PER_DAY;
036import static org.threeten.bp.LocalTime.MILLIS_PER_DAY;
037import static org.threeten.bp.LocalTime.MINUTES_PER_DAY;
038import static org.threeten.bp.LocalTime.NANOS_PER_DAY;
039import static org.threeten.bp.LocalTime.NANOS_PER_HOUR;
040import static org.threeten.bp.LocalTime.NANOS_PER_MINUTE;
041import static org.threeten.bp.LocalTime.NANOS_PER_SECOND;
042import static org.threeten.bp.LocalTime.SECONDS_PER_DAY;
043
044import java.io.DataInput;
045import java.io.DataOutput;
046import java.io.IOException;
047import java.io.InvalidObjectException;
048import java.io.ObjectStreamException;
049import java.io.Serializable;
050import java.util.Objects;
051
052import org.threeten.bp.format.DateTimeFormatter;
053import org.threeten.bp.format.DateTimeFormatters;
054import org.threeten.bp.format.DateTimeParseException;
055import org.threeten.bp.jdk8.DefaultInterfaceChronoLocalDateTime;
056import org.threeten.bp.jdk8.Jdk8Methods;
057import org.threeten.bp.temporal.ChronoField;
058import org.threeten.bp.temporal.ChronoLocalDateTime;
059import org.threeten.bp.temporal.ChronoUnit;
060import org.threeten.bp.temporal.ISOChrono;
061import org.threeten.bp.temporal.Temporal;
062import org.threeten.bp.temporal.TemporalAccessor;
063import org.threeten.bp.temporal.TemporalAdder;
064import org.threeten.bp.temporal.TemporalAdjuster;
065import org.threeten.bp.temporal.TemporalAdjusters;
066import org.threeten.bp.temporal.TemporalField;
067import org.threeten.bp.temporal.TemporalQuery;
068import org.threeten.bp.temporal.TemporalSubtractor;
069import org.threeten.bp.temporal.TemporalUnit;
070import org.threeten.bp.temporal.ValueRange;
071import org.threeten.bp.zone.ZoneRules;
072
073/**
074 * A date-time without a time-zone in the ISO-8601 calendar system,
075 * such as {@code 2007-12-03T10:15:30}.
076 * <p>
077 * {@code LocalDateTime} is an immutable date-time object that represents a date-time,
078 * often viewed as year-month-day-hour-minute-second. Other date and time fields,
079 * such as day-of-year, day-of-week and week-of-year, can also be accessed.
080 * Time is represented to nanosecond precision.
081 * For example, the value "2nd October 2007 at 13:45.30.123456789" can be
082 * stored in a {@code LocalDateTime}.
083 * <p>
084 * This class does not store or represent a time-zone.
085 * Instead, it is a description of the date, as used for birthdays, combined with
086 * the local time as seen on a wall clock.
087 * It cannot represent an instant on the time-line without additional information
088 * such as an offset or time-zone.
089 * <p>
090 * The ISO-8601 calendar system is the modern civil calendar system used today
091 * in most of the world. It is equivalent to the proleptic Gregorian calendar
092 * system, in which today's rules for leap years are applied for all time.
093 * For most applications written today, the ISO-8601 rules are entirely suitable.
094 * However, any application that makes use of historical dates, and requires them
095 * to be accurate will find the ISO-8601 approach unsuitable.
096 *
097 * <h3>Specification for implementors</h3>
098 * This class is immutable and thread-safe.
099 */
100public final class LocalDateTime
101        extends DefaultInterfaceChronoLocalDateTime<ISOChrono>
102        implements Temporal, TemporalAdjuster, ChronoLocalDateTime<ISOChrono>, Serializable {
103
104    /**
105     * The minimum supported {@code LocalDateTime}, '-999999999-01-01T00:00:00'.
106     * This is the local date-time of midnight at the start of the minimum date.
107     * This combines {@link LocalDate#MIN} and {@link LocalTime#MIN}.
108     * This could be used by an application as a "far past" date-time.
109     */
110    public static final LocalDateTime MIN = LocalDateTime.of(LocalDate.MIN, LocalTime.MIN);
111    /**
112     * The maximum supported {@code LocalDateTime}, '+999999999-12-31T23:59:59.999999999'.
113     * This is the local date-time just before midnight at the end of the maximum date.
114     * This combines {@link LocalDate#MAX} and {@link LocalTime#MAX}.
115     * This could be used by an application as a "far future" date-time.
116     */
117    public static final LocalDateTime MAX = LocalDateTime.of(LocalDate.MAX, LocalTime.MAX);
118
119    /**
120     * Serialization version.
121     */
122    private static final long serialVersionUID = 6207766400415563566L;
123
124    /**
125     * The date part.
126     */
127    private final LocalDate date;
128    /**
129     * The time part.
130     */
131    private final LocalTime time;
132
133    //-----------------------------------------------------------------------
134    /**
135     * Obtains the current date-time from the system clock in the default time-zone.
136     * <p>
137     * This will query the {@link Clock#systemDefaultZone() system clock} in the default
138     * time-zone to obtain the current date-time.
139     * <p>
140     * Using this method will prevent the ability to use an alternate clock for testing
141     * because the clock is hard-coded.
142     *
143     * @return the current date-time using the system clock and default time-zone, not null
144     */
145    public static LocalDateTime now() {
146        return now(Clock.systemDefaultZone());
147    }
148
149    /**
150     * Obtains the current date-time from the system clock in the specified time-zone.
151     * <p>
152     * This will query the {@link Clock#system(ZoneId) system clock} to obtain the current date-time.
153     * Specifying the time-zone avoids dependence on the default time-zone.
154     * <p>
155     * Using this method will prevent the ability to use an alternate clock for testing
156     * because the clock is hard-coded.
157     *
158     * @param zone  the zone ID to use, not null
159     * @return the current date-time using the system clock, not null
160     */
161    public static LocalDateTime now(ZoneId zone) {
162        return now(Clock.system(zone));
163    }
164
165    /**
166     * Obtains the current date-time from the specified clock.
167     * <p>
168     * This will query the specified clock to obtain the current date-time.
169     * Using this method allows the use of an alternate clock for testing.
170     * The alternate clock may be introduced using {@link Clock dependency injection}.
171     *
172     * @param clock  the clock to use, not null
173     * @return the current date-time, not null
174     */
175    public static LocalDateTime now(Clock clock) {
176        Objects.requireNonNull(clock, "clock");
177        final Instant now = clock.instant();  // called once
178        ZoneOffset offset = clock.getZone().getRules().getOffset(now);
179        return ofEpochSecond(now.getEpochSecond(), now.getNano(), offset);
180    }
181
182    //-----------------------------------------------------------------------
183    /**
184     * Obtains an instance of {@code LocalDateTime} from year, month,
185     * day, hour and minute, setting the second and nanosecond to zero.
186     * <p>
187     * The day must be valid for the year and month, otherwise an exception will be thrown.
188     * The second and nanosecond fields will be set to zero.
189     *
190     * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
191     * @param month  the month-of-year to represent, not null
192     * @param dayOfMonth  the day-of-month to represent, from 1 to 31
193     * @param hour  the hour-of-day to represent, from 0 to 23
194     * @param minute  the minute-of-hour to represent, from 0 to 59
195     * @return the local date-time, not null
196     * @throws DateTimeException if the value of any field is out of range
197     * @throws DateTimeException if the day-of-month is invalid for the month-year
198     */
199    public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour, int minute) {
200        LocalDate date = LocalDate.of(year, month, dayOfMonth);
201        LocalTime time = LocalTime.of(hour, minute);
202        return new LocalDateTime(date, time);
203    }
204
205    /**
206     * Obtains an instance of {@code LocalDateTime} from year, month,
207     * day, hour, minute and second, setting the nanosecond to zero.
208     * <p>
209     * The day must be valid for the year and month, otherwise an exception will be thrown.
210     * The nanosecond field will be set to zero.
211     *
212     * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
213     * @param month  the month-of-year to represent, not null
214     * @param dayOfMonth  the day-of-month to represent, from 1 to 31
215     * @param hour  the hour-of-day to represent, from 0 to 23
216     * @param minute  the minute-of-hour to represent, from 0 to 59
217     * @param second  the second-of-minute to represent, from 0 to 59
218     * @return the local date-time, not null
219     * @throws DateTimeException if the value of any field is out of range
220     * @throws DateTimeException if the day-of-month is invalid for the month-year
221     */
222    public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour, int minute, int second) {
223        LocalDate date = LocalDate.of(year, month, dayOfMonth);
224        LocalTime time = LocalTime.of(hour, minute, second);
225        return new LocalDateTime(date, time);
226    }
227
228    /**
229     * Obtains an instance of {@code LocalDateTime} from year, month,
230     * day, hour, minute, second and nanosecond.
231     * <p>
232     * The day must be valid for the year and month, otherwise an exception will be thrown.
233     *
234     * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
235     * @param month  the month-of-year to represent, not null
236     * @param dayOfMonth  the day-of-month to represent, from 1 to 31
237     * @param hour  the hour-of-day to represent, from 0 to 23
238     * @param minute  the minute-of-hour to represent, from 0 to 59
239     * @param second  the second-of-minute to represent, from 0 to 59
240     * @param nanoOfSecond  the nano-of-second to represent, from 0 to 999,999,999
241     * @return the local date-time, not null
242     * @throws DateTimeException if the value of any field is out of range
243     * @throws DateTimeException if the day-of-month is invalid for the month-year
244     */
245    public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond) {
246        LocalDate date = LocalDate.of(year, month, dayOfMonth);
247        LocalTime time = LocalTime.of(hour, minute, second, nanoOfSecond);
248        return new LocalDateTime(date, time);
249    }
250
251    //-----------------------------------------------------------------------
252    /**
253     * Obtains an instance of {@code LocalDateTime} from year, month,
254     * day, hour and minute, setting the second and nanosecond to zero.
255     * <p>
256     * The day must be valid for the year and month, otherwise an exception will be thrown.
257     * The second and nanosecond fields will be set to zero.
258     *
259     * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
260     * @param month  the month-of-year to represent, from 1 (January) to 12 (December)
261     * @param dayOfMonth  the day-of-month to represent, from 1 to 31
262     * @param hour  the hour-of-day to represent, from 0 to 23
263     * @param minute  the minute-of-hour to represent, from 0 to 59
264     * @return the local date-time, not null
265     * @throws DateTimeException if the value of any field is out of range
266     * @throws DateTimeException if the day-of-month is invalid for the month-year
267     */
268    public static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute) {
269        LocalDate date = LocalDate.of(year, month, dayOfMonth);
270        LocalTime time = LocalTime.of(hour, minute);
271        return new LocalDateTime(date, time);
272    }
273
274    /**
275     * Obtains an instance of {@code LocalDateTime} from year, month,
276     * day, hour, minute and second, setting the nanosecond to zero.
277     * <p>
278     * The day must be valid for the year and month, otherwise an exception will be thrown.
279     * The nanosecond field will be set to zero.
280     *
281     * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
282     * @param month  the month-of-year to represent, from 1 (January) to 12 (December)
283     * @param dayOfMonth  the day-of-month to represent, from 1 to 31
284     * @param hour  the hour-of-day to represent, from 0 to 23
285     * @param minute  the minute-of-hour to represent, from 0 to 59
286     * @param second  the second-of-minute to represent, from 0 to 59
287     * @return the local date-time, not null
288     * @throws DateTimeException if the value of any field is out of range
289     * @throws DateTimeException if the day-of-month is invalid for the month-year
290     */
291    public static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute, int second) {
292        LocalDate date = LocalDate.of(year, month, dayOfMonth);
293        LocalTime time = LocalTime.of(hour, minute, second);
294        return new LocalDateTime(date, time);
295    }
296
297    /**
298     * Obtains an instance of {@code LocalDateTime} from year, month,
299     * day, hour, minute, second and nanosecond.
300     * <p>
301     * The day must be valid for the year and month, otherwise an exception will be thrown.
302     *
303     * @param year  the year to represent, from MIN_YEAR to MAX_YEAR
304     * @param month  the month-of-year to represent, from 1 (January) to 12 (December)
305     * @param dayOfMonth  the day-of-month to represent, from 1 to 31
306     * @param hour  the hour-of-day to represent, from 0 to 23
307     * @param minute  the minute-of-hour to represent, from 0 to 59
308     * @param second  the second-of-minute to represent, from 0 to 59
309     * @param nanoOfSecond  the nano-of-second to represent, from 0 to 999,999,999
310     * @return the local date-time, not null
311     * @throws DateTimeException if the value of any field is out of range
312     * @throws DateTimeException if the day-of-month is invalid for the month-year
313     */
314    public static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond) {
315        LocalDate date = LocalDate.of(year, month, dayOfMonth);
316        LocalTime time = LocalTime.of(hour, minute, second, nanoOfSecond);
317        return new LocalDateTime(date, time);
318    }
319
320    /**
321     * Obtains an instance of {@code LocalDateTime} from a date and time.
322     *
323     * @param date  the local date, not null
324     * @param time  the local time, not null
325     * @return the local date-time, not null
326     */
327    public static LocalDateTime of(LocalDate date, LocalTime time) {
328        Objects.requireNonNull(date, "date");
329        Objects.requireNonNull(time, "time");
330        return new LocalDateTime(date, time);
331    }
332
333    //-------------------------------------------------------------------------
334    /**
335     * Obtains an instance of {@code LocalDateTime} from an {@code Instant} and zone ID.
336     * <p>
337     * This creates a local date-time based on the specified instant.
338     * First, the offset from UTC/Greenwich is obtained using the zone ID and instant,
339     * which is simple as there is only one valid offset for each instant.
340     * Then, the instant and offset are used to calculate the local date-time.
341     *
342     * @param instant  the instant to create the date-time from, not null
343     * @param zone  the time-zone, which may be an offset, not null
344     * @return the local date-time, not null
345     * @throws DateTimeException if the result exceeds the supported range
346     */
347    public static LocalDateTime ofInstant(Instant instant, ZoneId zone) {
348        Objects.requireNonNull(instant, "instant");
349        Objects.requireNonNull(zone, "zone");
350        ZoneRules rules = zone.getRules();
351        ZoneOffset offset = rules.getOffset(instant);
352        return ofEpochSecond(instant.getEpochSecond(), instant.getNano(), offset);
353    }
354
355    /**
356     * Obtains an instance of {@code LocalDateTime} using seconds from the
357     * epoch of 1970-01-01T00:00:00Z.
358     * <p>
359     * This allows the {@link ChronoField#INSTANT_SECONDS epoch-second} field
360     * to be converted to a local date-time. This is primarily intended for
361     * low-level conversions rather than general application usage.
362     *
363     * @param epochSecond  the number of seconds from the epoch of 1970-01-01T00:00:00Z
364     * @param nanoOfSecond  the nanosecond within the second, from 0 to 999,999,999
365     * @param offset  the zone offset, not null
366     * @return the local date-time, not null
367     * @throws DateTimeException if the result exceeds the supported range
368     */
369    public static LocalDateTime ofEpochSecond(long epochSecond, int nanoOfSecond, ZoneOffset offset) {
370        Objects.requireNonNull(offset, "offset");
371        long localSecond = epochSecond + offset.getTotalSeconds();  // overflow caught later
372        long localEpochDay = Jdk8Methods.floorDiv(localSecond, SECONDS_PER_DAY);
373        int secsOfDay = Jdk8Methods.floorMod(localSecond, SECONDS_PER_DAY);
374        LocalDate date = LocalDate.ofEpochDay(localEpochDay);
375        LocalTime time = LocalTime.ofSecondOfDay(secsOfDay, nanoOfSecond);
376        return new LocalDateTime(date, time);
377    }
378
379    //-----------------------------------------------------------------------
380    /**
381     * Obtains an instance of {@code LocalDateTime} from a temporal object.
382     * <p>
383     * A {@code TemporalAccessor} represents some form of date and time information.
384     * This factory converts the arbitrary temporal object to an instance of {@code LocalDateTime}.
385     * <p>
386     * The conversion extracts and combines {@code LocalDate} and {@code LocalTime}.
387     * <p>
388     * This method matches the signature of the functional interface {@link TemporalQuery}
389     * allowing it to be used as a query via method reference, {@code LocalDateTime::from}.
390     *
391     * @param temporal  the temporal object to convert, not null
392     * @return the local date-time, not null
393     * @throws DateTimeException if unable to convert to a {@code LocalDateTime}
394     */
395    public static LocalDateTime from(TemporalAccessor temporal) {
396        if (temporal instanceof LocalDateTime) {
397            return (LocalDateTime) temporal;
398        } else if (temporal instanceof ZonedDateTime) {
399            return ((ZonedDateTime) temporal).getDateTime();
400        }
401        try {
402            LocalDate date = LocalDate.from(temporal);
403            LocalTime time = LocalTime.from(temporal);
404            return new LocalDateTime(date, time);
405        } catch (DateTimeException ex) {
406            throw new DateTimeException("Unable to obtain LocalDateTime from TemporalAccessor: " + temporal.getClass(), ex);
407        }
408    }
409
410    //-----------------------------------------------------------------------
411    /**
412     * Obtains an instance of {@code LocalDateTime} from a text string such as {@code 2007-12-03T10:15:30}.
413     * <p>
414     * The string must represent a valid date-time and is parsed using
415     * {@link org.threeten.bp.format.DateTimeFormatters#isoLocalDateTime()}.
416     *
417     * @param text  the text to parse such as "2007-12-03T10:15:30", not null
418     * @return the parsed local date-time, not null
419     * @throws DateTimeParseException if the text cannot be parsed
420     */
421    public static LocalDateTime parse(CharSequence text) {
422        return parse(text, DateTimeFormatters.isoLocalDateTime());
423    }
424
425    /**
426     * Obtains an instance of {@code LocalDateTime} from a text string using a specific formatter.
427     * <p>
428     * The text is parsed using the formatter, returning a date-time.
429     *
430     * @param text  the text to parse, not null
431     * @param formatter  the formatter to use, not null
432     * @return the parsed local date-time, not null
433     * @throws DateTimeParseException if the text cannot be parsed
434     */
435    public static LocalDateTime parse(CharSequence text, DateTimeFormatter formatter) {
436        Objects.requireNonNull(formatter, "formatter");
437        return formatter.parse(text, LocalDateTime.class);
438    }
439
440    //-----------------------------------------------------------------------
441    /**
442     * Constructor.
443     *
444     * @param date  the date part of the date-time, validated not null
445     * @param time  the time part of the date-time, validated not null
446     */
447    private LocalDateTime(LocalDate date, LocalTime time) {
448        this.date = date;
449        this.time = time;
450    }
451
452    /**
453     * Returns a copy of this date-time with the new date and time, checking
454     * to see if a new object is in fact required.
455     *
456     * @param newDate  the date of the new date-time, not null
457     * @param newTime  the time of the new date-time, not null
458     * @return the date-time, not null
459     */
460    private LocalDateTime with(LocalDate newDate, LocalTime newTime) {
461        if (date == newDate && time == newTime) {
462            return this;
463        }
464        return new LocalDateTime(newDate, newTime);
465    }
466
467    //-----------------------------------------------------------------------
468    /**
469     * Checks if the specified field is supported.
470     * <p>
471     * This checks if this date-time can be queried for the specified field.
472     * If false, then calling the {@link #range(TemporalField) range} and
473     * {@link #get(TemporalField) get} methods will throw an exception.
474     * <p>
475     * If the field is a {@link ChronoField} then the query is implemented here.
476     * The supported fields are:
477     * <ul>
478     * <li>{@code NANO_OF_SECOND}
479     * <li>{@code NANO_OF_DAY}
480     * <li>{@code MICRO_OF_SECOND}
481     * <li>{@code MICRO_OF_DAY}
482     * <li>{@code MILLI_OF_SECOND}
483     * <li>{@code MILLI_OF_DAY}
484     * <li>{@code SECOND_OF_MINUTE}
485     * <li>{@code SECOND_OF_DAY}
486     * <li>{@code MINUTE_OF_HOUR}
487     * <li>{@code MINUTE_OF_DAY}
488     * <li>{@code HOUR_OF_AMPM}
489     * <li>{@code CLOCK_HOUR_OF_AMPM}
490     * <li>{@code HOUR_OF_DAY}
491     * <li>{@code CLOCK_HOUR_OF_DAY}
492     * <li>{@code AMPM_OF_DAY}
493     * <li>{@code DAY_OF_WEEK}
494     * <li>{@code ALIGNED_DAY_OF_WEEK_IN_MONTH}
495     * <li>{@code ALIGNED_DAY_OF_WEEK_IN_YEAR}
496     * <li>{@code DAY_OF_MONTH}
497     * <li>{@code DAY_OF_YEAR}
498     * <li>{@code EPOCH_DAY}
499     * <li>{@code ALIGNED_WEEK_OF_MONTH}
500     * <li>{@code ALIGNED_WEEK_OF_YEAR}
501     * <li>{@code MONTH_OF_YEAR}
502     * <li>{@code EPOCH_MONTH}
503     * <li>{@code YEAR_OF_ERA}
504     * <li>{@code YEAR}
505     * <li>{@code ERA}
506     * </ul>
507     * All other {@code ChronoField} instances will return false.
508     * <p>
509     * If the field is not a {@code ChronoField}, then the result of this method
510     * is obtained by invoking {@code TemporalField.doIsSupported(TemporalAccessor)}
511     * passing {@code this} as the argument.
512     * Whether the field is supported is determined by the field.
513     *
514     * @param field  the field to check, null returns false
515     * @return true if the field is supported on this date-time, false if not
516     */
517    @Override
518    public boolean isSupported(TemporalField field) {
519        if (field instanceof ChronoField) {
520            ChronoField f = (ChronoField) field;
521            return f.isDateField() || f.isTimeField();
522        }
523        return field != null && field.doIsSupported(this);
524    }
525
526    /**
527     * Gets the range of valid values for the specified field.
528     * <p>
529     * The range object expresses the minimum and maximum valid values for a field.
530     * This date-time is used to enhance the accuracy of the returned range.
531     * If it is not possible to return the range, because the field is not supported
532     * or for some other reason, an exception is thrown.
533     * <p>
534     * If the field is a {@link ChronoField} then the query is implemented here.
535     * The {@link #isSupported(TemporalField) supported fields} will return
536     * appropriate range instances.
537     * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
538     * <p>
539     * If the field is not a {@code ChronoField}, then the result of this method
540     * is obtained by invoking {@code TemporalField.doRange(TemporalAccessor)}
541     * passing {@code this} as the argument.
542     * Whether the range can be obtained is determined by the field.
543     *
544     * @param field  the field to query the range for, not null
545     * @return the range of valid values for the field, not null
546     * @throws DateTimeException if the range for the field cannot be obtained
547     */
548    @Override
549    public ValueRange range(TemporalField field) {
550        if (field instanceof ChronoField) {
551            ChronoField f = (ChronoField) field;
552            return (f.isTimeField() ? time.range(field) : date.range(field));
553        }
554        return field.doRange(this);
555    }
556
557    /**
558     * Gets the value of the specified field from this date-time as an {@code int}.
559     * <p>
560     * This queries this date-time for the value for the specified field.
561     * The returned value will always be within the valid range of values for the field.
562     * If it is not possible to return the value, because the field is not supported
563     * or for some other reason, an exception is thrown.
564     * <p>
565     * If the field is a {@link ChronoField} then the query is implemented here.
566     * The {@link #isSupported(TemporalField) supported fields} will return valid
567     * values based on this date-time, except {@code NANO_OF_DAY}, {@code MICRO_OF_DAY},
568     * {@code EPOCH_DAY} and {@code EPOCH_MONTH} which are too large to fit in
569     * an {@code int} and throw a {@code DateTimeException}.
570     * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
571     * <p>
572     * If the field is not a {@code ChronoField}, then the result of this method
573     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
574     * passing {@code this} as the argument. Whether the value can be obtained,
575     * and what the value represents, is determined by the field.
576     *
577     * @param field  the field to get, not null
578     * @return the value for the field
579     * @throws DateTimeException if a value for the field cannot be obtained
580     * @throws ArithmeticException if numeric overflow occurs
581     */
582    @Override
583    public int get(TemporalField field) {
584        if (field instanceof ChronoField) {
585            ChronoField f = (ChronoField) field;
586            return (f.isTimeField() ? time.get(field) : date.get(field));
587        }
588        return super.get(field);
589    }
590
591    /**
592     * Gets the value of the specified field from this date-time as a {@code long}.
593     * <p>
594     * This queries this date-time for the value for the specified field.
595     * If it is not possible to return the value, because the field is not supported
596     * or for some other reason, an exception is thrown.
597     * <p>
598     * If the field is a {@link ChronoField} then the query is implemented here.
599     * The {@link #isSupported(TemporalField) supported fields} will return valid
600     * values based on this date-time.
601     * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
602     * <p>
603     * If the field is not a {@code ChronoField}, then the result of this method
604     * is obtained by invoking {@code TemporalField.doGet(TemporalAccessor)}
605     * passing {@code this} as the argument. Whether the value can be obtained,
606     * and what the value represents, is determined by the field.
607     *
608     * @param field  the field to get, not null
609     * @return the value for the field
610     * @throws DateTimeException if a value for the field cannot be obtained
611     * @throws ArithmeticException if numeric overflow occurs
612     */
613    @Override
614    public long getLong(TemporalField field) {
615        if (field instanceof ChronoField) {
616            ChronoField f = (ChronoField) field;
617            return (f.isTimeField() ? time.getLong(field) : date.getLong(field));
618        }
619        return field.doGet(this);
620    }
621
622    //-----------------------------------------------------------------------
623    /**
624     * Gets the {@code LocalDate} part of this date-time.
625     * <p>
626     * This returns a {@code LocalDate} with the same year, month and day
627     * as this date-time.
628     *
629     * @return the date part of this date-time, not null
630     */
631    @Override
632    public LocalDate getDate() {
633        return date;
634    }
635
636    /**
637     * Gets the year field.
638     * <p>
639     * This method returns the primitive {@code int} value for the year.
640     * <p>
641     * The year returned by this method is proleptic as per {@code get(YEAR)}.
642     * To obtain the year-of-era, use {@code get(YEAR_OF_ERA}.
643     *
644     * @return the year, from MIN_YEAR to MAX_YEAR
645     */
646    public int getYear() {
647        return date.getYear();
648    }
649
650    /**
651     * Gets the month-of-year field from 1 to 12.
652     * <p>
653     * This method returns the month as an {@code int} from 1 to 12.
654     * Application code is frequently clearer if the enum {@link Month}
655     * is used by calling {@link #getMonth()}.
656     *
657     * @return the month-of-year, from 1 to 12
658     * @see #getMonth()
659     */
660    public int getMonthValue() {
661        return date.getMonthValue();
662    }
663
664    /**
665     * Gets the month-of-year field using the {@code Month} enum.
666     * <p>
667     * This method returns the enum {@link Month} for the month.
668     * This avoids confusion as to what {@code int} values mean.
669     * If you need access to the primitive {@code int} value then the enum
670     * provides the {@link Month#getValue() int value}.
671     *
672     * @return the month-of-year, not null
673     * @see #getMonthValue()
674     */
675    public Month getMonth() {
676        return date.getMonth();
677    }
678
679    /**
680     * Gets the day-of-month field.
681     * <p>
682     * This method returns the primitive {@code int} value for the day-of-month.
683     *
684     * @return the day-of-month, from 1 to 31
685     */
686    public int getDayOfMonth() {
687        return date.getDayOfMonth();
688    }
689
690    /**
691     * Gets the day-of-year field.
692     * <p>
693     * This method returns the primitive {@code int} value for the day-of-year.
694     *
695     * @return the day-of-year, from 1 to 365, or 366 in a leap year
696     */
697    public int getDayOfYear() {
698        return date.getDayOfYear();
699    }
700
701    /**
702     * Gets the day-of-week field, which is an enum {@code DayOfWeek}.
703     * <p>
704     * This method returns the enum {@link DayOfWeek} for the day-of-week.
705     * This avoids confusion as to what {@code int} values mean.
706     * If you need access to the primitive {@code int} value then the enum
707     * provides the {@link DayOfWeek#getValue() int value}.
708     * <p>
709     * Additional information can be obtained from the {@code DayOfWeek}.
710     * This includes textual names of the values.
711     *
712     * @return the day-of-week, not null
713     */
714    public DayOfWeek getDayOfWeek() {
715        return date.getDayOfWeek();
716    }
717
718    //-----------------------------------------------------------------------
719    /**
720     * Gets the {@code LocalTime} part of this date-time.
721     * <p>
722     * This returns a {@code LocalTime} with the same hour, minute, second and
723     * nanosecond as this date-time.
724     *
725     * @return the time part of this date-time, not null
726     */
727    @Override
728    public LocalTime getTime() {
729        return time;
730    }
731
732    /**
733     * Gets the hour-of-day field.
734     *
735     * @return the hour-of-day, from 0 to 23
736     */
737    public int getHour() {
738        return time.getHour();
739    }
740
741    /**
742     * Gets the minute-of-hour field.
743     *
744     * @return the minute-of-hour, from 0 to 59
745     */
746    public int getMinute() {
747        return time.getMinute();
748    }
749
750    /**
751     * Gets the second-of-minute field.
752     *
753     * @return the second-of-minute, from 0 to 59
754     */
755    public int getSecond() {
756        return time.getSecond();
757    }
758
759    /**
760     * Gets the nano-of-second field.
761     *
762     * @return the nano-of-second, from 0 to 999,999,999
763     */
764    public int getNano() {
765        return time.getNano();
766    }
767
768    //-----------------------------------------------------------------------
769    /**
770     * Returns an adjusted copy of this date-time.
771     * <p>
772     * This returns a new {@code LocalDateTime}, based on this one, with the date-time adjusted.
773     * The adjustment takes place using the specified adjuster strategy object.
774     * Read the documentation of the adjuster to understand what adjustment will be made.
775     * <p>
776     * A simple adjuster might simply set the one of the fields, such as the year field.
777     * A more complex adjuster might set the date to the last day of the month.
778     * A selection of common adjustments is provided in {@link TemporalAdjusters}.
779     * These include finding the "last day of the month" and "next Wednesday".
780     * Key date-time classes also implement the {@code TemporalAdjuster} interface,
781     * such as {@link Month} and {@link MonthDay MonthDay}.
782     * The adjuster is responsible for handling special cases, such as the varying
783     * lengths of month and leap years.
784     * <p>
785     * For example this code returns a date on the last day of July:
786     * <pre>
787     *  import static org.threeten.bp.Month.*;
788     *  import static org.threeten.bp.temporal.Adjusters.*;
789     *
790     *  result = localDateTime.with(JULY).with(lastDayOfMonth());
791     * </pre>
792     * <p>
793     * The classes {@link LocalDate} and {@link LocalTime} implement {@code TemporalAdjuster},
794     * thus this method can be used to change the date, time or offset:
795     * <pre>
796     *  result = localDateTime.with(date);
797     *  result = localDateTime.with(time);
798     * </pre>
799     * <p>
800     * The result of this method is obtained by invoking the
801     * {@link TemporalAdjuster#adjustInto(Temporal)} method on the
802     * specified adjuster passing {@code this} as the argument.
803     * <p>
804     * This instance is immutable and unaffected by this method call.
805     *
806     * @param adjuster the adjuster to use, not null
807     * @return a {@code LocalDateTime} based on {@code this} with the adjustment made, not null
808     * @throws DateTimeException if the adjustment cannot be made
809     * @throws ArithmeticException if numeric overflow occurs
810     */
811    @Override
812    public LocalDateTime with(TemporalAdjuster adjuster) {
813        // optimizations
814        if (adjuster instanceof LocalDate) {
815            return with((LocalDate) adjuster, time);
816        } else if (adjuster instanceof LocalTime) {
817            return with(date, (LocalTime) adjuster);
818        } else if (adjuster instanceof LocalDateTime) {
819            return (LocalDateTime) adjuster;
820        }
821        return (LocalDateTime) adjuster.adjustInto(this);
822    }
823
824    /**
825     * Returns a copy of this date-time with the specified field set to a new value.
826     * <p>
827     * This returns a new {@code LocalDateTime}, based on this one, with the value
828     * for the specified field changed.
829     * This can be used to change any supported field, such as the year, month or day-of-month.
830     * If it is not possible to set the value, because the field is not supported or for
831     * some other reason, an exception is thrown.
832     * <p>
833     * In some cases, changing the specified field can cause the resulting date-time to become invalid,
834     * such as changing the month from 31st January to February would make the day-of-month invalid.
835     * In cases like this, the field is responsible for resolving the date. Typically it will choose
836     * the previous valid date, which would be the last valid day of February in this example.
837     * <p>
838     * If the field is a {@link ChronoField} then the adjustment is implemented here.
839     * The {@link #isSupported(TemporalField) supported fields} will behave as per
840     * the matching method on {@link LocalDate#with(TemporalField, long) LocalDate}
841     * or {@link LocalTime#with(TemporalField, long) LocalTime}.
842     * All other {@code ChronoField} instances will throw a {@code DateTimeException}.
843     * <p>
844     * If the field is not a {@code ChronoField}, then the result of this method
845     * is obtained by invoking {@code TemporalField.doWith(Temporal, long)}
846     * passing {@code this} as the argument. In this case, the field determines
847     * whether and how to adjust the instant.
848     * <p>
849     * This instance is immutable and unaffected by this method call.
850     *
851     * @param field  the field to set in the result, not null
852     * @param newValue  the new value of the field in the result
853     * @return a {@code LocalDateTime} based on {@code this} with the specified field set, not null
854     * @throws DateTimeException if the field cannot be set
855     * @throws ArithmeticException if numeric overflow occurs
856     */
857    @Override
858    public LocalDateTime with(TemporalField field, long newValue) {
859        if (field instanceof ChronoField) {
860            ChronoField f = (ChronoField) field;
861            if (f.isTimeField()) {
862                return with(date, time.with(field, newValue));
863            } else {
864                return with(date.with(field, newValue), time);
865            }
866        }
867        return field.doWith(this, newValue);
868    }
869
870    //-----------------------------------------------------------------------
871    /**
872     * Returns a copy of this {@code LocalDateTime} with the year altered.
873     * The time does not affect the calculation and will be the same in the result.
874     * If the day-of-month is invalid for the year, it will be changed to the last valid day of the month.
875     * <p>
876     * This instance is immutable and unaffected by this method call.
877     *
878     * @param year  the year to set in the result, from MIN_YEAR to MAX_YEAR
879     * @return a {@code LocalDateTime} based on this date-time with the requested year, not null
880     * @throws DateTimeException if the year value is invalid
881     */
882    public LocalDateTime withYear(int year) {
883        return with(date.withYear(year), time);
884    }
885
886    /**
887     * Returns a copy of this {@code LocalDateTime} with the month-of-year altered.
888     * The time does not affect the calculation and will be the same in the result.
889     * If the day-of-month is invalid for the year, it will be changed to the last valid day of the month.
890     * <p>
891     * This instance is immutable and unaffected by this method call.
892     *
893     * @param month  the month-of-year to set in the result, from 1 (January) to 12 (December)
894     * @return a {@code LocalDateTime} based on this date-time with the requested month, not null
895     * @throws DateTimeException if the month-of-year value is invalid
896     */
897    public LocalDateTime withMonth(int month) {
898        return with(date.withMonth(month), time);
899    }
900
901    /**
902     * Returns a copy of this {@code LocalDateTime} with the day-of-month altered.
903     * If the resulting {@code LocalDateTime} is invalid, an exception is thrown.
904     * The time does not affect the calculation and will be the same in the result.
905     * <p>
906     * This instance is immutable and unaffected by this method call.
907     *
908     * @param dayOfMonth  the day-of-month to set in the result, from 1 to 28-31
909     * @return a {@code LocalDateTime} based on this date-time with the requested day, not null
910     * @throws DateTimeException if the day-of-month value is invalid
911     * @throws DateTimeException if the day-of-month is invalid for the month-year
912     */
913    public LocalDateTime withDayOfMonth(int dayOfMonth) {
914        return with(date.withDayOfMonth(dayOfMonth), time);
915    }
916
917    /**
918     * Returns a copy of this {@code LocalDateTime} with the day-of-year altered.
919     * If the resulting {@code LocalDateTime} is invalid, an exception is thrown.
920     * <p>
921     * This instance is immutable and unaffected by this method call.
922     *
923     * @param dayOfYear  the day-of-year to set in the result, from 1 to 365-366
924     * @return a {@code LocalDateTime} based on this date with the requested day, not null
925     * @throws DateTimeException if the day-of-year value is invalid
926     * @throws DateTimeException if the day-of-year is invalid for the year
927     */
928    public LocalDateTime withDayOfYear(int dayOfYear) {
929        return with(date.withDayOfYear(dayOfYear), time);
930    }
931
932    //-----------------------------------------------------------------------
933    /**
934     * Returns a copy of this {@code LocalDateTime} with the hour-of-day value altered.
935     * <p>
936     * This instance is immutable and unaffected by this method call.
937     *
938     * @param hour  the hour-of-day to set in the result, from 0 to 23
939     * @return a {@code LocalDateTime} based on this date-time with the requested hour, not null
940     * @throws DateTimeException if the hour value is invalid
941     */
942    public LocalDateTime withHour(int hour) {
943        LocalTime newTime = time.withHour(hour);
944        return with(date, newTime);
945    }
946
947    /**
948     * Returns a copy of this {@code LocalDateTime} with the minute-of-hour value altered.
949     * <p>
950     * This instance is immutable and unaffected by this method call.
951     *
952     * @param minute  the minute-of-hour to set in the result, from 0 to 59
953     * @return a {@code LocalDateTime} based on this date-time with the requested minute, not null
954     * @throws DateTimeException if the minute value is invalid
955     */
956    public LocalDateTime withMinute(int minute) {
957        LocalTime newTime = time.withMinute(minute);
958        return with(date, newTime);
959    }
960
961    /**
962     * Returns a copy of this {@code LocalDateTime} with the second-of-minute value altered.
963     * <p>
964     * This instance is immutable and unaffected by this method call.
965     *
966     * @param second  the second-of-minute to set in the result, from 0 to 59
967     * @return a {@code LocalDateTime} based on this date-time with the requested second, not null
968     * @throws DateTimeException if the second value is invalid
969     */
970    public LocalDateTime withSecond(int second) {
971        LocalTime newTime = time.withSecond(second);
972        return with(date, newTime);
973    }
974
975    /**
976     * Returns a copy of this {@code LocalDateTime} with the nano-of-second value altered.
977     * <p>
978     * This instance is immutable and unaffected by this method call.
979     *
980     * @param nanoOfSecond  the nano-of-second to set in the result, from 0 to 999,999,999
981     * @return a {@code LocalDateTime} based on this date-time with the requested nanosecond, not null
982     * @throws DateTimeException if the nano value is invalid
983     */
984    public LocalDateTime withNano(int nanoOfSecond) {
985        LocalTime newTime = time.withNano(nanoOfSecond);
986        return with(date, newTime);
987    }
988
989    //-----------------------------------------------------------------------
990    /**
991     * Returns a copy of this {@code LocalDateTime} with the time truncated.
992     * <p>
993     * Truncation returns a copy of the original date-time with fields
994     * smaller than the specified unit set to zero.
995     * For example, truncating with the {@link ChronoUnit#MINUTES minutes} unit
996     * will set the second-of-minute and nano-of-second field to zero.
997     * <p>
998     * Not all units are accepted. The {@link ChronoUnit#DAYS days} unit and time
999     * units with an exact duration can be used, other units throw an exception.
1000     * <p>
1001     * This instance is immutable and unaffected by this method call.
1002     *
1003     * @param unit  the unit to truncate to, not null
1004     * @return a {@code LocalDateTime} based on this date-time with the time truncated, not null
1005     * @throws DateTimeException if unable to truncate
1006     */
1007    public LocalDateTime truncatedTo(TemporalUnit unit) {
1008        return with(date, time.truncatedTo(unit));
1009    }
1010
1011    //-----------------------------------------------------------------------
1012    /**
1013     * Returns a copy of this date-time with the specified period added.
1014     * <p>
1015     * This method returns a new date-time based on this time with the specified period added.
1016     * The adder is typically {@link Period} but may be any other type implementing
1017     * the {@link TemporalAdder} interface.
1018     * The calculation is delegated to the specified adjuster, which typically calls
1019     * back to {@link #plus(long, TemporalUnit)}.
1020     * <p>
1021     * This instance is immutable and unaffected by this method call.
1022     *
1023     * @param adder  the adder to use, not null
1024     * @return a {@code LocalDateTime} based on this date-time with the addition made, not null
1025     * @throws DateTimeException if the addition cannot be made
1026     * @throws ArithmeticException if numeric overflow occurs
1027     */
1028    @Override
1029    public LocalDateTime plus(TemporalAdder adder) {
1030        return (LocalDateTime) adder.addTo(this);
1031    }
1032
1033    /**
1034     * Returns a copy of this date-time with the specified period added.
1035     * <p>
1036     * This method returns a new date-time based on this date-time with the specified period added.
1037     * This can be used to add any period that is defined by a unit, for example to add years, months or days.
1038     * The unit is responsible for the details of the calculation, including the resolution
1039     * of any edge cases in the calculation.
1040     * <p>
1041     * This instance is immutable and unaffected by this method call.
1042     *
1043     * @param amountToAdd  the amount of the unit to add to the result, may be negative
1044     * @param unit  the unit of the period to add, not null
1045     * @return a {@code LocalDateTime} based on this date-time with the specified period added, not null
1046     * @throws DateTimeException if the unit cannot be added to this type
1047     */
1048    @Override
1049    public LocalDateTime plus(long amountToAdd, TemporalUnit unit) {
1050        if (unit instanceof ChronoUnit) {
1051            ChronoUnit f = (ChronoUnit) unit;
1052            switch (f) {
1053                case NANOS: return plusNanos(amountToAdd);
1054                case MICROS: return plusDays(amountToAdd / MICROS_PER_DAY).plusNanos((amountToAdd % MICROS_PER_DAY) * 1000);
1055                case MILLIS: return plusDays(amountToAdd / MILLIS_PER_DAY).plusNanos((amountToAdd % MILLIS_PER_DAY) * 1000_000);
1056                case SECONDS: return plusSeconds(amountToAdd);
1057                case MINUTES: return plusMinutes(amountToAdd);
1058                case HOURS: return plusHours(amountToAdd);
1059                case HALF_DAYS: return plusDays(amountToAdd / 256).plusHours((amountToAdd % 256) * 12);  // no overflow (256 is multiple of 2)
1060            }
1061            return with(date.plus(amountToAdd, unit), time);
1062        }
1063        return unit.doPlus(this, amountToAdd);
1064    }
1065
1066    //-----------------------------------------------------------------------
1067    /**
1068     * Returns a copy of this {@code LocalDateTime} with the specified period in years added.
1069     * <p>
1070     * This method adds the specified amount to the years field in three steps:
1071     * <ol>
1072     * <li>Add the input years to the year field</li>
1073     * <li>Check if the resulting date would be invalid</li>
1074     * <li>Adjust the day-of-month to the last valid day if necessary</li>
1075     * </ol>
1076     * <p>
1077     * For example, 2008-02-29 (leap year) plus one year would result in the
1078     * invalid date 2009-02-29 (standard year). Instead of returning an invalid
1079     * result, the last valid day of the month, 2009-02-28, is selected instead.
1080     * <p>
1081     * This instance is immutable and unaffected by this method call.
1082     *
1083     * @param years  the years to add, may be negative
1084     * @return a {@code LocalDateTime} based on this date-time with the years added, not null
1085     * @throws DateTimeException if the result exceeds the supported date range
1086     */
1087    public LocalDateTime plusYears(long years) {
1088        LocalDate newDate = date.plusYears(years);
1089        return with(newDate, time);
1090    }
1091
1092    /**
1093     * Returns a copy of this {@code LocalDateTime} with the specified period in months added.
1094     * <p>
1095     * This method adds the specified amount to the months field in three steps:
1096     * <ol>
1097     * <li>Add the input months to the month-of-year field</li>
1098     * <li>Check if the resulting date would be invalid</li>
1099     * <li>Adjust the day-of-month to the last valid day if necessary</li>
1100     * </ol>
1101     * <p>
1102     * For example, 2007-03-31 plus one month would result in the invalid date
1103     * 2007-04-31. Instead of returning an invalid result, the last valid day
1104     * of the month, 2007-04-30, is selected instead.
1105     * <p>
1106     * This instance is immutable and unaffected by this method call.
1107     *
1108     * @param months  the months to add, may be negative
1109     * @return a {@code LocalDateTime} based on this date-time with the months added, not null
1110     * @throws DateTimeException if the result exceeds the supported date range
1111     */
1112    public LocalDateTime plusMonths(long months) {
1113        LocalDate newDate = date.plusMonths(months);
1114        return with(newDate, time);
1115    }
1116
1117    /**
1118     * Returns a copy of this {@code LocalDateTime} with the specified period in weeks added.
1119     * <p>
1120     * This method adds the specified amount in weeks to the days field incrementing
1121     * the month and year fields as necessary to ensure the result remains valid.
1122     * The result is only invalid if the maximum/minimum year is exceeded.
1123     * <p>
1124     * For example, 2008-12-31 plus one week would result in 2009-01-07.
1125     * <p>
1126     * This instance is immutable and unaffected by this method call.
1127     *
1128     * @param weeks  the weeks to add, may be negative
1129     * @return a {@code LocalDateTime} based on this date-time with the weeks added, not null
1130     * @throws DateTimeException if the result exceeds the supported date range
1131     */
1132    public LocalDateTime plusWeeks(long weeks) {
1133        LocalDate newDate = date.plusWeeks(weeks);
1134        return with(newDate, time);
1135    }
1136
1137    /**
1138     * Returns a copy of this {@code LocalDateTime} with the specified period in days added.
1139     * <p>
1140     * This method adds the specified amount to the days field incrementing the
1141     * month and year fields as necessary to ensure the result remains valid.
1142     * The result is only invalid if the maximum/minimum year is exceeded.
1143     * <p>
1144     * For example, 2008-12-31 plus one day would result in 2009-01-01.
1145     * <p>
1146     * This instance is immutable and unaffected by this method call.
1147     *
1148     * @param days  the days to add, may be negative
1149     * @return a {@code LocalDateTime} based on this date-time with the days added, not null
1150     * @throws DateTimeException if the result exceeds the supported date range
1151     */
1152    public LocalDateTime plusDays(long days) {
1153        LocalDate newDate = date.plusDays(days);
1154        return with(newDate, time);
1155    }
1156
1157    //-----------------------------------------------------------------------
1158    /**
1159     * Returns a copy of this {@code LocalDateTime} with the specified period in hours added.
1160     * <p>
1161     * This instance is immutable and unaffected by this method call.
1162     *
1163     * @param hours  the hours to add, may be negative
1164     * @return a {@code LocalDateTime} based on this date-time with the hours added, not null
1165     * @throws DateTimeException if the result exceeds the supported date range
1166     */
1167    public LocalDateTime plusHours(long hours) {
1168        return plusWithOverflow(date, hours, 0, 0, 0, 1);
1169    }
1170
1171    /**
1172     * Returns a copy of this {@code LocalDateTime} with the specified period in minutes added.
1173     * <p>
1174     * This instance is immutable and unaffected by this method call.
1175     *
1176     * @param minutes  the minutes to add, may be negative
1177     * @return a {@code LocalDateTime} based on this date-time with the minutes added, not null
1178     * @throws DateTimeException if the result exceeds the supported date range
1179     */
1180    public LocalDateTime plusMinutes(long minutes) {
1181        return plusWithOverflow(date, 0, minutes, 0, 0, 1);
1182    }
1183
1184    /**
1185     * Returns a copy of this {@code LocalDateTime} with the specified period in seconds added.
1186     * <p>
1187     * This instance is immutable and unaffected by this method call.
1188     *
1189     * @param seconds  the seconds to add, may be negative
1190     * @return a {@code LocalDateTime} based on this date-time with the seconds added, not null
1191     * @throws DateTimeException if the result exceeds the supported date range
1192     */
1193    public LocalDateTime plusSeconds(long seconds) {
1194        return plusWithOverflow(date, 0, 0, seconds, 0, 1);
1195    }
1196
1197    /**
1198     * Returns a copy of this {@code LocalDateTime} with the specified period in nanoseconds added.
1199     * <p>
1200     * This instance is immutable and unaffected by this method call.
1201     *
1202     * @param nanos  the nanos to add, may be negative
1203     * @return a {@code LocalDateTime} based on this date-time with the nanoseconds added, not null
1204     * @throws DateTimeException if the result exceeds the supported date range
1205     */
1206    public LocalDateTime plusNanos(long nanos) {
1207        return plusWithOverflow(date, 0, 0, 0, nanos, 1);
1208    }
1209
1210    //-----------------------------------------------------------------------
1211    /**
1212     * Returns a copy of this date-time with the specified period subtracted.
1213     * <p>
1214     * This method returns a new date-time based on this time with the specified period subtracted.
1215     * The subtractor is typically {@link Period} but may be any other type implementing
1216     * the {@link TemporalSubtractor} interface.
1217     * The calculation is delegated to the specified adjuster, which typically calls
1218     * back to {@link #minus(long, TemporalUnit)}.
1219     * <p>
1220     * This instance is immutable and unaffected by this method call.
1221     *
1222     * @param subtractor  the subtractor to use, not null
1223     * @return a {@code LocalDateTime} based on this date-time with the subtraction made, not null
1224     * @throws DateTimeException if the subtraction cannot be made
1225     * @throws ArithmeticException if numeric overflow occurs
1226     */
1227    @Override
1228    public LocalDateTime minus(TemporalSubtractor subtractor) {
1229        return (LocalDateTime) subtractor.subtractFrom(this);
1230    }
1231
1232    /**
1233     * Returns a copy of this date-time with the specified period subtracted.
1234     * <p>
1235     * This method returns a new date-time based on this date-time with the specified period subtracted.
1236     * This can be used to subtract any period that is defined by a unit, for example to subtract years, months or days.
1237     * The unit is responsible for the details of the calculation, including the resolution
1238     * of any edge cases in the calculation.
1239     * <p>
1240     * This instance is immutable and unaffected by this method call.
1241     *
1242     * @param amountToSubtract  the amount of the unit to subtract from the result, may be negative
1243     * @param unit  the unit of the period to subtract, not null
1244     * @return a {@code LocalDateTime} based on this date-time with the specified period subtracted, not null
1245     * @throws DateTimeException if the unit cannot be added to this type
1246     */
1247    @Override
1248    public LocalDateTime minus(long amountToSubtract, TemporalUnit unit) {
1249        return (amountToSubtract == Long.MIN_VALUE ? plus(Long.MAX_VALUE, unit).plus(1, unit) : plus(-amountToSubtract, unit));
1250    }
1251
1252    //-----------------------------------------------------------------------
1253    /**
1254     * Returns a copy of this {@code LocalDateTime} with the specified period in years subtracted.
1255     * <p>
1256     * This method subtracts the specified amount from the years field in three steps:
1257     * <ol>
1258     * <li>Subtract the input years from the year field</li>
1259     * <li>Check if the resulting date would be invalid</li>
1260     * <li>Adjust the day-of-month to the last valid day if necessary</li>
1261     * </ol>
1262     * <p>
1263     * For example, 2008-02-29 (leap year) minus one year would result in the
1264     * invalid date 2009-02-29 (standard year). Instead of returning an invalid
1265     * result, the last valid day of the month, 2009-02-28, is selected instead.
1266     * <p>
1267     * This instance is immutable and unaffected by this method call.
1268     *
1269     * @param years  the years to subtract, may be negative
1270     * @return a {@code LocalDateTime} based on this date-time with the years subtracted, not null
1271     * @throws DateTimeException if the result exceeds the supported date range
1272     */
1273    public LocalDateTime minusYears(long years) {
1274        return (years == Long.MIN_VALUE ? plusYears(Long.MAX_VALUE).plusYears(1) : plusYears(-years));
1275    }
1276
1277    /**
1278     * Returns a copy of this {@code LocalDateTime} with the specified period in months subtracted.
1279     * <p>
1280     * This method subtracts the specified amount from the months field in three steps:
1281     * <ol>
1282     * <li>Subtract the input months from the month-of-year field</li>
1283     * <li>Check if the resulting date would be invalid</li>
1284     * <li>Adjust the day-of-month to the last valid day if necessary</li>
1285     * </ol>
1286     * <p>
1287     * For example, 2007-03-31 minus one month would result in the invalid date
1288     * 2007-04-31. Instead of returning an invalid result, the last valid day
1289     * of the month, 2007-04-30, is selected instead.
1290     * <p>
1291     * This instance is immutable and unaffected by this method call.
1292     *
1293     * @param months  the months to subtract, may be negative
1294     * @return a {@code LocalDateTime} based on this date-time with the months subtracted, not null
1295     * @throws DateTimeException if the result exceeds the supported date range
1296     */
1297    public LocalDateTime minusMonths(long months) {
1298        return (months == Long.MIN_VALUE ? plusMonths(Long.MAX_VALUE).plusMonths(1) : plusMonths(-months));
1299    }
1300
1301    /**
1302     * Returns a copy of this {@code LocalDateTime} with the specified period in weeks subtracted.
1303     * <p>
1304     * This method subtracts the specified amount in weeks from the days field decrementing
1305     * the month and year fields as necessary to ensure the result remains valid.
1306     * The result is only invalid if the maximum/minimum year is exceeded.
1307     * <p>
1308     * For example, 2009-01-07 minus one week would result in 2008-12-31.
1309     * <p>
1310     * This instance is immutable and unaffected by this method call.
1311     *
1312     * @param weeks  the weeks to subtract, may be negative
1313     * @return a {@code LocalDateTime} based on this date-time with the weeks subtracted, not null
1314     * @throws DateTimeException if the result exceeds the supported date range
1315     */
1316    public LocalDateTime minusWeeks(long weeks) {
1317        return (weeks == Long.MIN_VALUE ? plusWeeks(Long.MAX_VALUE).plusWeeks(1) : plusWeeks(-weeks));
1318    }
1319
1320    /**
1321     * Returns a copy of this {@code LocalDateTime} with the specified period in days subtracted.
1322     * <p>
1323     * This method subtracts the specified amount from the days field incrementing the
1324     * month and year fields as necessary to ensure the result remains valid.
1325     * The result is only invalid if the maximum/minimum year is exceeded.
1326     * <p>
1327     * For example, 2009-01-01 minus one day would result in 2008-12-31.
1328     * <p>
1329     * This instance is immutable and unaffected by this method call.
1330     *
1331     * @param days  the days to subtract, may be negative
1332     * @return a {@code LocalDateTime} based on this date-time with the days subtracted, not null
1333     * @throws DateTimeException if the result exceeds the supported date range
1334     */
1335    public LocalDateTime minusDays(long days) {
1336        return (days == Long.MIN_VALUE ? plusDays(Long.MAX_VALUE).plusDays(1) : plusDays(-days));
1337    }
1338
1339    //-----------------------------------------------------------------------
1340    /**
1341     * Returns a copy of this {@code LocalDateTime} with the specified period in hours subtracted.
1342     * <p>
1343     * This instance is immutable and unaffected by this method call.
1344     *
1345     * @param hours  the hours to subtract, may be negative
1346     * @return a {@code LocalDateTime} based on this date-time with the hours subtracted, not null
1347     * @throws DateTimeException if the result exceeds the supported date range
1348     */
1349    public LocalDateTime minusHours(long hours) {
1350        return plusWithOverflow(date, hours, 0, 0, 0, -1);
1351   }
1352
1353    /**
1354     * Returns a copy of this {@code LocalDateTime} with the specified period in minutes subtracted.
1355     * <p>
1356     * This instance is immutable and unaffected by this method call.
1357     *
1358     * @param minutes  the minutes to subtract, may be negative
1359     * @return a {@code LocalDateTime} based on this date-time with the minutes subtracted, not null
1360     * @throws DateTimeException if the result exceeds the supported date range
1361     */
1362    public LocalDateTime minusMinutes(long minutes) {
1363        return plusWithOverflow(date, 0, minutes, 0, 0, -1);
1364    }
1365
1366    /**
1367     * Returns a copy of this {@code LocalDateTime} with the specified period in seconds subtracted.
1368     * <p>
1369     * This instance is immutable and unaffected by this method call.
1370     *
1371     * @param seconds  the seconds to subtract, may be negative
1372     * @return a {@code LocalDateTime} based on this date-time with the seconds subtracted, not null
1373     * @throws DateTimeException if the result exceeds the supported date range
1374     */
1375    public LocalDateTime minusSeconds(long seconds) {
1376        return plusWithOverflow(date, 0, 0, seconds, 0, -1);
1377    }
1378
1379    /**
1380     * Returns a copy of this {@code LocalDateTime} with the specified period in nanoseconds subtracted.
1381     * <p>
1382     * This instance is immutable and unaffected by this method call.
1383     *
1384     * @param nanos  the nanos to subtract, may be negative
1385     * @return a {@code LocalDateTime} based on this date-time with the nanoseconds subtracted, not null
1386     * @throws DateTimeException if the result exceeds the supported date range
1387     */
1388    public LocalDateTime minusNanos(long nanos) {
1389        return plusWithOverflow(date, 0, 0, 0, nanos, -1);
1390    }
1391
1392    //-----------------------------------------------------------------------
1393    /**
1394     * Returns a copy of this {@code LocalDateTime} with the specified period added.
1395     * <p>
1396     * This instance is immutable and unaffected by this method call.
1397     *
1398     * @param newDate  the new date to base the calculation on, not null
1399     * @param hours  the hours to add, may be negative
1400     * @param minutes the minutes to add, may be negative
1401     * @param seconds the seconds to add, may be negative
1402     * @param nanos the nanos to add, may be negative
1403     * @param sign  the sign to determine add or subtract
1404     * @return the combined result, not null
1405     */
1406    private LocalDateTime plusWithOverflow(LocalDate newDate, long hours, long minutes, long seconds, long nanos, int sign) {
1407        // 9223372036854775808 long, 2147483648 int
1408        if ((hours | minutes | seconds | nanos) == 0) {
1409            return with(newDate, time);
1410        }
1411        long totDays = nanos / NANOS_PER_DAY +             //   max/24*60*60*1B
1412                seconds / SECONDS_PER_DAY +                //   max/24*60*60
1413                minutes / MINUTES_PER_DAY +                //   max/24*60
1414                hours / HOURS_PER_DAY;                     //   max/24
1415        totDays *= sign;                                   // total max*0.4237...
1416        long totNanos = nanos % NANOS_PER_DAY +                    //   max  86400000000000
1417                (seconds % SECONDS_PER_DAY) * NANOS_PER_SECOND +   //   max  86400000000000
1418                (minutes % MINUTES_PER_DAY) * NANOS_PER_MINUTE +   //   max  86400000000000
1419                (hours % HOURS_PER_DAY) * NANOS_PER_HOUR;          //   max  86400000000000
1420        long curNoD = time.toNanoOfDay();                       //   max  86400000000000
1421        totNanos = totNanos * sign + curNoD;                    // total 432000000000000
1422        totDays += Jdk8Methods.floorDiv(totNanos, NANOS_PER_DAY);
1423        long newNoD = Jdk8Methods.floorMod(totNanos, NANOS_PER_DAY);
1424        LocalTime newTime = (newNoD == curNoD ? time : LocalTime.ofNanoOfDay(newNoD));
1425        return with(newDate.plusDays(totDays), newTime);
1426    }
1427
1428    //-----------------------------------------------------------------------
1429    /**
1430     * Queries this date-time using the specified query.
1431     * <p>
1432     * This queries this date-time using the specified query strategy object.
1433     * The {@code TemporalQuery} object defines the logic to be used to
1434     * obtain the result. Read the documentation of the query to understand
1435     * what the result of this method will be.
1436     * <p>
1437     * The result of this method is obtained by invoking the
1438     * {@link TemporalQuery#queryFrom(TemporalAccessor)} method on the
1439     * specified query passing {@code this} as the argument.
1440     *
1441     * @param <R> the type of the result
1442     * @param query  the query to invoke, not null
1443     * @return the query result, null may be returned (defined by the query)
1444     * @throws DateTimeException if unable to query (defined by the query)
1445     * @throws ArithmeticException if numeric overflow occurs (defined by the query)
1446     */
1447    @Override  // override for Javadoc
1448    public <R> R query(TemporalQuery<R> query) {
1449        return super.query(query);
1450    }
1451
1452    /**
1453     * Adjusts the specified temporal object to have the same date and time as this object.
1454     * <p>
1455     * This returns a temporal object of the same observable type as the input
1456     * with the date and time changed to be the same as this.
1457     * <p>
1458     * The adjustment is equivalent to using {@link Temporal#with(TemporalField, long)}
1459     * twice, passing {@link ChronoField#EPOCH_DAY} and
1460     * {@link ChronoField#NANO_OF_DAY} as the fields.
1461     * <p>
1462     * In most cases, it is clearer to reverse the calling pattern by using
1463     * {@link Temporal#with(TemporalAdjuster)}:
1464     * <pre>
1465     *   // these two lines are equivalent, but the second approach is recommended
1466     *   temporal = thisLocalDateTime.adjustInto(temporal);
1467     *   temporal = temporal.with(thisLocalDateTime);
1468     * </pre>
1469     * <p>
1470     * This instance is immutable and unaffected by this method call.
1471     *
1472     * @param temporal  the target object to be adjusted, not null
1473     * @return the adjusted object, not null
1474     * @throws DateTimeException if unable to make the adjustment
1475     * @throws ArithmeticException if numeric overflow occurs
1476     */
1477    @Override  // override for Javadoc
1478    public Temporal adjustInto(Temporal temporal) {
1479        return super.adjustInto(temporal);
1480    }
1481
1482    /**
1483     * Calculates the period between this date-time and another date-time in
1484     * terms of the specified unit.
1485     * <p>
1486     * This calculates the period between two date-times in terms of a single unit.
1487     * The start and end points are {@code this} and the specified date-time.
1488     * The result will be negative if the end is before the start.
1489     * The {@code Temporal} passed to this method must be a {@code LocalDateTime}.
1490     * For example, the period in days between two date-times can be calculated
1491     * using {@code startDateTime.periodUntil(endDateTime, DAYS)}.
1492     * <p>
1493     * The calculation returns a whole number, representing the number of
1494     * complete units between the two date-times.
1495     * For example, the period in months between 2012-06-15T00:00 and 2012-08-14T23:59
1496     * will only be one month as it is one minute short of two months.
1497     * <p>
1498     * This method operates in association with {@link TemporalUnit#between}.
1499     * The result of this method is a {@code long} representing the amount of
1500     * the specified unit. By contrast, the result of {@code between} is an
1501     * object that can be used directly in addition/subtraction:
1502     * <pre>
1503     *   long period = start.periodUntil(end, MONTHS);   // this method
1504     *   dateTime.plus(MONTHS.between(start, end));      // use in plus/minus
1505     * </pre>
1506     * <p>
1507     * The calculation is implemented in this method for {@link ChronoUnit}.
1508     * The units {@code NANOS}, {@code MICROS}, {@code MILLIS}, {@code SECONDS},
1509     * {@code MINUTES}, {@code HOURS} and {@code HALF_DAYS}, {@code DAYS},
1510     * {@code WEEKS}, {@code MONTHS}, {@code YEARS}, {@code DECADES},
1511     * {@code CENTURIES}, {@code MILLENNIA} and {@code ERAS} are supported.
1512     * Other {@code ChronoUnit} values will throw an exception.
1513     * <p>
1514     * If the unit is not a {@code ChronoUnit}, then the result of this method
1515     * is obtained by invoking {@code TemporalUnit.between(Temporal, Temporal)}
1516     * passing {@code this} as the first argument and the input temporal as
1517     * the second argument.
1518     * <p>
1519     * This instance is immutable and unaffected by this method call.
1520     *
1521     * @param endDateTime  the end date-time, which must be a {@code LocalDateTime}, not null
1522     * @param unit  the unit to measure the period in, not null
1523     * @return the amount of the period between this date-time and the end date-time
1524     * @throws DateTimeException if the period cannot be calculated
1525     * @throws ArithmeticException if numeric overflow occurs
1526     */
1527    @Override
1528    public long periodUntil(Temporal endDateTime, TemporalUnit unit) {
1529        if (endDateTime instanceof LocalDateTime == false) {
1530            Objects.requireNonNull(endDateTime, "endDateTime");
1531            throw new DateTimeException("Unable to calculate period between objects of two different types");
1532        }
1533        LocalDateTime end = (LocalDateTime) endDateTime;
1534        if (unit instanceof ChronoUnit) {
1535            ChronoUnit f = (ChronoUnit) unit;
1536            if (f.isTimeUnit()) {
1537                long amount = date.daysUntil(end.date);
1538                switch (f) {
1539                    case NANOS: amount = Jdk8Methods.safeMultiply(amount, NANOS_PER_DAY); break;
1540                    case MICROS: amount = Jdk8Methods.safeMultiply(amount, MICROS_PER_DAY); break;
1541                    case MILLIS: amount = Jdk8Methods.safeMultiply(amount, MILLIS_PER_DAY); break;
1542                    case SECONDS: amount = Jdk8Methods.safeMultiply(amount, SECONDS_PER_DAY); break;
1543                    case MINUTES: amount = Jdk8Methods.safeMultiply(amount, MINUTES_PER_DAY); break;
1544                    case HOURS: amount = Jdk8Methods.safeMultiply(amount, HOURS_PER_DAY); break;
1545                    case HALF_DAYS: amount = Jdk8Methods.safeMultiply(amount, 2); break;
1546                }
1547                return Jdk8Methods.safeAdd(amount, time.periodUntil(end.time, unit));
1548            }
1549            LocalDate endDate = end.date;
1550            if (end.time.isBefore(time)) {
1551                endDate = endDate.minusDays(1);
1552            }
1553            return date.periodUntil(endDate, unit);
1554        }
1555        return unit.between(this, endDateTime).getAmount();
1556    }
1557
1558    //-----------------------------------------------------------------------
1559    /**
1560     * Returns an offset date-time formed from this date-time and the specified offset.
1561     * <p>
1562     * This combines this date-time with the specified offset to form an {@code OffsetDateTime}.
1563     * All possible combinations of date-time and offset are valid.
1564     * <p>
1565     * This instance is immutable and unaffected by this method call.
1566     *
1567     * @param offset  the offset to combine with, not null
1568     * @return the offset date-time formed from this date-time and the specified offset, not null
1569     */
1570    public OffsetDateTime atOffset(ZoneOffset offset) {
1571        return OffsetDateTime.of(this, offset);
1572    }
1573
1574    /**
1575     * Returns a zoned date-time formed from this date-time and the specified time-zone.
1576     * <p>
1577     * This creates a zoned date-time matching the input date-time as closely as possible.
1578     * Time-zone rules, such as daylight savings, mean that not every local date-time
1579     * is valid for the specified zone, thus the local date-time may be adjusted.
1580     * <p>
1581     * The local date-time is resolved to a single instant on the time-line.
1582     * This is achieved by finding a valid offset from UTC/Greenwich for the local
1583     * date-time as defined by the {@link ZoneRules rules} of the zone ID.
1584     *<p>
1585     * In most cases, there is only one valid offset for a local date-time.
1586     * In the case of an overlap, where clocks are set back, there are two valid offsets.
1587     * This method uses the earlier offset typically corresponding to "summer".
1588     * <p>
1589     * In the case of a gap, where clocks jump forward, there is no valid offset.
1590     * Instead, the local date-time is adjusted to be later by the length of the gap.
1591     * For a typical one hour daylight savings change, the local date-time will be
1592     * moved one hour later into the offset typically corresponding to "summer".
1593     * <p>
1594     * To obtain the later offset during an overlap, call
1595     * {@link ZonedDateTime#withLaterOffsetAtOverlap()} on the result of this method.
1596     * To throw an exception when there is a gap or overlap, use
1597     * {@link ZonedDateTime#ofStrict(LocalDateTime, ZoneOffset, ZoneId)}.
1598     * <p>
1599     * This instance is immutable and unaffected by this method call.
1600     *
1601     * @param zone  the time-zone to use, not null
1602     * @return the zoned date-time formed from this date-time, not null
1603     */
1604    @Override
1605    public ZonedDateTime atZone(ZoneId zone) {
1606        return ZonedDateTime.of(this, zone);
1607    }
1608
1609    //-----------------------------------------------------------------------
1610    /**
1611     * Compares this date-time to another date-time.
1612     * <p>
1613     * The comparison is primarily based on the date-time, from earliest to latest.
1614     * It is "consistent with equals", as defined by {@link Comparable}.
1615     * <p>
1616     * If all the date-times being compared are instances of {@code LocalDateTime},
1617     * then the comparison will be entirely based on the date-time.
1618     * If some dates being compared are in different chronologies, then the
1619     * chronology is also considered, see {@link ChronoLocalDateTime#compareTo}.
1620     *
1621     * @param other  the other date-time to compare to, not null
1622     * @return the comparator value, negative if less, positive if greater
1623     */
1624    @Override  // override for Javadoc and performance
1625    public int compareTo(ChronoLocalDateTime<?> other) {
1626        if (other instanceof LocalDateTime) {
1627            return compareTo0((LocalDateTime) other);
1628        }
1629        return super.compareTo(other);
1630    }
1631
1632    private int compareTo0(LocalDateTime other) {
1633        int cmp = date.compareTo0(other.getDate());
1634        if (cmp == 0) {
1635            cmp = time.compareTo(other.getTime());
1636        }
1637        return cmp;
1638    }
1639
1640    /**
1641     * Checks if this date-time is after the specified date-time.
1642     * <p>
1643     * This checks to see if this date-time represents a point on the
1644     * local time-line after the other date-time.
1645     * <pre>
1646     *   LocalDate a = LocalDateTime.of(2012, 6, 30, 12, 00);
1647     *   LocalDate b = LocalDateTime.of(2012, 7, 1, 12, 00);
1648     *   a.isAfter(b) == false
1649     *   a.isAfter(a) == false
1650     *   b.isAfter(a) == true
1651     * </pre>
1652     * <p>
1653     * This method only considers the position of the two date-times on the local time-line.
1654     * It does not take into account the chronology, or calendar system.
1655     * This is different from the comparison in {@link #compareTo(ChronoLocalDateTime)},
1656     * but is the same approach as {@link #DATE_TIME_COMPARATOR}.
1657     *
1658     * @param other  the other date-time to compare to, not null
1659     * @return true if this date-time is after the specified date-time
1660     */
1661    @Override  // override for Javadoc and performance
1662    public boolean isAfter(ChronoLocalDateTime<?> other) {
1663        if (other instanceof LocalDateTime) {
1664            return compareTo0((LocalDateTime) other) > 0;
1665        }
1666        return super.isAfter(other);
1667    }
1668
1669    /**
1670     * Checks if this date-time is before the specified date-time.
1671     * <p>
1672     * This checks to see if this date-time represents a point on the
1673     * local time-line before the other date-time.
1674     * <pre>
1675     *   LocalDate a = LocalDateTime.of(2012, 6, 30, 12, 00);
1676     *   LocalDate b = LocalDateTime.of(2012, 7, 1, 12, 00);
1677     *   a.isBefore(b) == true
1678     *   a.isBefore(a) == false
1679     *   b.isBefore(a) == false
1680     * </pre>
1681     * <p>
1682     * This method only considers the position of the two date-times on the local time-line.
1683     * It does not take into account the chronology, or calendar system.
1684     * This is different from the comparison in {@link #compareTo(ChronoLocalDateTime)},
1685     * but is the same approach as {@link #DATE_TIME_COMPARATOR}.
1686     *
1687     * @param other  the other date-time to compare to, not null
1688     * @return true if this date-time is before the specified date-time
1689     */
1690    @Override  // override for Javadoc and performance
1691    public boolean isBefore(ChronoLocalDateTime<?> other) {
1692        if (other instanceof LocalDateTime) {
1693            return compareTo0((LocalDateTime) other) < 0;
1694        }
1695        return super.isBefore(other);
1696    }
1697
1698    /**
1699     * Checks if this date-time is equal to the specified date-time.
1700     * <p>
1701     * This checks to see if this date-time represents the same point on the
1702     * local time-line as the other date-time.
1703     * <pre>
1704     *   LocalDate a = LocalDateTime.of(2012, 6, 30, 12, 00);
1705     *   LocalDate b = LocalDateTime.of(2012, 7, 1, 12, 00);
1706     *   a.isEqual(b) == false
1707     *   a.isEqual(a) == true
1708     *   b.isEqual(a) == false
1709     * </pre>
1710     * <p>
1711     * This method only considers the position of the two date-times on the local time-line.
1712     * It does not take into account the chronology, or calendar system.
1713     * This is different from the comparison in {@link #compareTo(ChronoLocalDateTime)},
1714     * but is the same approach as {@link #DATE_TIME_COMPARATOR}.
1715     *
1716     * @param other  the other date-time to compare to, not null
1717     * @return true if this date-time is equal to the specified date-time
1718     */
1719    @Override  // override for Javadoc and performance
1720    public boolean isEqual(ChronoLocalDateTime<?> other) {
1721        if (other instanceof LocalDateTime) {
1722            return compareTo0((LocalDateTime) other) == 0;
1723        }
1724        return super.isEqual(other);
1725    }
1726
1727    //-----------------------------------------------------------------------
1728    /**
1729     * Checks if this date-time is equal to another date-time.
1730     * <p>
1731     * Compares this {@code LocalDateTime} with another ensuring that the date-time is the same.
1732     * Only objects of type {@code LocalDateTime} are compared, other types return false.
1733     *
1734     * @param obj  the object to check, null returns false
1735     * @return true if this is equal to the other date-time
1736     */
1737    @Override
1738    public boolean equals(Object obj) {
1739        if (this == obj) {
1740            return true;
1741        }
1742        if (obj instanceof LocalDateTime) {
1743            LocalDateTime other = (LocalDateTime) obj;
1744            return date.equals(other.date) && time.equals(other.time);
1745        }
1746        return false;
1747    }
1748
1749    /**
1750     * A hash code for this date-time.
1751     *
1752     * @return a suitable hash code
1753     */
1754    @Override
1755    public int hashCode() {
1756        return date.hashCode() ^ time.hashCode();
1757    }
1758
1759    //-----------------------------------------------------------------------
1760    /**
1761     * Outputs this date-time as a {@code String}, such as {@code 2007-12-03T10:15:30}.
1762     * <p>
1763     * The output will be one of the following ISO-8601 formats:
1764     * <p><ul>
1765     * <li>{@code yyyy-MM-dd'T'HH:mm}</li>
1766     * <li>{@code yyyy-MM-dd'T'HH:mm:ss}</li>
1767     * <li>{@code yyyy-MM-dd'T'HH:mm:ss.SSS}</li>
1768     * <li>{@code yyyy-MM-dd'T'HH:mm:ss.SSSSSS}</li>
1769     * <li>{@code yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSS}</li>
1770     * </ul><p>
1771     * The format used will be the shortest that outputs the full value of
1772     * the time where the omitted parts are implied to be zero.
1773     *
1774     * @return a string representation of this date-time, not null
1775     */
1776    @Override
1777    public String toString() {
1778        return date.toString() + 'T' + time.toString();
1779    }
1780
1781    /**
1782     * Outputs this date-time as a {@code String} using the formatter.
1783     * <p>
1784     * This date-time will be passed to the formatter
1785     * {@link DateTimeFormatter#print(TemporalAccessor) print method}.
1786     *
1787     * @param formatter  the formatter to use, not null
1788     * @return the formatted date-time string, not null
1789     * @throws DateTimeException if an error occurs during printing
1790     */
1791    @Override  // override for Javadoc
1792    public String toString(DateTimeFormatter formatter) {
1793        return super.toString(formatter);
1794    }
1795
1796    //-----------------------------------------------------------------------
1797    private Object writeReplace() {
1798        return new Ser(Ser.LOCAL_DATE_TIME_TYPE, this);
1799    }
1800
1801    /**
1802     * Defend against malicious streams.
1803     * @return never
1804     * @throws InvalidObjectException always
1805     */
1806    private Object readResolve() throws ObjectStreamException {
1807        throw new InvalidObjectException("Deserialization via serialization delegate");
1808    }
1809
1810    void writeExternal(DataOutput out) throws IOException {
1811        date.writeExternal(out);
1812        time.writeExternal(out);
1813    }
1814
1815    static LocalDateTime readExternal(DataInput in) throws IOException {
1816        LocalDate date = LocalDate.readExternal(in);
1817        LocalTime time = LocalTime.readExternal(in);
1818        return LocalDateTime.of(date, time);
1819    }
1820
1821}