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