View Javadoc

1   /*
2    *  Copyright 2001-2013 Stephen Colebourne
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  package org.joda.time;
17  
18  import java.io.IOException;
19  import java.io.ObjectInputStream;
20  import java.io.ObjectOutputStream;
21  import java.io.Serializable;
22  import java.util.Calendar;
23  import java.util.Date;
24  import java.util.GregorianCalendar;
25  import java.util.Locale;
26  import java.util.TimeZone;
27  
28  import org.joda.convert.FromString;
29  import org.joda.convert.ToString;
30  import org.joda.time.base.BaseLocal;
31  import org.joda.time.chrono.ISOChronology;
32  import org.joda.time.convert.ConverterManager;
33  import org.joda.time.convert.PartialConverter;
34  import org.joda.time.field.AbstractReadableInstantFieldProperty;
35  import org.joda.time.format.DateTimeFormat;
36  import org.joda.time.format.DateTimeFormatter;
37  import org.joda.time.format.ISODateTimeFormat;
38  
39  /**
40   * LocalDateTime is an unmodifiable datetime class representing a
41   * datetime without a time zone.
42   * <p>
43   * LocalDateTime implements the {@link ReadablePartial} interface.
44   * To do this, certain methods focus on key fields Year, MonthOfYear,
45   * DayOfYear and MillisOfDay.
46   * However, <b>all</b> fields may in fact be queried.
47   * <p>
48   * Internally, LocalDateTime uses a single millisecond-based value to
49   * represent the local datetime. This value is only used internally and
50   * is not exposed to applications.
51   * <p>
52   * Calculations on LocalDateTime are performed using a {@link Chronology}.
53   * This chronology will be set internally to be in the UTC time zone
54   * for all calculations.
55   *
56   * <p>Each individual field can be queried in two ways:
57   * <ul>
58   * <li><code>getHourOfDay()</code>
59   * <li><code>hourOfDay().get()</code>
60   * </ul>
61   * The second technique also provides access to other useful methods on the
62   * field:
63   * <ul>
64   * <li>numeric value
65   * <li>text value
66   * <li>short text value
67   * <li>maximum/minimum values
68   * <li>add/subtract
69   * <li>set
70   * <li>rounding
71   * </ul>
72   *
73   * <p>
74   * LocalDateTime is thread-safe and immutable, provided that the Chronology is as well.
75   * All standard Chronology classes supplied are thread-safe and immutable.
76   *
77   * @author Stephen Colebourne
78   * @since 1.3
79   */
80  public final class LocalDateTime
81          extends BaseLocal
82          implements ReadablePartial, Serializable {
83  
84      /** Serialization lock */
85      private static final long serialVersionUID = -268716875315837168L;
86  
87      /** The index of the year field in the field array */
88      private static final int YEAR = 0;
89      /** The index of the monthOfYear field in the field array */
90      private static final int MONTH_OF_YEAR = 1;
91      /** The index of the dayOfMonth field in the field array */
92      private static final int DAY_OF_MONTH = 2;
93      /** The index of the millis field in the field array */
94      private static final int MILLIS_OF_DAY = 3;
95  
96      /** The local millis from 1970-01-01T00:00:00 */
97      private final long iLocalMillis;
98      /** The chronology to use in UTC */
99      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 }