001    /*
002     *  Copyright 2001-2011 Stephen Colebourne
003     *
004     *  Licensed under the Apache License, Version 2.0 (the "License");
005     *  you may not use this file except in compliance with the License.
006     *  You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     *  Unless required by applicable law or agreed to in writing, software
011     *  distributed under the License is distributed on an "AS IS" BASIS,
012     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     *  See the License for the specific language governing permissions and
014     *  limitations under the License.
015     */
016    package org.joda.time;
017    
018    import java.io.IOException;
019    import java.io.ObjectInputStream;
020    import java.io.ObjectOutputStream;
021    import java.io.Serializable;
022    import java.util.Calendar;
023    import java.util.Date;
024    import java.util.Locale;
025    import java.util.TimeZone;
026    
027    import org.joda.convert.FromString;
028    import org.joda.convert.ToString;
029    import org.joda.time.base.BaseLocal;
030    import org.joda.time.chrono.ISOChronology;
031    import org.joda.time.convert.ConverterManager;
032    import org.joda.time.convert.PartialConverter;
033    import org.joda.time.field.AbstractReadableInstantFieldProperty;
034    import org.joda.time.format.DateTimeFormat;
035    import org.joda.time.format.DateTimeFormatter;
036    import org.joda.time.format.ISODateTimeFormat;
037    
038    /**
039     * LocalDateTime is an unmodifiable datetime class representing a
040     * datetime without a time zone.
041     * <p>
042     * LocalDateTime implements the {@link ReadablePartial} interface.
043     * To do this, certain methods focus on key fields Year, MonthOfYear,
044     * DayOfYear and MillisOfDay.
045     * However, <b>all</b> fields may in fact be queried.
046     * <p>
047     * Internally, LocalDateTime uses a single millisecond-based value to
048     * represent the local datetime. This value is only used internally and
049     * is not exposed to applications.
050     * <p>
051     * Calculations on LocalDateTime are performed using a {@link Chronology}.
052     * This chronology will be set internally to be in the UTC time zone
053     * for all calculations.
054     *
055     * <p>Each individual field can be queried in two ways:
056     * <ul>
057     * <li><code>getHourOfDay()</code>
058     * <li><code>hourOfDay().get()</code>
059     * </ul>
060     * The second technique also provides access to other useful methods on the
061     * field:
062     * <ul>
063     * <li>numeric value
064     * <li>text value
065     * <li>short text value
066     * <li>maximum/minimum values
067     * <li>add/subtract
068     * <li>set
069     * <li>rounding
070     * </ul>
071     *
072     * <p>
073     * LocalDateTime is thread-safe and immutable, provided that the Chronology is as well.
074     * All standard Chronology classes supplied are thread-safe and immutable.
075     *
076     * @author Stephen Colebourne
077     * @since 1.3
078     */
079    public final class LocalDateTime
080            extends BaseLocal
081            implements ReadablePartial, Serializable {
082    
083        /** Serialization lock */
084        private static final long serialVersionUID = -268716875315837168L;
085    
086        /** The index of the year field in the field array */
087        private static final int YEAR = 0;
088        /** The index of the monthOfYear field in the field array */
089        private static final int MONTH_OF_YEAR = 1;
090        /** The index of the dayOfMonth field in the field array */
091        private static final int DAY_OF_MONTH = 2;
092        /** The index of the millis field in the field array */
093        private static final int MILLIS_OF_DAY = 3;
094    
095        /** The local millis from 1970-01-01T00:00:00 */
096        private final long iLocalMillis;
097        /** The chronology to use in UTC */
098        private final Chronology iChronology;
099    
100        //-----------------------------------------------------------------------
101        /**
102         * Obtains a {@code LocalDateTime} set to the current system millisecond time
103         * using <code>ISOChronology</code> in the default time zone.
104         * The resulting object does not use the zone.
105         * 
106         * @return the current date, not null
107         * @since 2.0
108         */
109        public static LocalDateTime now() {
110            return new LocalDateTime();
111        }
112    
113        /**
114         * Obtains a {@code LocalDateTime} set to the current system millisecond time
115         * using <code>ISOChronology</code> in the specified time zone.
116         * The resulting object does not use the zone.
117         *
118         * @param zone  the time zone, not null
119         * @return the current date, not null
120         * @since 2.0
121         */
122        public static LocalDateTime now(DateTimeZone zone) {
123            if (zone == null) {
124                throw new NullPointerException("Zone must not be null");
125            }
126            return new LocalDateTime(zone);
127        }
128    
129        /**
130         * Obtains a {@code LocalDateTime} set to the current system millisecond time
131         * using the specified chronology.
132         * The resulting object does not use the zone.
133         *
134         * @param chronology  the chronology, not null
135         * @return the current date, not null
136         * @since 2.0
137         */
138        public static LocalDateTime now(Chronology chronology) {
139            if (chronology == null) {
140                throw new NullPointerException("Chronology must not be null");
141            }
142            return new LocalDateTime(chronology);
143        }
144    
145        //-----------------------------------------------------------------------
146        /**
147         * Parses a {@code LocalDateTime} from the specified string.
148         * <p>
149         * This uses {@link ISODateTimeFormat#localDateOptionalTimeParser()}.
150         * 
151         * @param str  the string to parse, not null
152         * @since 2.0
153         */
154        @FromString
155        public static LocalDateTime parse(String str) {
156            return parse(str, ISODateTimeFormat.localDateOptionalTimeParser());
157        }
158    
159        /**
160         * Parses a {@code LocalDateTime} from the specified string using a formatter.
161         * 
162         * @param str  the string to parse, not null
163         * @param formatter  the formatter to use, not null
164         * @since 2.0
165         */
166        public static LocalDateTime parse(String str, DateTimeFormatter formatter) {
167            return formatter.parseLocalDateTime(str);
168        }
169    
170        //-----------------------------------------------------------------------
171        /**
172         * Constructs a LocalDateTime from a <code>java.util.Calendar</code>
173         * using exactly the same field values.
174         * <p>
175         * Each field is queried from the Calendar and assigned to the LocalDateTime.
176         * This is useful if you have been using the Calendar as a local date,
177         * ignoring the zone.
178         * <p>
179         * One advantage of this method is that this method is unaffected if the
180         * version of the time zone data differs between the JDK and Joda-Time.
181         * That is because the local field values are transferred, calculated using
182         * the JDK time zone data and without using the Joda-Time time zone data.
183         * <p>
184         * This factory method ignores the type of the calendar and always
185         * creates a LocalDateTime with ISO chronology. It is expected that you
186         * will only pass in instances of <code>GregorianCalendar</code> however
187         * this is not validated.
188         *
189         * @param calendar  the Calendar to extract fields from
190         * @return the created LocalDateTime
191         * @throws IllegalArgumentException if the calendar is null
192         * @throws IllegalArgumentException if the date is invalid for the ISO chronology
193         */
194        public static LocalDateTime fromCalendarFields(Calendar calendar) {
195            if (calendar == null) {
196                throw new IllegalArgumentException("The calendar must not be null");
197            }
198            return new LocalDateTime(
199                calendar.get(Calendar.YEAR),
200                calendar.get(Calendar.MONTH) + 1,
201                calendar.get(Calendar.DAY_OF_MONTH),
202                calendar.get(Calendar.HOUR_OF_DAY),
203                calendar.get(Calendar.MINUTE),
204                calendar.get(Calendar.SECOND),
205                calendar.get(Calendar.MILLISECOND)
206            );
207        }
208    
209        /**
210         * Constructs a LocalDateTime from a <code>java.util.Date</code>
211         * using exactly the same field values.
212         * <p>
213         * Each field is queried from the Date and assigned to the LocalDateTime.
214         * This is useful if you have been using the Date as a local date,
215         * ignoring the zone.
216         * <p>
217         * One advantage of this method is that this method is unaffected if the
218         * version of the time zone data differs between the JDK and Joda-Time.
219         * That is because the local field values are transferred, calculated using
220         * the JDK time zone data and without using the Joda-Time time zone data.
221         * <p>
222         * This factory method always creates a LocalDateTime with ISO chronology.
223         *
224         * @param date  the Date to extract fields from
225         * @return the created LocalDateTime
226         * @throws IllegalArgumentException if the calendar is null
227         * @throws IllegalArgumentException if the date is invalid for the ISO chronology
228         */
229        @SuppressWarnings("deprecation")
230        public static LocalDateTime fromDateFields(Date date) {
231            if (date == null) {
232                throw new IllegalArgumentException("The date must not be null");
233            }
234            return new LocalDateTime(
235                date.getYear() + 1900,
236                date.getMonth() + 1,
237                date.getDate(),
238                date.getHours(),
239                date.getMinutes(),
240                date.getSeconds(),
241                (int) (date.getTime() % 1000)
242            );
243        }
244    
245        //-----------------------------------------------------------------------
246        /**
247         * Constructs an instance set to the current local time evaluated using
248         * ISO chronology in the default zone.
249         * <p>
250         * Once the constructor is completed, the zone is no longer used.
251         * 
252         * @see #now()
253         */
254        public LocalDateTime() {
255            this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance());
256        }
257    
258        /**
259         * Constructs an instance set to the current local time evaluated using
260         * ISO chronology in the specified zone.
261         * <p>
262         * If the specified time zone is null, the default zone is used.
263         * Once the constructor is completed, the zone is no longer used.
264         *
265         * @param zone  the time zone, null means default zone
266         * @see #now(DateTimeZone)
267         */
268        public LocalDateTime(DateTimeZone zone) {
269            this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance(zone));
270        }
271    
272        /**
273         * Constructs an instance set to the current local time evaluated using
274         * specified chronology.
275         * <p>
276         * If the chronology is null, ISO chronology in the default time zone is used.
277         * Once the constructor is completed, the zone is no longer used.
278         *
279         * @param chronology  the chronology, null means ISOChronology in default zone
280         * @see #now(Chronology)
281         */
282        public LocalDateTime(Chronology chronology) {
283            this(DateTimeUtils.currentTimeMillis(), chronology);
284        }
285    
286        //-----------------------------------------------------------------------
287        /**
288         * Constructs an instance set to the local time defined by the specified
289         * instant evaluated using ISO chronology in the default zone.
290         * <p>
291         * Once the constructor is completed, the zone is no longer used.
292         *
293         * @param instant  the milliseconds from 1970-01-01T00:00:00Z
294         */
295        public LocalDateTime(long instant) {
296            this(instant, ISOChronology.getInstance());
297        }
298    
299        /**
300         * Constructs an instance set to the local time defined by the specified
301         * instant evaluated using ISO chronology in the specified zone.
302         * <p>
303         * If the specified time zone is null, the default zone is used.
304         * Once the constructor is completed, the zone is no longer used.
305         *
306         * @param instant  the milliseconds from 1970-01-01T00:00:00Z
307         * @param zone  the time zone, null means default zone
308         */
309        public LocalDateTime(long instant, DateTimeZone zone) {
310            this(instant, ISOChronology.getInstance(zone));
311        }
312    
313        /**
314         * Constructs an instance set to the local time defined by the specified
315         * instant evaluated using the specified chronology.
316         * <p>
317         * If the chronology is null, ISO chronology in the default zone is used.
318         * Once the constructor is completed, the zone is no longer used.
319         *
320         * @param instant  the milliseconds from 1970-01-01T00:00:00Z
321         * @param chronology  the chronology, null means ISOChronology in default zone
322         */
323        public LocalDateTime(long instant, Chronology chronology) {
324            chronology = DateTimeUtils.getChronology(chronology);
325            
326            long localMillis = chronology.getZone().getMillisKeepLocal(DateTimeZone.UTC, instant);
327            iLocalMillis = localMillis;
328            iChronology = chronology.withUTC();
329        }
330    
331        //-----------------------------------------------------------------------
332        /**
333         * Constructs an instance from an Object that represents a datetime.
334         * <p>
335         * If the object contains no chronology, <code>ISOChronology</code> is used.
336         * If the object contains no time zone, the default zone is used.
337         * Once the constructor is completed, the zone is no longer used.
338         * <p>
339         * The recognised object types are defined in
340         * {@link org.joda.time.convert.ConverterManager ConverterManager} and
341         * include ReadablePartial, ReadableInstant, String, Calendar and Date.
342         * The String formats are described by {@link ISODateTimeFormat#localDateOptionalTimeParser()}.
343         * The default String converter ignores the zone and only parses the field values.
344         *
345         * @param instant  the datetime object
346         * @throws IllegalArgumentException if the instant is invalid
347         */
348        public LocalDateTime(Object instant) {
349            this(instant, (Chronology) null);
350        }
351    
352        /**
353         * Constructs an instance from an Object that represents a datetime,
354         * forcing the time zone to that specified.
355         * <p>
356         * If the object contains no chronology, <code>ISOChronology</code> is used.
357         * If the specified time zone is null, the default zone is used.
358         * Once the constructor is completed, the zone is no longer used.
359         * <p>
360         * The recognised object types are defined in
361         * {@link org.joda.time.convert.ConverterManager ConverterManager} and
362         * include ReadablePartial, ReadableInstant, String, Calendar and Date.
363         * The String formats are described by {@link ISODateTimeFormat#localDateOptionalTimeParser()}.
364         * The default String converter ignores the zone and only parses the field values.
365         *
366         * @param instant  the datetime object
367         * @param zone  the time zone
368         * @throws IllegalArgumentException if the instant is invalid
369         */
370        public LocalDateTime(Object instant, DateTimeZone zone) {
371            PartialConverter converter = ConverterManager.getInstance().getPartialConverter(instant);
372            Chronology chronology = converter.getChronology(instant, zone);
373            chronology = DateTimeUtils.getChronology(chronology);
374            iChronology = chronology.withUTC();
375            int[] values = converter.getPartialValues(this, instant, chronology, ISODateTimeFormat.localDateOptionalTimeParser());
376            iLocalMillis = iChronology.getDateTimeMillis(values[0], values[1], values[2], values[3]);
377        }
378    
379        /**
380         * Constructs an instance from an Object that represents a datetime,
381         * using the specified chronology.
382         * <p>
383         * If the chronology is null, ISO in the default time zone is used.
384         * Once the constructor is completed, the zone is no longer used.
385         * <p>
386         * The recognised object types are defined in
387         * {@link org.joda.time.convert.ConverterManager ConverterManager} and
388         * include ReadablePartial, ReadableInstant, String, Calendar and Date.
389         * The String formats are described by {@link ISODateTimeFormat#localDateOptionalTimeParser()}.
390         * The default String converter ignores the zone and only parses the field values.
391         *
392         * @param instant  the datetime object
393         * @param chronology  the chronology
394         * @throws IllegalArgumentException if the instant is invalid
395         */
396        public LocalDateTime(Object instant, Chronology chronology) {
397            PartialConverter converter = ConverterManager.getInstance().getPartialConverter(instant);
398            chronology = converter.getChronology(instant, chronology);
399            chronology = DateTimeUtils.getChronology(chronology);
400            iChronology = chronology.withUTC();
401            int[] values = converter.getPartialValues(this, instant, chronology, ISODateTimeFormat.localDateOptionalTimeParser());
402            iLocalMillis = iChronology.getDateTimeMillis(values[0], values[1], values[2], values[3]);
403        }
404    
405        //-----------------------------------------------------------------------
406        /**
407         * Constructs an instance set to the specified date and time
408         * using <code>ISOChronology</code>.
409         *
410         * @param year  the year
411         * @param monthOfYear  the month of the year
412         * @param dayOfMonth  the day of the month
413         * @param hourOfDay  the hour of the day
414         * @param minuteOfHour  the minute of the hour
415         */
416        public LocalDateTime(
417                int year,
418                int monthOfYear,
419                int dayOfMonth,
420                int hourOfDay,
421                int minuteOfHour) {
422            this(year, monthOfYear, dayOfMonth, hourOfDay,
423                minuteOfHour, 0, 0, ISOChronology.getInstanceUTC());
424        }
425    
426        /**
427         * Constructs an instance set to the specified date and time
428         * using <code>ISOChronology</code>.
429         *
430         * @param year  the year
431         * @param monthOfYear  the month of the year
432         * @param dayOfMonth  the day of the month
433         * @param hourOfDay  the hour of the day
434         * @param minuteOfHour  the minute of the hour
435         * @param secondOfMinute  the second of the minute
436         */
437        public LocalDateTime(
438                int year,
439                int monthOfYear,
440                int dayOfMonth,
441                int hourOfDay,
442                int minuteOfHour,
443                int secondOfMinute) {
444            this(year, monthOfYear, dayOfMonth, hourOfDay,
445                minuteOfHour, secondOfMinute, 0, ISOChronology.getInstanceUTC());
446        }
447    
448        /**
449         * Constructs an instance set to the specified date and time
450         * using <code>ISOChronology</code>.
451         *
452         * @param year  the year
453         * @param monthOfYear  the month of the year
454         * @param dayOfMonth  the day of the month
455         * @param hourOfDay  the hour of the day
456         * @param minuteOfHour  the minute of the hour
457         * @param secondOfMinute  the second of the minute
458         * @param millisOfSecond  the millisecond of the second
459         */
460        public LocalDateTime(
461                int year,
462                int monthOfYear,
463                int dayOfMonth,
464                int hourOfDay,
465                int minuteOfHour,
466                int secondOfMinute,
467                int millisOfSecond) {
468            this(year, monthOfYear, dayOfMonth, hourOfDay,
469                minuteOfHour, secondOfMinute, millisOfSecond, ISOChronology.getInstanceUTC());
470        }
471    
472        /**
473         * Constructs an instance set to the specified date and time
474         * using the specified chronology, whose zone is ignored.
475         * <p>
476         * If the chronology is null, <code>ISOChronology</code> is used.
477         *
478         * @param year  the year
479         * @param monthOfYear  the month of the year
480         * @param dayOfMonth  the day of the month
481         * @param hourOfDay  the hour of the day
482         * @param minuteOfHour  the minute of the hour
483         * @param secondOfMinute  the second of the minute
484         * @param millisOfSecond  the millisecond of the second
485         * @param chronology  the chronology, null means ISOChronology in default zone
486         */
487        public LocalDateTime(
488                int year,
489                int monthOfYear,
490                int dayOfMonth,
491                int hourOfDay,
492                int minuteOfHour,
493                int secondOfMinute,
494                int millisOfSecond,
495                Chronology chronology) {
496            super();
497            chronology = DateTimeUtils.getChronology(chronology).withUTC();
498            long instant = chronology.getDateTimeMillis(year, monthOfYear, dayOfMonth,
499                hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond);
500            iChronology = chronology;
501            iLocalMillis = instant;
502        }
503    
504        /**
505         * Handle broken serialization from other tools.
506         * @return the resolved object, not null
507         */
508        private Object readResolve() {
509            if (DateTimeZone.UTC.equals(iChronology.getZone()) == false) {
510                return new LocalDateTime(iLocalMillis, iChronology.withUTC());
511            }
512            return this;
513        }
514    
515        //-----------------------------------------------------------------------
516        /**
517         * Gets the number of fields in this partial, which is four.
518         * The supported fields are Year, MonthOfDay, DayOfMonth and MillisOfDay.
519         *
520         * @return the field count, four
521         */
522        public int size() {
523            return 4;
524        }
525    
526        /**
527         * Gets the field for a specific index in the chronology specified.
528         * <p>
529         * This method must not use any instance variables.
530         *
531         * @param index  the index to retrieve
532         * @param chrono  the chronology to use
533         * @return the field
534         */
535        protected DateTimeField getField(int index, Chronology chrono) {
536            switch (index) {
537                case YEAR:
538                    return chrono.year();
539                case MONTH_OF_YEAR:
540                    return chrono.monthOfYear();
541                case DAY_OF_MONTH:
542                    return chrono.dayOfMonth();
543                case MILLIS_OF_DAY:
544                    return chrono.millisOfDay();
545                default:
546                    throw new IndexOutOfBoundsException("Invalid index: " + index);
547            }
548        }
549    
550        /**
551         * Gets the value of the field at the specifed index.
552         * <p>
553         * This method is required to support the <code>ReadablePartial</code>
554         * interface. The supported fields are Year, MonthOfDay, DayOfMonth and MillisOfDay.
555         *
556         * @param index  the index, zero to two
557         * @return the value
558         * @throws IndexOutOfBoundsException if the index is invalid
559         */
560        public int getValue(int index) {
561            switch (index) {
562                case YEAR:
563                    return getChronology().year().get(getLocalMillis());
564                case MONTH_OF_YEAR:
565                    return getChronology().monthOfYear().get(getLocalMillis());
566                case DAY_OF_MONTH:
567                    return getChronology().dayOfMonth().get(getLocalMillis());
568                case MILLIS_OF_DAY:
569                    return getChronology().millisOfDay().get(getLocalMillis());
570                default:
571                    throw new IndexOutOfBoundsException("Invalid index: " + index);
572            }
573        }
574    
575        //-----------------------------------------------------------------------
576        /**
577         * Get the value of one of the fields of a datetime.
578         * <p>
579         * This method gets the value of the specified field.
580         * For example:
581         * <pre>
582         * DateTime dt = new DateTime();
583         * int year = dt.get(DateTimeFieldType.year());
584         * </pre>
585         *
586         * @param type  a field type, usually obtained from DateTimeFieldType, not null
587         * @return the value of that field
588         * @throws IllegalArgumentException if the field type is null
589         */
590        public int get(DateTimeFieldType type) {
591            if (type == null) {
592                throw new IllegalArgumentException("The DateTimeFieldType must not be null");
593            }
594            return type.getField(getChronology()).get(getLocalMillis());
595        }
596    
597        /**
598         * Checks if the field type specified is supported by this
599         * local datetime and chronology.
600         * This can be used to avoid exceptions in {@link #get(DateTimeFieldType)}.
601         *
602         * @param type  a field type, usually obtained from DateTimeFieldType
603         * @return true if the field type is supported
604         */
605        public boolean isSupported(DateTimeFieldType type) {
606            if (type == null) {
607                return false;
608            }
609            return type.getField(getChronology()).isSupported();
610        }
611    
612        /**
613         * Checks if the duration type specified is supported by this
614         * local datetime and chronology.
615         *
616         * @param type  a duration type, usually obtained from DurationFieldType
617         * @return true if the field type is supported
618         */
619        public boolean isSupported(DurationFieldType type) {
620            if (type == null) {
621                return false;
622            }
623            return type.getField(getChronology()).isSupported();
624        }
625    
626        //-----------------------------------------------------------------------
627        /**
628         * Gets the milliseconds of the datetime instant from the Java epoch
629         * of 1970-01-01T00:00:00 (not fixed to any specific time zone).
630         *
631         * @return the number of milliseconds since 1970-01-01T00:00:00
632         * @since 1.5 (previously private)
633         */
634        protected long getLocalMillis() {
635            return iLocalMillis;
636        }
637    
638        /**
639         * Gets the chronology of the datetime.
640         *
641         * @return the Chronology that the datetime is using
642         */
643        public Chronology getChronology() {
644            return iChronology;
645        }
646    
647        //-----------------------------------------------------------------------
648        /**
649         * Compares this ReadablePartial with another returning true if the chronology,
650         * field types and values are equal.
651         *
652         * @param partial  an object to check against
653         * @return true if fields and values are equal
654         */
655        public boolean equals(Object partial) {
656            // override to perform faster
657            if (this == partial) {
658                return true;
659            }
660            if (partial instanceof LocalDateTime) {
661                LocalDateTime other = (LocalDateTime) partial;
662                if (iChronology.equals(other.iChronology)) {
663                    return iLocalMillis == other.iLocalMillis;
664                }
665            }
666            return super.equals(partial);
667        }
668    
669        /**
670         * Compares this partial with another returning an integer
671         * indicating the order.
672         * <p>
673         * The fields are compared in order, from largest to smallest.
674         * The first field that is non-equal is used to determine the result.
675         * <p>
676         * The specified object must be a partial instance whose field types
677         * match those of this partial.
678         *
679         * @param partial  an object to check against
680         * @return negative if this is less, zero if equal, positive if greater
681         * @throws ClassCastException if the partial is the wrong class
682         *  or if it has field types that don't match
683         * @throws NullPointerException if the partial is null
684         */
685        public int compareTo(ReadablePartial partial) {
686            // override to perform faster
687            if (this == partial) {
688                return 0;
689            }
690            if (partial instanceof LocalDateTime) {
691                LocalDateTime other = (LocalDateTime) partial;
692                if (iChronology.equals(other.iChronology)) {
693                    return (iLocalMillis < other.iLocalMillis ? -1 :
694                                (iLocalMillis == other.iLocalMillis ? 0 : 1));
695    
696                }
697            }
698            return super.compareTo(partial);
699        }
700    
701        //-----------------------------------------------------------------------
702        /**
703         * Converts this object to a DateTime using the default zone.
704         * <p>
705         * This method will throw an exception if the datetime that would be
706         * created does not exist when the time zone is taken into account.
707         * 
708         * @return <code>this</code>
709         */
710        public DateTime toDateTime() {
711            return toDateTime((DateTimeZone) null);
712        }
713    
714        /**
715         * Converts this object to a DateTime using the specified zone.
716         * <p>
717         * This method will throw an exception if the datetime that would be
718         * created does not exist when the time zone is taken into account.
719         * 
720         * @param zone time zone to apply, or default if null
721         * @return a DateTime using the same millis
722         */
723        public DateTime toDateTime(DateTimeZone zone) {
724            zone = DateTimeUtils.getZone(zone);
725            Chronology chrono = iChronology.withZone(zone);
726            return new DateTime(
727                    getYear(), getMonthOfYear(), getDayOfMonth(),
728                    getHourOfDay(), getMinuteOfHour(),
729                    getSecondOfMinute(), getMillisOfSecond(), chrono);
730        }
731    
732        //-----------------------------------------------------------------------
733        /**
734         * Converts this object to a LocalDate with the same date and chronology.
735         *
736         * @return a LocalDate with the same date and chronology
737         */
738        public LocalDate toLocalDate() {
739            return new LocalDate(getLocalMillis(), getChronology());
740        }
741    
742        /**
743         * Converts this object to a LocalTime with the same time and chronology.
744         *
745         * @return a LocalTime with the same time and chronology
746         */
747        public LocalTime toLocalTime() {
748            return new LocalTime(getLocalMillis(), getChronology());
749        }
750    
751        //-----------------------------------------------------------------------
752        /**
753         * Get the date time as a <code>java.util.Date</code>.
754         * <p>
755         * The <code>Date</code> object created has exactly the same fields as this
756         * date-time, except when the time would be invalid due to a daylight savings
757         * gap. In that case, the time will be set to the earliest valid time after the gap.
758         * <p>
759         * In the case of a daylight savings overlap, the earlier instant is selected.
760         * <p>
761         * Converting to a JDK Date is full of complications as the JDK Date constructor
762         * doesn't behave as you might expect around DST transitions. This method works
763         * by taking a first guess and then adjusting. This also handles the situation
764         * where the JDK time zone data differs from the Joda-Time time zone data.
765         *
766         * @return a Date initialised with this date-time, never null
767         * @since 2.0
768         */
769        @SuppressWarnings("deprecation")
770        public Date toDate() {
771            int dom = getDayOfMonth();
772            Date date = new Date(getYear() - 1900, getMonthOfYear() - 1, dom,
773                            getHourOfDay(), getMinuteOfHour(), getSecondOfMinute());
774            date.setTime(date.getTime() + getMillisOfSecond());
775            LocalDateTime check = LocalDateTime.fromDateFields(date);
776            if (check.isBefore(this)) {
777                // DST gap
778                // move forward in units of one minute until equal/after
779                while (check.isBefore(this)) {
780                    date.setTime(date.getTime() + 60000);
781                    check = LocalDateTime.fromDateFields(date);
782                }
783                // move back in units of one second until date wrong
784                while (check.isBefore(this) == false) {
785                    date.setTime(date.getTime() - 1000);
786                    check = LocalDateTime.fromDateFields(date);
787                }
788                date.setTime(date.getTime() + 1000);
789            } else if (check.equals(this)) {
790                // check for DST overlap
791                Date earlier = new Date(date.getTime() - TimeZone.getDefault().getDSTSavings());
792                check = LocalDateTime.fromDateFields(earlier);
793                if (check.equals(this)) {
794                    date = earlier;
795                }
796            }
797            return date;
798        }
799    
800        //-----------------------------------------------------------------------
801        /**
802         * Returns a copy of this datetime with different local millis.
803         * <p>
804         * The returned object will be a new instance of the same type.
805         * Only the millis will change, the chronology is kept.
806         * The returned object will be either be a new instance or <code>this</code>.
807         *
808         * @param newMillis  the new millis, from 1970-01-01T00:00:00
809         * @return a copy of this datetime with different millis
810         */
811        LocalDateTime withLocalMillis(long newMillis) {
812            return (newMillis == getLocalMillis() ? this : new LocalDateTime(newMillis, getChronology()));
813        }
814    
815        //-----------------------------------------------------------------------
816        /**
817         * Returns a copy of this datetime with the specified date,
818         * retaining the time fields.
819         * <p>
820         * If the date is already the date passed in, then <code>this</code> is returned.
821         * <p>
822         * To set a single field use the properties, for example:
823         * <pre>
824         * DateTime set = dt.monthOfYear().setCopy(6);
825         * </pre>
826         *
827         * @param year  the new year value
828         * @param monthOfYear  the new monthOfYear value
829         * @param dayOfMonth  the new dayOfMonth value
830         * @return a copy of this datetime with a different date
831         * @throws IllegalArgumentException if any value if invalid
832         */
833        public LocalDateTime withDate(int year, int monthOfYear, int dayOfMonth) {
834            Chronology chrono = getChronology();
835            long instant = getLocalMillis();
836            instant = chrono.year().set(instant, year);
837            instant = chrono.monthOfYear().set(instant, monthOfYear);
838            instant = chrono.dayOfMonth().set(instant, dayOfMonth);
839            return withLocalMillis(instant);
840        }
841    
842        /**
843         * Returns a copy of this datetime with the specified time,
844         * retaining the date fields.
845         * <p>
846         * If the time is already the time passed in, then <code>this</code> is returned.
847         * <p>
848         * To set a single field use the properties, for example:
849         * <pre>
850         * LocalDateTime set = dt.hourOfDay().setCopy(6);
851         * </pre>
852         *
853         * @param hourOfDay  the hour of the day
854         * @param minuteOfHour  the minute of the hour
855         * @param secondOfMinute  the second of the minute
856         * @param millisOfSecond  the millisecond of the second
857         * @return a copy of this datetime with a different time
858         * @throws IllegalArgumentException if any value if invalid
859         */
860        public LocalDateTime withTime(int hourOfDay, int minuteOfHour, int secondOfMinute, int millisOfSecond) {
861            Chronology chrono = getChronology();
862            long instant = getLocalMillis();
863            instant = chrono.hourOfDay().set(instant, hourOfDay);
864            instant = chrono.minuteOfHour().set(instant, minuteOfHour);
865            instant = chrono.secondOfMinute().set(instant, secondOfMinute);
866            instant = chrono.millisOfSecond().set(instant, millisOfSecond);
867            return withLocalMillis(instant);
868        }
869    
870        //-----------------------------------------------------------------------
871        /**
872         * Returns a copy of this datetime with the partial set of fields
873         * replacing those from this instance.
874         * <p>
875         * For example, if the partial is a <code>TimeOfDay</code> then the time fields
876         * would be changed in the returned instance.
877         * If the partial is null, then <code>this</code> is returned.
878         *
879         * @param partial  the partial set of fields to apply to this datetime, null ignored
880         * @return a copy of this datetime with a different set of fields
881         * @throws IllegalArgumentException if any value is invalid
882         */
883        public LocalDateTime withFields(ReadablePartial partial) {
884            if (partial == null) {
885                return this;
886            }
887            return withLocalMillis(getChronology().set(partial, getLocalMillis()));
888        }
889    
890        /**
891         * Returns a copy of this datetime with the specified field set to a new value.
892         * <p>
893         * For example, if the field type is <code>hourOfDay</code> then the hour of day
894         * field would be changed in the returned instance.
895         * If the field type is null, then <code>this</code> is returned.
896         * <p>
897         * These three lines are equivalent:
898         * <pre>
899         * LocalDateTime updated = dt.withField(DateTimeFieldType.dayOfMonth(), 6);
900         * LocalDateTime updated = dt.dayOfMonth().setCopy(6);
901         * LocalDateTime updated = dt.property(DateTimeFieldType.dayOfMonth()).setCopy(6);
902         * </pre>
903         *
904         * @param fieldType  the field type to set, not null
905         * @param value  the value to set
906         * @return a copy of this datetime with the field set
907         * @throws IllegalArgumentException if the value is null or invalid
908         */
909        public LocalDateTime withField(DateTimeFieldType fieldType, int value) {
910            if (fieldType == null) {
911                throw new IllegalArgumentException("Field must not be null");
912            }
913            long instant = fieldType.getField(getChronology()).set(getLocalMillis(), value);
914            return withLocalMillis(instant);
915        }
916    
917        /**
918         * Returns a copy of this datetime with the value of the specified
919         * field increased.
920         * <p>
921         * If the addition is zero or the field is null, then <code>this</code> is returned.
922         * <p>
923         * These three lines are equivalent:
924         * <pre>
925         * LocalDateTime added = dt.withFieldAdded(DurationFieldType.years(), 6);
926         * LocalDateTime added = dt.plusYears(6);
927         * LocalDateTime added = dt.plus(Period.years(6));
928         * </pre>
929         *
930         * @param fieldType  the field type to add to, not null
931         * @param amount  the amount to add
932         * @return a copy of this datetime with the field updated
933         * @throws IllegalArgumentException if the value is null or invalid
934         * @throws ArithmeticException if the result exceeds the internal capacity
935         */
936        public LocalDateTime withFieldAdded(DurationFieldType fieldType, int amount) {
937            if (fieldType == null) {
938                throw new IllegalArgumentException("Field must not be null");
939            }
940            if (amount == 0) {
941                return this;
942            }
943            long instant = fieldType.getField(getChronology()).add(getLocalMillis(), amount);
944            return withLocalMillis(instant);
945        }
946    
947        //-----------------------------------------------------------------------
948        /**
949         * Returns a copy of this datetime with the specified duration added.
950         * <p>
951         * If the addition is zero, then <code>this</code> is returned.
952         *
953         * @param durationToAdd  the duration to add to this one, null means zero
954         * @param scalar  the amount of times to add, such as -1 to subtract once
955         * @return a copy of this datetime with the duration added
956         * @throws ArithmeticException if the result exceeds the internal capacity
957         */
958        public LocalDateTime withDurationAdded(ReadableDuration durationToAdd, int scalar) {
959            if (durationToAdd == null || scalar == 0) {
960                return this;
961            }
962            long instant = getChronology().add(getLocalMillis(), durationToAdd.getMillis(), scalar);
963            return withLocalMillis(instant);
964        }
965    
966        /**
967         * Returns a copy of this datetime with the specified period added.
968         * <p>
969         * If the addition is zero, then <code>this</code> is returned.
970         * <p>
971         * This method is typically used to add multiple copies of complex
972         * period instances. Adding one field is best achieved using methods
973         * like {@link #withFieldAdded(DurationFieldType, int)}
974         * or {@link #plusYears(int)}.
975         *
976         * @param period  the period to add to this one, null means zero
977         * @param scalar  the amount of times to add, such as -1 to subtract once
978         * @return a copy of this datetime with the period added
979         * @throws ArithmeticException if the result exceeds the internal capacity
980         */
981        public LocalDateTime withPeriodAdded(ReadablePeriod period, int scalar) {
982            if (period == null || scalar == 0) {
983                return this;
984            }
985            long instant = getChronology().add(period, getLocalMillis(), scalar);
986            return withLocalMillis(instant);
987        }
988    
989        //-----------------------------------------------------------------------
990        /**
991         * Returns a copy of this datetime with the specified duration added.
992         * <p>
993         * If the amount is zero or null, then <code>this</code> is returned.
994         *
995         * @param duration  the duration to add to this one, null means zero
996         * @return a copy of this datetime with the duration added
997         * @throws ArithmeticException if the result exceeds the internal capacity
998         */
999        public LocalDateTime plus(ReadableDuration duration) {
1000            return withDurationAdded(duration, 1);
1001        }
1002    
1003        /**
1004         * Returns a copy of this datetime with the specified period added.
1005         * <p>
1006         * If the amount is zero or null, then <code>this</code> is returned.
1007         * <p>
1008         * This method is typically used to add complex period instances.
1009         * Adding one field is best achieved using methods
1010         * like {@link #plusYears(int)}.
1011         *
1012         * @param period  the period to add to this one, null means zero
1013         * @return a copy of this datetime with the period added
1014         * @throws ArithmeticException if the result exceeds the internal capacity
1015         */
1016        public LocalDateTime plus(ReadablePeriod period) {
1017            return withPeriodAdded(period, 1);
1018        }
1019    
1020        //-----------------------------------------------------------------------
1021        /**
1022         * Returns a copy of this datetime plus the specified number of years.
1023         * <p>
1024         * This LocalDateTime instance is immutable and unaffected by this method call.
1025         * <p>
1026         * The following three lines are identical in effect:
1027         * <pre>
1028         * LocalDateTime added = dt.plusYears(6);
1029         * LocalDateTime added = dt.plus(Period.years(6));
1030         * LocalDateTime added = dt.withFieldAdded(DurationFieldType.years(), 6);
1031         * </pre>
1032         *
1033         * @param years  the amount of years to add, may be negative
1034         * @return the new LocalDateTime plus the increased years
1035         */
1036        public LocalDateTime plusYears(int years) {
1037            if (years == 0) {
1038                return this;
1039            }
1040            long instant = getChronology().years().add(getLocalMillis(), years);
1041            return withLocalMillis(instant);
1042        }
1043    
1044        /**
1045         * Returns a copy of this datetime plus the specified number of months.
1046         * <p>
1047         * This LocalDateTime instance is immutable and unaffected by this method call.
1048         * <p>
1049         * The following three lines are identical in effect:
1050         * <pre>
1051         * LocalDateTime added = dt.plusMonths(6);
1052         * LocalDateTime added = dt.plus(Period.months(6));
1053         * LocalDateTime added = dt.withFieldAdded(DurationFieldType.months(), 6);
1054         * </pre>
1055         *
1056         * @param months  the amount of months to add, may be negative
1057         * @return the new LocalDateTime plus the increased months
1058         */
1059        public LocalDateTime plusMonths(int months) {
1060            if (months == 0) {
1061                return this;
1062            }
1063            long instant = getChronology().months().add(getLocalMillis(), months);
1064            return withLocalMillis(instant);
1065        }
1066    
1067        /**
1068         * Returns a copy of this datetime plus the specified number of weeks.
1069         * <p>
1070         * This LocalDateTime instance is immutable and unaffected by this method call.
1071         * <p>
1072         * The following three lines are identical in effect:
1073         * <pre>
1074         * LocalDateTime added = dt.plusWeeks(6);
1075         * LocalDateTime added = dt.plus(Period.weeks(6));
1076         * LocalDateTime added = dt.withFieldAdded(DurationFieldType.weeks(), 6);
1077         * </pre>
1078         *
1079         * @param weeks  the amount of weeks to add, may be negative
1080         * @return the new LocalDateTime plus the increased weeks
1081         */
1082        public LocalDateTime plusWeeks(int weeks) {
1083            if (weeks == 0) {
1084                return this;
1085            }
1086            long instant = getChronology().weeks().add(getLocalMillis(), weeks);
1087            return withLocalMillis(instant);
1088        }
1089    
1090        /**
1091         * Returns a copy of this datetime plus the specified number of days.
1092         * <p>
1093         * This LocalDateTime instance is immutable and unaffected by this method call.
1094         * <p>
1095         * The following three lines are identical in effect:
1096         * <pre>
1097         * LocalDateTime added = dt.plusDays(6);
1098         * LocalDateTime added = dt.plus(Period.days(6));
1099         * LocalDateTime added = dt.withFieldAdded(DurationFieldType.days(), 6);
1100         * </pre>
1101         *
1102         * @param days  the amount of days to add, may be negative
1103         * @return the new LocalDateTime plus the increased days
1104         */
1105        public LocalDateTime plusDays(int days) {
1106            if (days == 0) {
1107                return this;
1108            }
1109            long instant = getChronology().days().add(getLocalMillis(), days);
1110            return withLocalMillis(instant);
1111        }
1112    
1113        //-----------------------------------------------------------------------
1114        /**
1115         * Returns a copy of this datetime plus the specified number of hours.
1116         * <p>
1117         * This LocalDateTime instance is immutable and unaffected by this method call.
1118         * <p>
1119         * The following three lines are identical in effect:
1120         * <pre>
1121         * LocalDateTime added = dt.plusHours(6);
1122         * LocalDateTime added = dt.plus(Period.hours(6));
1123         * LocalDateTime added = dt.withFieldAdded(DurationFieldType.hours(), 6);
1124         * </pre>
1125         *
1126         * @param hours  the amount of hours to add, may be negative
1127         * @return the new LocalDateTime plus the increased hours
1128         */
1129        public LocalDateTime plusHours(int hours) {
1130            if (hours == 0) {
1131                return this;
1132            }
1133            long instant = getChronology().hours().add(getLocalMillis(), hours);
1134            return withLocalMillis(instant);
1135        }
1136    
1137        /**
1138         * Returns a copy of this datetime plus the specified number of minutes.
1139         * <p>
1140         * This LocalDateTime instance is immutable and unaffected by this method call.
1141         * <p>
1142         * The following three lines are identical in effect:
1143         * <pre>
1144         * LocalDateTime added = dt.plusMinutes(6);
1145         * LocalDateTime added = dt.plus(Period.minutes(6));
1146         * LocalDateTime added = dt.withFieldAdded(DurationFieldType.minutes(), 6);
1147         * </pre>
1148         *
1149         * @param minutes  the amount of minutes to add, may be negative
1150         * @return the new LocalDateTime plus the increased minutes
1151         */
1152        public LocalDateTime plusMinutes(int minutes) {
1153            if (minutes == 0) {
1154                return this;
1155            }
1156            long instant = getChronology().minutes().add(getLocalMillis(), minutes);
1157            return withLocalMillis(instant);
1158        }
1159    
1160        /**
1161         * Returns a copy of this datetime plus the specified number of seconds.
1162         * <p>
1163         * This LocalDateTime instance is immutable and unaffected by this method call.
1164         * <p>
1165         * The following three lines are identical in effect:
1166         * <pre>
1167         * LocalDateTime added = dt.plusSeconds(6);
1168         * LocalDateTime added = dt.plus(Period.seconds(6));
1169         * LocalDateTime added = dt.withFieldAdded(DurationFieldType.seconds(), 6);
1170         * </pre>
1171         *
1172         * @param seconds  the amount of seconds to add, may be negative
1173         * @return the new LocalDateTime plus the increased seconds
1174         */
1175        public LocalDateTime plusSeconds(int seconds) {
1176            if (seconds == 0) {
1177                return this;
1178            }
1179            long instant = getChronology().seconds().add(getLocalMillis(), seconds);
1180            return withLocalMillis(instant);
1181        }
1182    
1183        /**
1184         * Returns a copy of this datetime plus the specified number of millis.
1185         * <p>
1186         * This LocalDateTime instance is immutable and unaffected by this method call.
1187         * <p>
1188         * The following three lines are identical in effect:
1189         * <pre>
1190         * LocalDateTime added = dt.plusMillis(6);
1191         * LocalDateTime added = dt.plus(Period.millis(6));
1192         * LocalDateTime added = dt.withFieldAdded(DurationFieldType.millis(), 6);
1193         * </pre>
1194         *
1195         * @param millis  the amount of millis to add, may be negative
1196         * @return the new LocalDateTime plus the increased millis
1197         */
1198        public LocalDateTime plusMillis(int millis) {
1199            if (millis == 0) {
1200                return this;
1201            }
1202            long instant = getChronology().millis().add(getLocalMillis(), millis);
1203            return withLocalMillis(instant);
1204        }
1205    
1206        //-----------------------------------------------------------------------
1207        /**
1208         * Returns a copy of this datetime with the specified duration taken away.
1209         * <p>
1210         * If the amount is zero or null, then <code>this</code> is returned.
1211         *
1212         * @param duration  the duration to reduce this instant by
1213         * @return a copy of this datetime with the duration taken away
1214         * @throws ArithmeticException if the result exceeds the internal capacity
1215         */
1216        public LocalDateTime minus(ReadableDuration duration) {
1217            return withDurationAdded(duration, -1);
1218        }
1219    
1220        /**
1221         * Returns a copy of this datetime with the specified period taken away.
1222         * <p>
1223         * If the amount is zero or null, then <code>this</code> is returned.
1224         * <p>
1225         * This method is typically used to subtract complex period instances.
1226         * Subtracting one field is best achieved using methods
1227         * like {@link #minusYears(int)}.
1228         *
1229         * @param period  the period to reduce this instant by
1230         * @return a copy of this datetime with the period taken away
1231         * @throws ArithmeticException if the result exceeds the internal capacity
1232         */
1233        public LocalDateTime minus(ReadablePeriod period) {
1234            return withPeriodAdded(period, -1);
1235        }
1236    
1237        //-----------------------------------------------------------------------
1238        /**
1239         * Returns a copy of this datetime minus the specified number of years.
1240         * <p>
1241         * This LocalDateTime instance is immutable and unaffected by this method call.
1242         * <p>
1243         * The following three lines are identical in effect:
1244         * <pre>
1245         * LocalDateTime subtracted = dt.minusYears(6);
1246         * LocalDateTime subtracted = dt.minus(Period.years(6));
1247         * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.years(), -6);
1248         * </pre>
1249         *
1250         * @param years  the amount of years to subtract, may be negative
1251         * @return the new LocalDateTime minus the increased years
1252         */
1253        public LocalDateTime minusYears(int years) {
1254            if (years == 0) {
1255                return this;
1256            }
1257            long instant = getChronology().years().subtract(getLocalMillis(), years);
1258            return withLocalMillis(instant);
1259        }
1260    
1261        /**
1262         * Returns a copy of this datetime minus the specified number of months.
1263         * <p>
1264         * This LocalDateTime instance is immutable and unaffected by this method call.
1265         * <p>
1266         * The following three lines are identical in effect:
1267         * <pre>
1268         * LocalDateTime subtracted = dt.minusMonths(6);
1269         * LocalDateTime subtracted = dt.minus(Period.months(6));
1270         * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.months(), -6);
1271         * </pre>
1272         *
1273         * @param months  the amount of months to subtract, may be negative
1274         * @return the new LocalDateTime minus the increased months
1275         */
1276        public LocalDateTime minusMonths(int months) {
1277            if (months == 0) {
1278                return this;
1279            }
1280            long instant = getChronology().months().subtract(getLocalMillis(), months);
1281            return withLocalMillis(instant);
1282        }
1283    
1284        /**
1285         * Returns a copy of this datetime minus the specified number of weeks.
1286         * <p>
1287         * This LocalDateTime instance is immutable and unaffected by this method call.
1288         * <p>
1289         * The following three lines are identical in effect:
1290         * <pre>
1291         * LocalDateTime subtracted = dt.minusWeeks(6);
1292         * LocalDateTime subtracted = dt.minus(Period.weeks(6));
1293         * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.weeks(), -6);
1294         * </pre>
1295         *
1296         * @param weeks  the amount of weeks to subtract, may be negative
1297         * @return the new LocalDateTime minus the increased weeks
1298         */
1299        public LocalDateTime minusWeeks(int weeks) {
1300            if (weeks == 0) {
1301                return this;
1302            }
1303            long instant = getChronology().weeks().subtract(getLocalMillis(), weeks);
1304            return withLocalMillis(instant);
1305        }
1306    
1307        /**
1308         * Returns a copy of this datetime minus the specified number of days.
1309         * <p>
1310         * This LocalDateTime instance is immutable and unaffected by this method call.
1311         * <p>
1312         * The following three lines are identical in effect:
1313         * <pre>
1314         * LocalDateTime subtracted = dt.minusDays(6);
1315         * LocalDateTime subtracted = dt.minus(Period.days(6));
1316         * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.days(), -6);
1317         * </pre>
1318         *
1319         * @param days  the amount of days to subtract, may be negative
1320         * @return the new LocalDateTime minus the increased days
1321         */
1322        public LocalDateTime minusDays(int days) {
1323            if (days == 0) {
1324                return this;
1325            }
1326            long instant = getChronology().days().subtract(getLocalMillis(), days);
1327            return withLocalMillis(instant);
1328        }
1329    
1330        //-----------------------------------------------------------------------
1331        /**
1332         * Returns a copy of this datetime minus the specified number of hours.
1333         * <p>
1334         * This LocalDateTime instance is immutable and unaffected by this method call.
1335         * <p>
1336         * The following three lines are identical in effect:
1337         * <pre>
1338         * LocalDateTime subtracted = dt.minusHours(6);
1339         * LocalDateTime subtracted = dt.minus(Period.hours(6));
1340         * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.hours(), -6);
1341         * </pre>
1342         *
1343         * @param hours  the amount of hours to subtract, may be negative
1344         * @return the new LocalDateTime minus the increased hours
1345         */
1346        public LocalDateTime minusHours(int hours) {
1347            if (hours == 0) {
1348                return this;
1349            }
1350            long instant = getChronology().hours().subtract(getLocalMillis(), hours);
1351            return withLocalMillis(instant);
1352        }
1353    
1354        /**
1355         * Returns a copy of this datetime minus the specified number of minutes.
1356         * <p>
1357         * This LocalDateTime instance is immutable and unaffected by this method call.
1358         * <p>
1359         * The following three lines are identical in effect:
1360         * <pre>
1361         * LocalDateTime subtracted = dt.minusMinutes(6);
1362         * LocalDateTime subtracted = dt.minus(Period.minutes(6));
1363         * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.minutes(), -6);
1364         * </pre>
1365         *
1366         * @param minutes  the amount of minutes to subtract, may be negative
1367         * @return the new LocalDateTime minus the increased minutes
1368         */
1369        public LocalDateTime minusMinutes(int minutes) {
1370            if (minutes == 0) {
1371                return this;
1372            }
1373            long instant = getChronology().minutes().subtract(getLocalMillis(), minutes);
1374            return withLocalMillis(instant);
1375        }
1376    
1377        /**
1378         * Returns a copy of this datetime minus the specified number of seconds.
1379         * <p>
1380         * This LocalDateTime instance is immutable and unaffected by this method call.
1381         * <p>
1382         * The following three lines are identical in effect:
1383         * <pre>
1384         * LocalDateTime subtracted = dt.minusSeconds(6);
1385         * LocalDateTime subtracted = dt.minus(Period.seconds(6));
1386         * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.seconds(), -6);
1387         * </pre>
1388         *
1389         * @param seconds  the amount of seconds to subtract, may be negative
1390         * @return the new LocalDateTime minus the increased seconds
1391         */
1392        public LocalDateTime minusSeconds(int seconds) {
1393            if (seconds == 0) {
1394                return this;
1395            }
1396            long instant = getChronology().seconds().subtract(getLocalMillis(), seconds);
1397            return withLocalMillis(instant);
1398        }
1399    
1400        /**
1401         * Returns a copy of this datetime minus the specified number of millis.
1402         * <p>
1403         * This LocalDateTime instance is immutable and unaffected by this method call.
1404         * <p>
1405         * The following three lines are identical in effect:
1406         * <pre>
1407         * LocalDateTime subtracted = dt.minusMillis(6);
1408         * LocalDateTime subtracted = dt.minus(Period.millis(6));
1409         * LocalDateTime subtracted = dt.withFieldAdded(DurationFieldType.millis(), -6);
1410         * </pre>
1411         *
1412         * @param millis  the amount of millis to subtract, may be negative
1413         * @return the new LocalDateTime minus the increased millis
1414         */
1415        public LocalDateTime minusMillis(int millis) {
1416            if (millis == 0) {
1417                return this;
1418            }
1419            long instant = getChronology().millis().subtract(getLocalMillis(), millis);
1420            return withLocalMillis(instant);
1421        }
1422    
1423        //-----------------------------------------------------------------------
1424        /**
1425         * Gets the property object for the specified type, which contains many
1426         * useful methods.
1427         *
1428         * @param fieldType  the field type to get the chronology for
1429         * @return the property object
1430         * @throws IllegalArgumentException if the field is null or unsupported
1431         */
1432        public Property property(DateTimeFieldType fieldType) {
1433            if (fieldType == null) {
1434                throw new IllegalArgumentException("The DateTimeFieldType must not be null");
1435            }
1436            if (isSupported(fieldType) == false) {
1437                throw new IllegalArgumentException("Field '" + fieldType + "' is not supported");
1438            }
1439            return new Property(this, fieldType.getField(getChronology()));
1440        }
1441    
1442        //-----------------------------------------------------------------------
1443        /**
1444         * Get the era field value.
1445         *
1446         * @return the era
1447         */
1448        public int getEra() {
1449            return getChronology().era().get(getLocalMillis());
1450        }
1451    
1452        /**
1453         * Get the year of era field value.
1454         *
1455         * @return the year of era
1456         */
1457        public int getCenturyOfEra() {
1458            return getChronology().centuryOfEra().get(getLocalMillis());
1459        }
1460    
1461        /**
1462         * Get the year of era field value.
1463         *
1464         * @return the year of era
1465         */
1466        public int getYearOfEra() {
1467            return getChronology().yearOfEra().get(getLocalMillis());
1468        }
1469    
1470        /**
1471         * Get the year of century field value.
1472         *
1473         * @return the year of century
1474         */
1475        public int getYearOfCentury() {
1476            return getChronology().yearOfCentury().get(getLocalMillis());
1477        }
1478    
1479        /**
1480         * Get the year field value.
1481         *
1482         * @return the year
1483         */
1484        public int getYear() {
1485            return getChronology().year().get(getLocalMillis());
1486        }
1487    
1488        /**
1489         * Get the weekyear field value.
1490         * <p>
1491         * The weekyear is the year that matches with the weekOfWeekyear field.
1492         * In the standard ISO8601 week algorithm, the first week of the year
1493         * is that in which at least 4 days are in the year. As a result of this
1494         * definition, day 1 of the first week may be in the previous year.
1495         * The weekyear allows you to query the effective year for that day.
1496         *
1497         * @return the weekyear
1498         */
1499        public int getWeekyear() {
1500            return getChronology().weekyear().get(getLocalMillis());
1501        }
1502    
1503        /**
1504         * Get the month of year field value.
1505         *
1506         * @return the month of year
1507         */
1508        public int getMonthOfYear() {
1509            return getChronology().monthOfYear().get(getLocalMillis());
1510        }
1511    
1512        /**
1513         * Get the week of weekyear field value.
1514         * <p>
1515         * This field is associated with the "weekyear" via {@link #getWeekyear()}.
1516         * In the standard ISO8601 week algorithm, the first week of the year
1517         * is that in which at least 4 days are in the year. As a result of this
1518         * definition, day 1 of the first week may be in the previous year.
1519         *
1520         * @return the week of a week based year
1521         */
1522        public int getWeekOfWeekyear() {
1523            return getChronology().weekOfWeekyear().get(getLocalMillis());
1524        }
1525    
1526        /**
1527         * Get the day of year field value.
1528         *
1529         * @return the day of year
1530         */
1531        public int getDayOfYear() {
1532            return getChronology().dayOfYear().get(getLocalMillis());
1533        }
1534    
1535        /**
1536         * Get the day of month field value.
1537         * <p>
1538         * The values for the day of month are defined in {@link org.joda.time.DateTimeConstants}.
1539         *
1540         * @return the day of month
1541         */
1542        public int getDayOfMonth() {
1543            return getChronology().dayOfMonth().get(getLocalMillis());
1544        }
1545    
1546        /**
1547         * Get the day of week field value.
1548         * <p>
1549         * The values for the day of week are defined in {@link org.joda.time.DateTimeConstants}.
1550         *
1551         * @return the day of week
1552         */
1553        public int getDayOfWeek() {
1554            return getChronology().dayOfWeek().get(getLocalMillis());
1555        }
1556    
1557        //-----------------------------------------------------------------------
1558        /**
1559         * Get the hour of day field value.
1560         *
1561         * @return the hour of day
1562         */
1563        public int getHourOfDay() {
1564            return getChronology().hourOfDay().get(getLocalMillis());
1565        }
1566    
1567        /**
1568         * Get the minute of hour field value.
1569         *
1570         * @return the minute of hour
1571         */
1572        public int getMinuteOfHour() {
1573            return getChronology().minuteOfHour().get(getLocalMillis());
1574        }
1575    
1576        /**
1577         * Get the second of minute field value.
1578         *
1579         * @return the second of minute
1580         */
1581        public int getSecondOfMinute() {
1582            return getChronology().secondOfMinute().get(getLocalMillis());
1583        }
1584    
1585        /**
1586         * Get the millis of second field value.
1587         *
1588         * @return the millis of second
1589         */
1590        public int getMillisOfSecond() {
1591            return getChronology().millisOfSecond().get(getLocalMillis());
1592        }
1593    
1594        /**
1595         * Get the millis of day field value.
1596         *
1597         * @return the millis of day
1598         */
1599        public int getMillisOfDay() {
1600            return getChronology().millisOfDay().get(getLocalMillis());
1601        }
1602    
1603        //-----------------------------------------------------------------------
1604        /**
1605         * Returns a copy of this datetime with the era field updated.
1606         * <p>
1607         * LocalDateTime is immutable, so there are no set methods.
1608         * Instead, this method returns a new instance with the value of
1609         * era changed.
1610         *
1611         * @param era  the era to set
1612         * @return a copy of this object with the field set
1613         * @throws IllegalArgumentException if the value is invalid
1614         */
1615        public LocalDateTime withEra(int era) {
1616            return withLocalMillis(getChronology().era().set(getLocalMillis(), era));
1617        }
1618    
1619        /**
1620         * Returns a copy of this datetime with the century of era field updated.
1621         * <p>
1622         * LocalDateTime is immutable, so there are no set methods.
1623         * Instead, this method returns a new instance with the value of
1624         * century of era changed.
1625         *
1626         * @param centuryOfEra  the centurey of era to set
1627         * @return a copy of this object with the field set
1628         * @throws IllegalArgumentException if the value is invalid
1629         */
1630        public LocalDateTime withCenturyOfEra(int centuryOfEra) {
1631            return withLocalMillis(getChronology().centuryOfEra().set(getLocalMillis(), centuryOfEra));
1632        }
1633    
1634        /**
1635         * Returns a copy of this datetime with the year of era field updated.
1636         * <p>
1637         * LocalDateTime is immutable, so there are no set methods.
1638         * Instead, this method returns a new instance with the value of
1639         * year of era changed.
1640         *
1641         * @param yearOfEra  the year of era to set
1642         * @return a copy of this object with the field set
1643         * @throws IllegalArgumentException if the value is invalid
1644         */
1645        public LocalDateTime withYearOfEra(int yearOfEra) {
1646            return withLocalMillis(getChronology().yearOfEra().set(getLocalMillis(), yearOfEra));
1647        }
1648    
1649        /**
1650         * Returns a copy of this datetime with the year of century field updated.
1651         * <p>
1652         * LocalDateTime is immutable, so there are no set methods.
1653         * Instead, this method returns a new instance with the value of
1654         * year of century changed.
1655         *
1656         * @param yearOfCentury  the year of century to set
1657         * @return a copy of this object with the field set
1658         * @throws IllegalArgumentException if the value is invalid
1659         */
1660        public LocalDateTime withYearOfCentury(int yearOfCentury) {
1661            return withLocalMillis(getChronology().yearOfCentury().set(getLocalMillis(), yearOfCentury));
1662        }
1663    
1664        /**
1665         * Returns a copy of this datetime with the year field updated.
1666         * <p>
1667         * LocalDateTime is immutable, so there are no set methods.
1668         * Instead, this method returns a new instance with the value of
1669         * year changed.
1670         *
1671         * @param year  the year to set
1672         * @return a copy of this object with the field set
1673         * @throws IllegalArgumentException if the value is invalid
1674         */
1675        public LocalDateTime withYear(int year) {
1676            return withLocalMillis(getChronology().year().set(getLocalMillis(), year));
1677        }
1678    
1679        /**
1680         * Returns a copy of this datetime with the weekyear field updated.
1681         * <p>
1682         * The weekyear is the year that matches with the weekOfWeekyear field.
1683         * In the standard ISO8601 week algorithm, the first week of the year
1684         * is that in which at least 4 days are in the year. As a result of this
1685         * definition, day 1 of the first week may be in the previous year.
1686         * The weekyear allows you to query the effective year for that day.
1687         * <p>
1688         * LocalDateTime is immutable, so there are no set methods.
1689         * Instead, this method returns a new instance with the value of
1690         * weekyear changed.
1691         *
1692         * @param weekyear  the weekyear to set
1693         * @return a copy of this object with the field set
1694         * @throws IllegalArgumentException if the value is invalid
1695         */
1696        public LocalDateTime withWeekyear(int weekyear) {
1697            return withLocalMillis(getChronology().weekyear().set(getLocalMillis(), weekyear));
1698        }
1699    
1700        /**
1701         * Returns a copy of this datetime with the month of year field updated.
1702         * <p>
1703         * LocalDateTime is immutable, so there are no set methods.
1704         * Instead, this method returns a new instance with the value of
1705         * month of year changed.
1706         *
1707         * @param monthOfYear  the month of year to set
1708         * @return a copy of this object with the field set
1709         * @throws IllegalArgumentException if the value is invalid
1710         */
1711        public LocalDateTime withMonthOfYear(int monthOfYear) {
1712            return withLocalMillis(getChronology().monthOfYear().set(getLocalMillis(), monthOfYear));
1713        }
1714    
1715        /**
1716         * Returns a copy of this datetime with the week of weekyear field updated.
1717         * <p>
1718         * This field is associated with the "weekyear" via {@link #withWeekyear(int)}.
1719         * In the standard ISO8601 week algorithm, the first week of the year
1720         * is that in which at least 4 days are in the year. As a result of this
1721         * definition, day 1 of the first week may be in the previous year.
1722         * <p>
1723         * LocalDateTime is immutable, so there are no set methods.
1724         * Instead, this method returns a new instance with the value of
1725         * week of weekyear changed.
1726         *
1727         * @param weekOfWeekyear  the week of weekyear to set
1728         * @return a copy of this object with the field set
1729         * @throws IllegalArgumentException if the value is invalid
1730         */
1731        public LocalDateTime withWeekOfWeekyear(int weekOfWeekyear) {
1732            return withLocalMillis(getChronology().weekOfWeekyear().set(getLocalMillis(), weekOfWeekyear));
1733        }
1734    
1735        /**
1736         * Returns a copy of this datetime with the day of year field updated.
1737         * <p>
1738         * LocalDateTime is immutable, so there are no set methods.
1739         * Instead, this method returns a new instance with the value of
1740         * day of year changed.
1741         *
1742         * @param dayOfYear  the day of year to set
1743         * @return a copy of this object with the field set
1744         * @throws IllegalArgumentException if the value is invalid
1745         */
1746        public LocalDateTime withDayOfYear(int dayOfYear) {
1747            return withLocalMillis(getChronology().dayOfYear().set(getLocalMillis(), dayOfYear));
1748        }
1749    
1750        /**
1751         * Returns a copy of this datetime with the day of month field updated.
1752         * <p>
1753         * LocalDateTime is immutable, so there are no set methods.
1754         * Instead, this method returns a new instance with the value of
1755         * day of month changed.
1756         *
1757         * @param dayOfMonth  the day of month to set
1758         * @return a copy of this object with the field set
1759         * @throws IllegalArgumentException if the value is invalid
1760         */
1761        public LocalDateTime withDayOfMonth(int dayOfMonth) {
1762            return withLocalMillis(getChronology().dayOfMonth().set(getLocalMillis(), dayOfMonth));
1763        }
1764    
1765        /**
1766         * Returns a copy of this datetime with the day of week field updated.
1767         * <p>
1768         * LocalDateTime is immutable, so there are no set methods.
1769         * Instead, this method returns a new instance with the value of
1770         * day of week changed.
1771         *
1772         * @param dayOfWeek  the day of week to set
1773         * @return a copy of this object with the field set
1774         * @throws IllegalArgumentException if the value is invalid
1775         */
1776        public LocalDateTime withDayOfWeek(int dayOfWeek) {
1777            return withLocalMillis(getChronology().dayOfWeek().set(getLocalMillis(), dayOfWeek));
1778        }
1779    
1780        //-----------------------------------------------------------------------
1781        /**
1782         * Returns a copy of this datetime with the hour of day field updated.
1783         * <p>
1784         * LocalDateTime is immutable, so there are no set methods.
1785         * Instead, this method returns a new instance with the value of
1786         * hour of day changed.
1787         *
1788         * @param hour  the hour of day to set
1789         * @return a copy of this object with the field set
1790         * @throws IllegalArgumentException if the value is invalid
1791         */
1792        public LocalDateTime withHourOfDay(int hour) {
1793            return withLocalMillis(getChronology().hourOfDay().set(getLocalMillis(), hour));
1794        }
1795    
1796        /**
1797         * Returns a copy of this datetime with the minute of hour field updated.
1798         * <p>
1799         * LocalDateTime is immutable, so there are no set methods.
1800         * Instead, this method returns a new instance with the value of
1801         * minute of hour changed.
1802         *
1803         * @param minute  the minute of hour to set
1804         * @return a copy of this object with the field set
1805         * @throws IllegalArgumentException if the value is invalid
1806         */
1807        public LocalDateTime withMinuteOfHour(int minute) {
1808            return withLocalMillis(getChronology().minuteOfHour().set(getLocalMillis(), minute));
1809        }
1810    
1811        /**
1812         * Returns a copy of this datetime with the second of minute field updated.
1813         * <p>
1814         * LocalDateTime is immutable, so there are no set methods.
1815         * Instead, this method returns a new instance with the value of
1816         * second of minute changed.
1817         *
1818         * @param second  the second of minute to set
1819         * @return a copy of this object with the field set
1820         * @throws IllegalArgumentException if the value is invalid
1821         */
1822        public LocalDateTime withSecondOfMinute(int second) {
1823            return withLocalMillis(getChronology().secondOfMinute().set(getLocalMillis(), second));
1824        }
1825    
1826        /**
1827         * Returns a copy of this datetime with the millis of second field updated.
1828         * <p>
1829         * LocalDateTime is immutable, so there are no set methods.
1830         * Instead, this method returns a new instance with the value of
1831         * millis of second changed.
1832         *
1833         * @param millis  the millis of second to set
1834         * @return a copy of this object with the field set
1835         * @throws IllegalArgumentException if the value is invalid
1836         */
1837        public LocalDateTime withMillisOfSecond(int millis) {
1838            return withLocalMillis(getChronology().millisOfSecond().set(getLocalMillis(), millis));
1839        }
1840    
1841        /**
1842         * Returns a copy of this datetime with the millis of day field updated.
1843         * <p>
1844         * LocalDateTime is immutable, so there are no set methods.
1845         * Instead, this method returns a new instance with the value of
1846         * millis of day changed.
1847         *
1848         * @param millis  the millis of day to set
1849         * @return a copy of this object with the field set
1850         * @throws IllegalArgumentException if the value is invalid
1851         */
1852        public LocalDateTime withMillisOfDay(int millis) {
1853            return withLocalMillis(getChronology().millisOfDay().set(getLocalMillis(), millis));
1854        }
1855    
1856        //-----------------------------------------------------------------------
1857        /**
1858         * Get the era property which provides access to advanced functionality.
1859         *
1860         * @return the era property
1861         */
1862        public Property era() {
1863            return new Property(this, getChronology().era());
1864        }
1865    
1866        /**
1867         * Get the century of era property which provides access to advanced functionality.
1868         *
1869         * @return the year of era property
1870         */
1871        public Property centuryOfEra() {
1872            return new Property(this, getChronology().centuryOfEra());
1873        }
1874    
1875        /**
1876         * Get the year of century property which provides access to advanced functionality.
1877         *
1878         * @return the year of era property
1879         */
1880        public Property yearOfCentury() {
1881            return new Property(this, getChronology().yearOfCentury());
1882        }
1883    
1884        /**
1885         * Get the year of era property which provides access to advanced functionality.
1886         *
1887         * @return the year of era property
1888         */
1889        public Property yearOfEra() {
1890            return new Property(this, getChronology().yearOfEra());
1891        }
1892    
1893        /**
1894         * Get the year property which provides access to advanced functionality.
1895         *
1896         * @return the year property
1897         */
1898        public Property year() {
1899            return new Property(this, getChronology().year());
1900        }
1901    
1902        /**
1903         * Get the weekyear property which provides access to advanced functionality.
1904         *
1905         * @return the weekyear property
1906         */
1907        public Property weekyear() {
1908            return new Property(this, getChronology().weekyear());
1909        }
1910    
1911        /**
1912         * Get the month of year property which provides access to advanced functionality.
1913         *
1914         * @return the month of year property
1915         */
1916        public Property monthOfYear() {
1917            return new Property(this, getChronology().monthOfYear());
1918        }
1919    
1920        /**
1921         * Get the week of a week based year property which provides access to advanced functionality.
1922         *
1923         * @return the week of a week based year property
1924         */
1925        public Property weekOfWeekyear() {
1926            return new Property(this, getChronology().weekOfWeekyear());
1927        }
1928    
1929        /**
1930         * Get the day of year property which provides access to advanced functionality.
1931         *
1932         * @return the day of year property
1933         */
1934        public Property dayOfYear() {
1935            return new Property(this, getChronology().dayOfYear());
1936        }
1937    
1938        /**
1939         * Get the day of month property which provides access to advanced functionality.
1940         *
1941         * @return the day of month property
1942         */
1943        public Property dayOfMonth() {
1944            return new Property(this, getChronology().dayOfMonth());
1945        }
1946    
1947        /**
1948         * Get the day of week property which provides access to advanced functionality.
1949         *
1950         * @return the day of week property
1951         */
1952        public Property dayOfWeek() {
1953            return new Property(this, getChronology().dayOfWeek());
1954        }
1955    
1956        //-----------------------------------------------------------------------
1957        /**
1958         * Get the hour of day field property which provides access to advanced functionality.
1959         * 
1960         * @return the hour of day property
1961         */
1962        public Property hourOfDay() {
1963            return new Property(this, getChronology().hourOfDay());
1964        }
1965    
1966        /**
1967         * Get the minute of hour field property which provides access to advanced functionality.
1968         * 
1969         * @return the minute of hour property
1970         */
1971        public Property minuteOfHour() {
1972            return new Property(this, getChronology().minuteOfHour());
1973        }
1974    
1975        /**
1976         * Get the second of minute field property which provides access to advanced functionality.
1977         * 
1978         * @return the second of minute property
1979         */
1980        public Property secondOfMinute() {
1981            return new Property(this, getChronology().secondOfMinute());
1982        }
1983    
1984        /**
1985         * Get the millis of second property which provides access to advanced functionality.
1986         * 
1987         * @return the millis of second property
1988         */
1989        public Property millisOfSecond() {
1990            return new Property(this, getChronology().millisOfSecond());
1991        }
1992    
1993        /**
1994         * Get the millis of day property which provides access to advanced functionality.
1995         * 
1996         * @return the millis of day property
1997         */
1998        public Property millisOfDay() {
1999            return new Property(this, getChronology().millisOfDay());
2000        }
2001    
2002        //-----------------------------------------------------------------------
2003        /**
2004         * Output the date time in ISO8601 format (yyyy-MM-ddTHH:mm:ss.SSS).
2005         * 
2006         * @return ISO8601 time formatted string.
2007         */
2008        @ToString
2009        public String toString() {
2010            return ISODateTimeFormat.dateTime().print(this);
2011        }
2012    
2013        /**
2014         * Output the date using the specified format pattern.
2015         *
2016         * @param pattern  the pattern specification, null means use <code>toString</code>
2017         * @see org.joda.time.format.DateTimeFormat
2018         */
2019        public String toString(String pattern) {
2020            if (pattern == null) {
2021                return toString();
2022            }
2023            return DateTimeFormat.forPattern(pattern).print(this);
2024        }
2025    
2026        /**
2027         * Output the date using the specified format pattern.
2028         *
2029         * @param pattern  the pattern specification, null means use <code>toString</code>
2030         * @param locale  Locale to use, null means default
2031         * @see org.joda.time.format.DateTimeFormat
2032         */
2033        public String toString(String pattern, Locale locale) throws IllegalArgumentException {
2034            if (pattern == null) {
2035                return toString();
2036            }
2037            return DateTimeFormat.forPattern(pattern).withLocale(locale).print(this);
2038        }
2039    
2040        //-----------------------------------------------------------------------
2041        /**
2042         * LocalDateTime.Property binds a LocalDateTime to a DateTimeField allowing
2043         * powerful datetime functionality to be easily accessed.
2044         * <p>
2045         * The simplest use of this class is as an alternative get method, here used to
2046         * get the year '1972' (as an int) and the month 'December' (as a String).
2047         * <pre>
2048         * LocalDateTime dt = new LocalDateTime(1972, 12, 3, 0, 0);
2049         * int year = dt.year().get();
2050         * String monthStr = dt.month().getAsText();
2051         * </pre>
2052         * <p>
2053         * Methods are also provided that allow date modification. These return
2054         * new instances of LocalDateTime - they do not modify the original.
2055         * The example below yields two independent immutable date objects
2056         * 20 years apart.
2057         * <pre>
2058         * LocalDateTime dt = new LocalDateTime(1972, 12, 3, 0, 0);
2059         * LocalDateTime dt1920 = dt.year().setCopy(1920);
2060         * </pre>
2061         * <p>
2062         * LocalDateTime.Property itself is thread-safe and immutable, as well as the
2063         * LocalDateTime being operated on.
2064         *
2065         * @author Stephen Colebourne
2066         * @author Brian S O'Neill
2067         * @since 1.3
2068         */
2069        public static final class Property extends AbstractReadableInstantFieldProperty {
2070            
2071            /** Serialization version */
2072            private static final long serialVersionUID = -358138762846288L;
2073            
2074            /** The instant this property is working against */
2075            private transient LocalDateTime iInstant;
2076            /** The field this property is working against */
2077            private transient DateTimeField iField;
2078            
2079            /**
2080             * Constructor.
2081             * 
2082             * @param instant  the instant to set
2083             * @param field  the field to use
2084             */
2085            Property(LocalDateTime instant, DateTimeField field) {
2086                super();
2087                iInstant = instant;
2088                iField = field;
2089            }
2090            
2091            /**
2092             * Writes the property in a safe serialization format.
2093             */
2094            private void writeObject(ObjectOutputStream oos) throws IOException {
2095                oos.writeObject(iInstant);
2096                oos.writeObject(iField.getType());
2097            }
2098    
2099            /**
2100             * Reads the property from a safe serialization format.
2101             */
2102            private void readObject(ObjectInputStream oos) throws IOException, ClassNotFoundException {
2103                iInstant = (LocalDateTime) oos.readObject();
2104                DateTimeFieldType type = (DateTimeFieldType) oos.readObject();
2105                iField = type.getField(iInstant.getChronology());
2106            }
2107    
2108            //-----------------------------------------------------------------------
2109            /**
2110             * Gets the field being used.
2111             * 
2112             * @return the field
2113             */
2114            public DateTimeField getField() {
2115                return iField;
2116            }
2117            
2118            /**
2119             * Gets the milliseconds of the datetime that this property is linked to.
2120             * 
2121             * @return the milliseconds
2122             */
2123            protected long getMillis() {
2124                return iInstant.getLocalMillis();
2125            }
2126            
2127            /**
2128             * Gets the chronology of the datetime that this property is linked to.
2129             * 
2130             * @return the chronology
2131             * @since 1.4
2132             */
2133            protected Chronology getChronology() {
2134                return iInstant.getChronology();
2135            }
2136            
2137            /**
2138             * Gets the LocalDateTime object linked to this property.
2139             * 
2140             * @return the linked LocalDateTime
2141             */
2142            public LocalDateTime getLocalDateTime() {
2143                return iInstant;
2144            }
2145            
2146            //-----------------------------------------------------------------------
2147            /**
2148             * Adds to this field in a copy of this LocalDateTime.
2149             * <p>
2150             * The LocalDateTime attached to this property is unchanged by this call.
2151             *
2152             * @param value  the value to add to the field in the copy
2153             * @return a copy of the LocalDateTime with the field value changed
2154             * @throws IllegalArgumentException if the value isn't valid
2155             */
2156            public LocalDateTime addToCopy(int value) {
2157                return iInstant.withLocalMillis(iField.add(iInstant.getLocalMillis(), value));
2158            }
2159            
2160            /**
2161             * Adds to this field in a copy of this LocalDateTime.
2162             * <p>
2163             * The LocalDateTime attached to this property is unchanged by this call.
2164             *
2165             * @param value  the value to add to the field in the copy
2166             * @return a copy of the LocalDateTime with the field value changed
2167             * @throws IllegalArgumentException if the value isn't valid
2168             */
2169            public LocalDateTime addToCopy(long value) {
2170                return iInstant.withLocalMillis(iField.add(iInstant.getLocalMillis(), value));
2171            }
2172            
2173            /**
2174             * Adds to this field, possibly wrapped, in a copy of this LocalDateTime.
2175             * A field wrapped operation only changes this field.
2176             * Thus 31st January addWrapField one day goes to the 1st January.
2177             * <p>
2178             * The LocalDateTime attached to this property is unchanged by this call.
2179             *
2180             * @param value  the value to add to the field in the copy
2181             * @return a copy of the LocalDateTime with the field value changed
2182             * @throws IllegalArgumentException if the value isn't valid
2183             */
2184            public LocalDateTime addWrapFieldToCopy(int value) {
2185                return iInstant.withLocalMillis(iField.addWrapField(iInstant.getLocalMillis(), value));
2186            }
2187            
2188            //-----------------------------------------------------------------------
2189            /**
2190             * Sets this field in a copy of the LocalDateTime.
2191             * <p>
2192             * The LocalDateTime attached to this property is unchanged by this call.
2193             *
2194             * @param value  the value to set the field in the copy to
2195             * @return a copy of the LocalDateTime with the field value changed
2196             * @throws IllegalArgumentException if the value isn't valid
2197             */
2198            public LocalDateTime setCopy(int value) {
2199                return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), value));
2200            }
2201            
2202            /**
2203             * Sets this field in a copy of the LocalDateTime to a parsed text value.
2204             * <p>
2205             * The LocalDateTime attached to this property is unchanged by this call.
2206             *
2207             * @param text  the text value to set
2208             * @param locale  optional locale to use for selecting a text symbol
2209             * @return a copy of the LocalDateTime with the field value changed
2210             * @throws IllegalArgumentException if the text value isn't valid
2211             */
2212            public LocalDateTime setCopy(String text, Locale locale) {
2213                return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), text, locale));
2214            }
2215            
2216            /**
2217             * Sets this field in a copy of the LocalDateTime to a parsed text value.
2218             * <p>
2219             * The LocalDateTime attached to this property is unchanged by this call.
2220             *
2221             * @param text  the text value to set
2222             * @return a copy of the LocalDateTime with the field value changed
2223             * @throws IllegalArgumentException if the text value isn't valid
2224             */
2225            public LocalDateTime setCopy(String text) {
2226                return setCopy(text, null);
2227            }
2228            
2229            //-----------------------------------------------------------------------
2230            /**
2231             * Returns a new LocalDateTime with this field set to the maximum value
2232             * for this field.
2233             * <p>
2234             * This operation is useful for obtaining a LocalDateTime on the last day
2235             * of the month, as month lengths vary.
2236             * <pre>
2237             * LocalDateTime lastDayOfMonth = dt.dayOfMonth().withMaximumValue();
2238             * </pre>
2239             * <p>
2240             * The LocalDateTime attached to this property is unchanged by this call.
2241             *
2242             * @return a copy of the LocalDateTime with this field set to its maximum
2243             */
2244            public LocalDateTime withMaximumValue() {
2245                return setCopy(getMaximumValue());
2246            }
2247            
2248            /**
2249             * Returns a new LocalDateTime with this field set to the minimum value
2250             * for this field.
2251             * <p>
2252             * The LocalDateTime attached to this property is unchanged by this call.
2253             *
2254             * @return a copy of the LocalDateTime with this field set to its minimum
2255             */
2256            public LocalDateTime withMinimumValue() {
2257                return setCopy(getMinimumValue());
2258            }
2259            
2260            //-----------------------------------------------------------------------
2261            /**
2262             * Rounds to the lowest whole unit of this field on a copy of this
2263             * LocalDateTime.
2264             * <p>
2265             * For example, rounding floor on the hourOfDay field of a LocalDateTime
2266             * where the time is 10:30 would result in new LocalDateTime with the
2267             * time of 10:00.
2268             *
2269             * @return a copy of the LocalDateTime with the field value changed
2270             */
2271            public LocalDateTime roundFloorCopy() {
2272                return iInstant.withLocalMillis(iField.roundFloor(iInstant.getLocalMillis()));
2273            }
2274            
2275            /**
2276             * Rounds to the highest whole unit of this field on a copy of this
2277             * LocalDateTime.
2278             * <p>
2279             * For example, rounding floor on the hourOfDay field of a LocalDateTime
2280             * where the time is 10:30 would result in new LocalDateTime with the
2281             * time of 11:00.
2282             *
2283             * @return a copy of the LocalDateTime with the field value changed
2284             */
2285            public LocalDateTime roundCeilingCopy() {
2286                return iInstant.withLocalMillis(iField.roundCeiling(iInstant.getLocalMillis()));
2287            }
2288            
2289            /**
2290             * Rounds to the nearest whole unit of this field on a copy of this
2291             * LocalDateTime, favoring the floor if halfway.
2292             *
2293             * @return a copy of the LocalDateTime with the field value changed
2294             */
2295            public LocalDateTime roundHalfFloorCopy() {
2296                return iInstant.withLocalMillis(iField.roundHalfFloor(iInstant.getLocalMillis()));
2297            }
2298            
2299            /**
2300             * Rounds to the nearest whole unit of this field on a copy of this
2301             * LocalDateTime, favoring the ceiling if halfway.
2302             *
2303             * @return a copy of the LocalDateTime with the field value changed
2304             */
2305            public LocalDateTime roundHalfCeilingCopy() {
2306                return iInstant.withLocalMillis(iField.roundHalfCeiling(iInstant.getLocalMillis()));
2307            }
2308            
2309            /**
2310             * Rounds to the nearest whole unit of this field on a copy of this
2311             * LocalDateTime.  If halfway, the ceiling is favored over the floor
2312             * only if it makes this field's value even.
2313             *
2314             * @return a copy of the LocalDateTime with the field value changed
2315             */
2316            public LocalDateTime roundHalfEvenCopy() {
2317                return iInstant.withLocalMillis(iField.roundHalfEven(iInstant.getLocalMillis()));
2318            }
2319        }
2320    
2321    }