001    /*
002     *  Copyright 2001-2006 Stephen Colebourne
003     *
004     *  Licensed under the Apache License, Version 2.0 (the "License");
005     *  you may not use this file except in compliance with the License.
006     *  You may obtain a copy of the License at
007     *
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     *
010     *  Unless required by applicable law or agreed to in writing, software
011     *  distributed under the License is distributed on an "AS IS" BASIS,
012     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     *  See the License for the specific language governing permissions and
014     *  limitations under the License.
015     */
016    package org.joda.time;
017    
018    import java.io.IOException;
019    import java.io.ObjectInputStream;
020    import java.io.ObjectOutputStream;
021    import java.io.Serializable;
022    import java.util.Locale;
023    
024    import org.joda.time.base.BaseDateTime;
025    import org.joda.time.chrono.ISOChronology;
026    import org.joda.time.field.AbstractReadableInstantFieldProperty;
027    import org.joda.time.format.ISODateTimeFormat;
028    
029    /**
030     * DateTime is the standard implementation of an unmodifiable datetime class.
031     * <p>
032     * <code>DateTime</code> is the most widely used implementation of
033     * {@link ReadableInstant}. As with all instants, it represents an exact
034     * point on the time-line, but limited to the precision of milliseconds.
035     * A <code>DateTime</code> calculates its fields with respect to a
036     * {@link DateTimeZone time zone}.
037     * <p>
038     * Internally, the class holds two pieces of data. Firstly, it holds the
039     * datetime as milliseconds from the Java epoch of 1970-01-01T00:00:00Z.
040     * Secondly, it holds a {@link Chronology} which determines how the
041     * millisecond instant value is converted into the date time fields.
042     * The default Chronology is {@link ISOChronology} which is the agreed
043     * international standard and compatible with the modern Gregorian calendar.
044     * <p>
045     * Each individual field can be queried in two ways:
046     * <ul>
047     * <li><code>getHourOfDay()</code>
048     * <li><code>hourOfDay().get()</code>
049     * </ul>
050     * The second technique also provides access to other useful methods on the
051     * field:
052     * <ul>
053     * <li>numeric value
054     * <li>text value
055     * <li>short text value
056     * <li>maximum/minimum values
057     * <li>add/subtract
058     * <li>set
059     * <li>rounding
060     * </ul>
061     * <p>
062     * DateTime is thread-safe and immutable, provided that the Chronology is as well.
063     * All standard Chronology classes supplied are thread-safe and immutable.
064     *
065     * @author Stephen Colebourne
066     * @author Kandarp Shah
067     * @author Brian S O'Neill
068     * @since 1.0
069     * @see MutableDateTime
070     */
071    public final class DateTime
072            extends BaseDateTime
073            implements ReadableDateTime, Serializable {
074    
075        /** Serialization lock */
076        private static final long serialVersionUID = -5171125899451703815L;
077    
078        //-----------------------------------------------------------------------
079        /**
080         * Constructs an instance set to the current system millisecond time
081         * using <code>ISOChronology</code> in the default time zone.
082         */
083        public DateTime() {
084            super();
085        }
086    
087        /**
088         * Constructs an instance set to the current system millisecond time
089         * using <code>ISOChronology</code> in the specified time zone.
090         * <p>
091         * If the specified time zone is null, the default zone is used.
092         *
093         * @param zone  the time zone, null means default zone
094         */
095        public DateTime(DateTimeZone zone) {
096            super(zone);
097        }
098    
099        /**
100         * Constructs an instance set to the current system millisecond time
101         * using the specified chronology.
102         * <p>
103         * If the chronology is null, <code>ISOChronology</code>
104         * in the default time zone is used.
105         *
106         * @param chronology  the chronology, null means ISOChronology in default zone
107         */
108        public DateTime(Chronology chronology) {
109            super(chronology);
110        }
111    
112        //-----------------------------------------------------------------------
113        /**
114         * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z
115         * using <code>ISOChronology</code> in the default time zone.
116         *
117         * @param instant  the milliseconds from 1970-01-01T00:00:00Z
118         */
119        public DateTime(long instant) {
120            super(instant);
121        }
122    
123        /**
124         * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z
125         * using <code>ISOChronology</code> in the specified time zone.
126         * <p>
127         * If the specified time zone is null, the default zone is used.
128         *
129         * @param instant  the milliseconds from 1970-01-01T00:00:00Z
130         * @param zone  the time zone, null means default zone
131         */
132        public DateTime(long instant, DateTimeZone zone) {
133            super(instant, zone);
134        }
135    
136        /**
137         * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z
138         * using the specified chronology.
139         * <p>
140         * If the chronology is null, <code>ISOChronology</code>
141         * in the default time zone is used.
142         *
143         * @param instant  the milliseconds from 1970-01-01T00:00:00Z
144         * @param chronology  the chronology, null means ISOChronology in default zone
145         */
146        public DateTime(long instant, Chronology chronology) {
147            super(instant, chronology);
148        }
149    
150        //-----------------------------------------------------------------------
151        /**
152         * Constructs an instance from an Object that represents a datetime.
153         * <p>
154         * If the object implies a chronology (such as GregorianCalendar does),
155         * then that chronology will be used. Otherwise, ISO default is used.
156         * Thus if a GregorianCalendar is passed in, the chronology used will
157         * be GJ, but if a Date is passed in the chronology will be ISO.
158         * <p>
159         * The recognised object types are defined in
160         * {@link org.joda.time.convert.ConverterManager ConverterManager} and
161         * include ReadableInstant, String, Calendar and Date.
162         * The String formats are described by {@link ISODateTimeFormat#dateTimeParser()}.
163         *
164         * @param instant  the datetime object, null means now
165         * @throws IllegalArgumentException if the instant is invalid
166         */
167        public DateTime(Object instant) {
168            super(instant, (Chronology) null);
169        }
170    
171        /**
172         * Constructs an instance from an Object that represents a datetime,
173         * forcing the time zone to that specified.
174         * <p>
175         * If the object implies a chronology (such as GregorianCalendar does),
176         * then that chronology will be used, but with the time zone adjusted.
177         * Otherwise, ISO is used in the specified time zone.
178         * If the specified time zone is null, the default zone is used.
179         * Thus if a GregorianCalendar is passed in, the chronology used will
180         * be GJ, but if a Date is passed in the chronology will be ISO.
181         * <p>
182         * The recognised object types are defined in
183         * {@link org.joda.time.convert.ConverterManager ConverterManager} and
184         * include ReadableInstant, String, Calendar and Date.
185         * The String formats are described by {@link ISODateTimeFormat#dateTimeParser()}.
186         *
187         * @param instant  the datetime object, null means now
188         * @param zone  the time zone, null means default time zone
189         * @throws IllegalArgumentException if the instant is invalid
190         */
191        public DateTime(Object instant, DateTimeZone zone) {
192            super(instant, zone);
193        }
194    
195        /**
196         * Constructs an instance from an Object that represents a datetime,
197         * using the specified chronology.
198         * <p>
199         * If the chronology is null, ISO in the default time zone is used.
200         * Any chronology implied by the object (such as GregorianCalendar does)
201         * is ignored.
202         * <p>
203         * The recognised object types are defined in
204         * {@link org.joda.time.convert.ConverterManager ConverterManager} and
205         * include ReadableInstant, String, Calendar and Date.
206         * The String formats are described by {@link ISODateTimeFormat#dateTimeParser()}.
207         *
208         * @param instant  the datetime object, null means now
209         * @param chronology  the chronology, null means ISO in default zone
210         * @throws IllegalArgumentException if the instant is invalid
211         */
212        public DateTime(Object instant, Chronology chronology) {
213            super(instant, DateTimeUtils.getChronology(chronology));
214        }
215    
216        //-----------------------------------------------------------------------
217        /**
218         * Constructs an instance from datetime field values
219         * using <code>ISOChronology</code> in the default time zone.
220         *
221         * @param year  the year
222         * @param monthOfYear  the month of the year
223         * @param dayOfMonth  the day of the month
224         * @param hourOfDay  the hour of the day
225         * @param minuteOfHour  the minute of the hour
226         * @param secondOfMinute  the second of the minute
227         * @param millisOfSecond  the millisecond of the second
228         */
229        public DateTime(
230                int year,
231                int monthOfYear,
232                int dayOfMonth,
233                int hourOfDay,
234                int minuteOfHour,
235                int secondOfMinute,
236                int millisOfSecond) {
237            super(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond);
238        }
239    
240        /**
241         * Constructs an instance from datetime field values
242         * using <code>ISOChronology</code> in the specified time zone.
243         * <p>
244         * If the specified time zone is null, the default zone is used.
245         *
246         * @param year  the year
247         * @param monthOfYear  the month of the year
248         * @param dayOfMonth  the day of the month
249         * @param hourOfDay  the hour of the day
250         * @param minuteOfHour  the minute of the hour
251         * @param secondOfMinute  the second of the minute
252         * @param millisOfSecond  the millisecond of the second
253         * @param zone  the time zone, null means default time zone
254         */
255        public DateTime(
256                int year,
257                int monthOfYear,
258                int dayOfMonth,
259                int hourOfDay,
260                int minuteOfHour,
261                int secondOfMinute,
262                int millisOfSecond,
263                DateTimeZone zone) {
264            super(year, monthOfYear, dayOfMonth,
265                  hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond, zone);
266        }
267    
268        /**
269         * Constructs an instance from datetime field values
270         * using the specified chronology.
271         * <p>
272         * If the chronology is null, <code>ISOChronology</code>
273         * in the default time zone is used.
274         *
275         * @param year  the year
276         * @param monthOfYear  the month of the year
277         * @param dayOfMonth  the day of the month
278         * @param hourOfDay  the hour of the day
279         * @param minuteOfHour  the minute of the hour
280         * @param secondOfMinute  the second of the minute
281         * @param millisOfSecond  the millisecond of the second
282         * @param chronology  the chronology, null means ISOChronology in default zone
283         */
284        public DateTime(
285                int year,
286                int monthOfYear,
287                int dayOfMonth,
288                int hourOfDay,
289                int minuteOfHour,
290                int secondOfMinute,
291                int millisOfSecond,
292                Chronology chronology) {
293            super(year, monthOfYear, dayOfMonth,
294                  hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond, chronology);
295        }
296    
297        //-----------------------------------------------------------------------
298        /**
299         * Get this object as a DateTime by returning <code>this</code>.
300         * 
301         * @return <code>this</code>
302         */
303        public DateTime toDateTime() {
304            return this;
305        }
306    
307        /**
308         * Get this object as a DateTime using ISOChronology in the default zone,
309         * returning <code>this</code> if possible.
310         * 
311         * @return a DateTime using the same millis
312         */
313        public DateTime toDateTimeISO() {
314            if (getChronology() == ISOChronology.getInstance()) {
315                return this;
316            }
317            return super.toDateTimeISO();
318        }
319    
320        /**
321         * Get this object as a DateTime, returning <code>this</code> if possible.
322         * 
323         * @param zone time zone to apply, or default if null
324         * @return a DateTime using the same millis
325         */
326        public DateTime toDateTime(DateTimeZone zone) {
327            zone = DateTimeUtils.getZone(zone);
328            if (getZone() == zone) {
329                return this;
330            }
331            return super.toDateTime(zone);
332        }
333    
334        /**
335         * Get this object as a DateTime, returning <code>this</code> if possible.
336         * 
337         * @param chronology chronology to apply, or ISOChronology if null
338         * @return a DateTime using the same millis
339         */
340        public DateTime toDateTime(Chronology chronology) {
341            chronology = DateTimeUtils.getChronology(chronology);
342            if (getChronology() == chronology) {
343                return this;
344            }
345            return super.toDateTime(chronology);
346        }
347    
348        //-----------------------------------------------------------------------
349        /**
350         * Returns a copy of this datetime with different millis.
351         * <p>
352         * The returned object will be either be a new instance or <code>this</code>.
353         * Only the millis will change, the chronology and time zone are kept.
354         *
355         * @param newMillis  the new millis, from 1970-01-01T00:00:00Z
356         * @return a copy of this datetime with different millis
357         */
358        public DateTime withMillis(long newMillis) {
359            return (newMillis == getMillis() ? this : new DateTime(newMillis, getChronology()));
360        }
361    
362        /**
363         * Returns a copy of this datetime with a different chronology.
364         * <p>
365         * The returned object will be either be a new instance or <code>this</code>.
366         * Only the chronology will change, the millis are kept.
367         *
368         * @param newChronology  the new chronology, null means ISO default
369         * @return a copy of this datetime with a different chronology
370         */
371        public DateTime withChronology(Chronology newChronology) {
372            newChronology = DateTimeUtils.getChronology(newChronology);
373            return (newChronology == getChronology() ? this : new DateTime(getMillis(), newChronology));
374        }
375    
376        //-----------------------------------------------------------------------
377        /**
378         * Returns a copy of this datetime with a different time zone, preserving the
379         * millisecond instant.
380         * <p>
381         * This method is useful for finding the local time in another timezone.
382         * For example, if this instant holds 12:30 in Europe/London, the result
383         * from this method with Europe/Paris would be 13:30.
384         * <p>
385         * The returned object will be a new instance of the same implementation type.
386         * This method changes the time zone, and does not change the
387         * millisecond instant, with the effect that the field values usually change.
388         * The returned object will be either be a new instance or <code>this</code>.
389         *
390         * @param newZone  the new time zone
391         * @return a copy of this datetime with a different time zone
392         * @see #withZoneRetainFields
393         */
394        public DateTime withZone(DateTimeZone newZone) {
395            return withChronology(getChronology().withZone(newZone));
396        }
397    
398        /**
399         * Returns a copy of this datetime with a different time zone, preserving the
400         * field values.
401         * <p>
402         * This method is useful for finding the millisecond time in another timezone.
403         * For example, if this instant holds 12:30 in Europe/London (ie. 12:30Z),
404         * the result from this method with Europe/Paris would be 12:30 (ie. 11:30Z).
405         * <p>
406         * The returned object will be a new instance of the same implementation type.
407         * This method changes the time zone and the millisecond instant to keep
408         * the field values the same.
409         * The returned object will be either be a new instance or <code>this</code>.
410         *
411         * @param newZone  the new time zone, null means default
412         * @return a copy of this datetime with a different time zone
413         * @see #withZone
414         */
415        public DateTime withZoneRetainFields(DateTimeZone newZone) {
416            newZone = DateTimeUtils.getZone(newZone);
417            DateTimeZone originalZone = DateTimeUtils.getZone(getZone());
418            if (newZone == originalZone) {
419                return this;
420            }
421            
422            long millis = originalZone.getMillisKeepLocal(newZone, getMillis());
423            return new DateTime(millis, getChronology().withZone(newZone));
424        }
425    
426        //-----------------------------------------------------------------------
427        /**
428         * Returns a copy of this datetime with the specified date, retaining the time fields.
429         * <p>
430         * If the date is already the date passed in, then <code>this</code> is returned.
431         * <p>
432         * To set a single field use the properties, for example:
433         * <pre>
434         * DateTime set = monthOfYear().setCopy(6);
435         * </pre>
436         *
437         * @param year  the new year value
438         * @param monthOfYear  the new monthOfYear value
439         * @param dayOfMonth  the new dayOfMonth value
440         * @return a copy of this datetime with a different date
441         * @throws IllegalArgumentException if any value if invalid
442         */
443        public DateTime withDate(int year, int monthOfYear, int dayOfMonth) {
444            Chronology chrono = getChronology();
445            long instant = getMillis();
446            instant = chrono.year().set(instant, year);
447            instant = chrono.monthOfYear().set(instant, monthOfYear);
448            instant = chrono.dayOfMonth().set(instant, dayOfMonth);
449            return withMillis(instant);
450        }
451    
452        /**
453         * Returns a copy of this datetime with the specified time, retaining the date fields.
454         * <p>
455         * If the time is already the time passed in, then <code>this</code> is returned.
456         * <p>
457         * To set a single field use the properties, for example:
458         * <pre>
459         * DateTime set = dt.hourOfDay().setCopy(6);
460         * </pre>
461         *
462         * @param hourOfDay  the hour of the day
463         * @param minuteOfHour  the minute of the hour
464         * @param secondOfMinute  the second of the minute
465         * @param millisOfSecond  the millisecond of the second
466         * @return a copy of this datetime with a different time
467         * @throws IllegalArgumentException if any value if invalid
468         */
469        public DateTime withTime(int hourOfDay, int minuteOfHour, int secondOfMinute, int millisOfSecond) {
470            Chronology chrono = getChronology();
471            long instant = getMillis();
472            instant = chrono.hourOfDay().set(instant, hourOfDay);
473            instant = chrono.minuteOfHour().set(instant, minuteOfHour);
474            instant = chrono.secondOfMinute().set(instant, secondOfMinute);
475            instant = chrono.millisOfSecond().set(instant, millisOfSecond);
476            return withMillis(instant);
477        }
478    
479        //-----------------------------------------------------------------------
480        /**
481         * Returns a copy of this datetime with the partial set of fields replacing those
482         * from this instance.
483         * <p>
484         * For example, if the partial is a <code>TimeOfDay</code> then the time fields
485         * would be changed in the returned instance.
486         * If the partial is null, then <code>this</code> is returned.
487         *
488         * @param partial  the partial set of fields to apply to this datetime, null ignored
489         * @return a copy of this datetime with a different set of fields
490         * @throws IllegalArgumentException if any value is invalid
491         */
492        public DateTime withFields(ReadablePartial partial) {
493            if (partial == null) {
494                return this;
495            }
496            return withMillis(getChronology().set(partial, getMillis()));
497        }
498    
499        /**
500         * Returns a copy of this datetime with the specified field set to a new value.
501         * <p>
502         * For example, if the field type is <code>hourOfDay</code> then the hour of day
503         * field would be changed in the returned instance.
504         * If the field type is null, then <code>this</code> is returned.
505         * <p>
506         * These three lines are equivalent:
507         * <pre>
508         * DateTime updated = dt.withField(DateTimeFieldType.dayOfMonth(), 6);
509         * DateTime updated = dt.dayOfMonth().setCopy(6);
510         * DateTime updated = dt.property(DateTimeFieldType.dayOfMonth()).setCopy(6);
511         * </pre>
512         *
513         * @param fieldType  the field type to set, not null
514         * @param value  the value to set
515         * @return a copy of this datetime with the field set
516         * @throws IllegalArgumentException if the value is null or invalid
517         */
518        public DateTime withField(DateTimeFieldType fieldType, int value) {
519            if (fieldType == null) {
520                throw new IllegalArgumentException("Field must not be null");
521            }
522            long instant = fieldType.getField(getChronology()).set(getMillis(), value);
523            return withMillis(instant);
524        }
525    
526        /**
527         * Returns a copy of this datetime with the value of the specified field increased.
528         * <p>
529         * If the addition is zero or the field is null, then <code>this</code> is returned.
530         * <p>
531         * These three lines are equivalent:
532         * <pre>
533         * DateTime added = dt.withFieldAdded(DurationFieldType.years(), 6);
534         * DateTime added = dt.plusYears(6);
535         * DateTime added = dt.plus(Period.years(6));
536         * </pre>
537         * 
538         * @param fieldType  the field type to add to, not null
539         * @param amount  the amount to add
540         * @return a copy of this datetime with the field updated
541         * @throws IllegalArgumentException if the value is null or invalid
542         * @throws ArithmeticException if the new datetime exceeds the capacity of a long
543         */
544        public DateTime withFieldAdded(DurationFieldType fieldType, int amount) {
545            if (fieldType == null) {
546                throw new IllegalArgumentException("Field must not be null");
547            }
548            if (amount == 0) {
549                return this;
550            }
551            long instant = fieldType.getField(getChronology()).add(getMillis(), amount);
552            return withMillis(instant);
553        }
554    
555        //-----------------------------------------------------------------------
556        /**
557         * Returns a copy of this datetime with the specified duration added.
558         * <p>
559         * If the addition is zero, then <code>this</code> is returned.
560         * 
561         * @param durationToAdd  the duration to add to this one
562         * @param scalar  the amount of times to add, such as -1 to subtract once
563         * @return a copy of this datetime with the duration added
564         * @throws ArithmeticException if the new datetime exceeds the capacity of a long
565         */
566        public DateTime withDurationAdded(long durationToAdd, int scalar) {
567            if (durationToAdd == 0 || scalar == 0) {
568                return this;
569            }
570            long instant = getChronology().add(getMillis(), durationToAdd, scalar);
571            return withMillis(instant);
572        }
573    
574        /**
575         * Returns a copy of this datetime with the specified duration added.
576         * <p>
577         * If the addition is zero, then <code>this</code> is returned.
578         * 
579         * @param durationToAdd  the duration to add to this one, null means zero
580         * @param scalar  the amount of times to add, such as -1 to subtract once
581         * @return a copy of this datetime with the duration added
582         * @throws ArithmeticException if the new datetime exceeds the capacity of a long
583         */
584        public DateTime withDurationAdded(ReadableDuration durationToAdd, int scalar) {
585            if (durationToAdd == null || scalar == 0) {
586                return this;
587            }
588            return withDurationAdded(durationToAdd.getMillis(), scalar);
589        }
590    
591        /**
592         * Returns a copy of this datetime with the specified period added.
593         * <p>
594         * If the addition is zero, then <code>this</code> is returned.
595         * <p>
596         * This method is typically used to add multiple copies of complex
597         * period instances. Adding one field is best achieved using methods
598         * like {@link #withFieldAdded(DurationFieldType, int)}
599         * or {@link #plusYears(int)}.
600         * 
601         * @param period  the period to add to this one, null means zero
602         * @param scalar  the amount of times to add, such as -1 to subtract once
603         * @return a copy of this datetime with the period added
604         * @throws ArithmeticException if the new datetime exceeds the capacity of a long
605         */
606        public DateTime withPeriodAdded(ReadablePeriod period, int scalar) {
607            if (period == null || scalar == 0) {
608                return this;
609            }
610            long instant = getChronology().add(period, getMillis(), scalar);
611            return withMillis(instant);
612        }
613    
614        //-----------------------------------------------------------------------
615        /**
616         * Returns a copy of this datetime with the specified duration added.
617         * <p>
618         * If the amount is zero or null, then <code>this</code> is returned.
619         * This datetime instance is immutable and unaffected by this method call.
620         * 
621         * @param duration  the duration, in millis, to add to this one
622         * @return a copy of this datetime with the duration added
623         * @throws ArithmeticException if the new datetime exceeds the capacity of a long
624         */
625        public DateTime plus(long duration) {
626            return withDurationAdded(duration, 1);
627        }
628    
629        /**
630         * Returns a copy of this datetime with the specified duration added.
631         * <p>
632         * If the amount is zero or null, then <code>this</code> is returned.
633         * This datetime instance is immutable and unaffected by this method call.
634         * 
635         * @param duration  the duration to add to this one, null means zero
636         * @return a copy of this datetime with the duration added
637         * @throws ArithmeticException if the new datetime exceeds the capacity of a long
638         */
639        public DateTime plus(ReadableDuration duration) {
640            return withDurationAdded(duration, 1);
641        }
642    
643        /**
644         * Returns a copy of this datetime with the specified period added.
645         * <p>
646         * This method will add each element of the period one by one, from largest
647         * to smallest, adjusting the datetime to be accurate between each.
648         * <p>
649         * Thus, adding a period of one month and one day to 2007-03-31 will
650         * work as follows:
651         * First add one month and adjust, resulting in 2007-04-30
652         * Then add one day and adjust, resulting in 2007-05-01.
653         * <p>
654         * This method is typically used to add complex period instances.
655         * Adding one field is best achieved using methods
656         * like {@link #plusYears(int)}.
657         * <p>
658         * If the amount is zero or null, then <code>this</code> is returned.
659         * This datetime instance is immutable and unaffected by this method call.
660         * 
661         * @param period  the duration to add to this one, null means zero
662         * @return a copy of this datetime with the period added
663         * @throws ArithmeticException if the new datetime exceeds the capacity of a long
664         */
665        public DateTime plus(ReadablePeriod period) {
666            return withPeriodAdded(period, 1);
667        }
668    
669        //-----------------------------------------------------------------------
670        /**
671         * Returns a copy of this datetime plus the specified number of years.
672         * <p>
673         * The calculation will do its best to only change the year field
674         * retaining the same month of year.
675         * However, in certain circumstances, it may be necessary to alter
676         * smaller fields. For example, 2008-02-29 plus one year cannot result
677         * in 2009-02-29, so the day of month is adjusted to 2009-02-28.
678         * <p>
679         * The following three lines are identical in effect:
680         * <pre>
681         * DateTime added = dt.plusYears(6);
682         * DateTime added = dt.plus(Period.years(6));
683         * DateTime added = dt.withFieldAdded(DurationFieldType.years(), 6);
684         * </pre>
685         * <p>
686         * This datetime instance is immutable and unaffected by this method call.
687         *
688         * @param years  the amount of years to add, may be negative
689         * @return the new datetime plus the increased years
690         * @since 1.1
691         */
692        public DateTime plusYears(int years) {
693            if (years == 0) {
694                return this;
695            }
696            long instant = getChronology().years().add(getMillis(), years);
697            return withMillis(instant);
698        }
699    
700        /**
701         * Returns a copy of this datetime plus the specified number of months.
702         * <p>
703         * The calculation will do its best to only change the month field
704         * retaining the same day of month.
705         * However, in certain circumstances, it may be necessary to alter
706         * smaller fields. For example, 2007-03-31 plus one month cannot result
707         * in 2007-04-31, so the day of month is adjusted to 2007-04-30.
708         * <p>
709         * The following three lines are identical in effect:
710         * <pre>
711         * DateTime added = dt.plusMonths(6);
712         * DateTime added = dt.plus(Period.months(6));
713         * DateTime added = dt.withFieldAdded(DurationFieldType.months(), 6);
714         * </pre>
715         * <p>
716         * This datetime instance is immutable and unaffected by this method call.
717         *
718         * @param months  the amount of months to add, may be negative
719         * @return the new datetime plus the increased months
720         * @since 1.1
721         */
722        public DateTime plusMonths(int months) {
723            if (months == 0) {
724                return this;
725            }
726            long instant = getChronology().months().add(getMillis(), months);
727            return withMillis(instant);
728        }
729    
730        /**
731         * Returns a copy of this datetime plus the specified number of weeks.
732         * <p>
733         * The calculation operates as if it were adding the equivalent in days.
734         * <p>
735         * The following three lines are identical in effect:
736         * <pre>
737         * DateTime added = dt.plusWeeks(6);
738         * DateTime added = dt.plus(Period.weeks(6));
739         * DateTime added = dt.withFieldAdded(DurationFieldType.weeks(), 6);
740         * </pre>
741         * <p>
742         * This datetime instance is immutable and unaffected by this method call.
743         *
744         * @param weeks  the amount of weeks to add, may be negative
745         * @return the new datetime plus the increased weeks
746         * @since 1.1
747         */
748        public DateTime plusWeeks(int weeks) {
749            if (weeks == 0) {
750                return this;
751            }
752            long instant = getChronology().weeks().add(getMillis(), weeks);
753            return withMillis(instant);
754        }
755    
756        /**
757         * Returns a copy of this datetime plus the specified number of days.
758         * <p>
759         * The calculation will do its best to only change the day field
760         * retaining the same time of day.
761         * However, in certain circumstances, typically daylight savings cutover,
762         * it may be necessary to alter the time fields.
763         * <p>
764         * In spring an hour is typically removed. If adding one day results in
765         * the time being within the cutover then the time is adjusted to be
766         * within summer time. For example, if the cutover is from 01:59 to 03:00
767         * and the result of this method would have been 02:30, then the result
768         * will be adjusted to 03:30.
769         * <p>
770         * The following three lines are identical in effect:
771         * <pre>
772         * DateTime added = dt.plusDays(6);
773         * DateTime added = dt.plus(Period.days(6));
774         * DateTime added = dt.withFieldAdded(DurationFieldType.days(), 6);
775         * </pre>
776         * <p>
777         * This datetime instance is immutable and unaffected by this method call.
778         *
779         * @param days  the amount of days to add, may be negative
780         * @return the new datetime plus the increased days
781         * @since 1.1
782         */
783        public DateTime plusDays(int days) {
784            if (days == 0) {
785                return this;
786            }
787            long instant = getChronology().days().add(getMillis(), days);
788            return withMillis(instant);
789        }
790    
791        /**
792         * Returns a copy of this datetime plus the specified number of hours.
793         * <p>
794         * The calculation will add a duration equivalent to the number of hours
795         * expressed in milliseconds.
796         * <p>
797         * For example, if a spring daylight savings cutover is from 01:59 to 03:00
798         * then adding one hour to 01:30 will result in 03:30. This is a duration
799         * of one hour later, even though the hour field value changed from 1 to 3.
800         * <p>
801         * The following three lines are identical in effect:
802         * <pre>
803         * DateTime added = dt.plusHours(6);
804         * DateTime added = dt.plus(Period.hours(6));
805         * DateTime added = dt.withFieldAdded(DurationFieldType.hours(), 6);
806         * </pre>
807         * <p>
808         * This datetime instance is immutable and unaffected by this method call.
809         *
810         * @param hours  the amount of hours to add, may be negative
811         * @return the new datetime plus the increased hours
812         * @since 1.1
813         */
814        public DateTime plusHours(int hours) {
815            if (hours == 0) {
816                return this;
817            }
818            long instant = getChronology().hours().add(getMillis(), hours);
819            return withMillis(instant);
820        }
821    
822        /**
823         * Returns a copy of this datetime plus the specified number of minutes.
824         * <p>
825         * The calculation will add a duration equivalent to the number of minutes
826         * expressed in milliseconds.
827         * <p>
828         * The following three lines are identical in effect:
829         * <pre>
830         * DateTime added = dt.plusMinutes(6);
831         * DateTime added = dt.plus(Period.minutes(6));
832         * DateTime added = dt.withFieldAdded(DurationFieldType.minutes(), 6);
833         * </pre>
834         * <p>
835         * This datetime instance is immutable and unaffected by this method call.
836         *
837         * @param minutes  the amount of minutes to add, may be negative
838         * @return the new datetime plus the increased minutes
839         * @since 1.1
840         */
841        public DateTime plusMinutes(int minutes) {
842            if (minutes == 0) {
843                return this;
844            }
845            long instant = getChronology().minutes().add(getMillis(), minutes);
846            return withMillis(instant);
847        }
848    
849        /**
850         * Returns a copy of this datetime plus the specified number of seconds.
851         * <p>
852         * The calculation will add a duration equivalent to the number of seconds
853         * expressed in milliseconds.
854         * <p>
855         * The following three lines are identical in effect:
856         * <pre>
857         * DateTime added = dt.plusSeconds(6);
858         * DateTime added = dt.plus(Period.seconds(6));
859         * DateTime added = dt.withFieldAdded(DurationFieldType.seconds(), 6);
860         * </pre>
861         * <p>
862         * This datetime instance is immutable and unaffected by this method call.
863         *
864         * @param seconds  the amount of seconds to add, may be negative
865         * @return the new datetime plus the increased seconds
866         * @since 1.1
867         */
868        public DateTime plusSeconds(int seconds) {
869            if (seconds == 0) {
870                return this;
871            }
872            long instant = getChronology().seconds().add(getMillis(), seconds);
873            return withMillis(instant);
874        }
875    
876        /**
877         * Returns a copy of this datetime plus the specified number of millis.
878         * <p>
879         * The calculation will add a duration equivalent to the number of milliseconds.
880         * <p>
881         * The following three lines are identical in effect:
882         * <pre>
883         * DateTime added = dt.plusMillis(6);
884         * DateTime added = dt.plus(Period.millis(6));
885         * DateTime added = dt.withFieldAdded(DurationFieldType.millis(), 6);
886         * </pre>
887         * <p>
888         * This datetime instance is immutable and unaffected by this method call.
889         *
890         * @param millis  the amount of millis to add, may be negative
891         * @return the new datetime plus the increased millis
892         * @since 1.1
893         */
894        public DateTime plusMillis(int millis) {
895            if (millis == 0) {
896                return this;
897            }
898            long instant = getChronology().millis().add(getMillis(), millis);
899            return withMillis(instant);
900        }
901    
902        //-----------------------------------------------------------------------
903        /**
904         * Returns a copy of this datetime with the specified duration taken away.
905         * <p>
906         * If the amount is zero or null, then <code>this</code> is returned.
907         * This datetime instance is immutable and unaffected by this method call.
908         * 
909         * @param duration  the duration, in millis, to reduce this instant by
910         * @return a copy of this datetime with the duration taken away
911         * @throws ArithmeticException if the new datetime exceeds the capacity of a long
912         */
913        public DateTime minus(long duration) {
914            return withDurationAdded(duration, -1);
915        }
916    
917        /**
918         * Returns a copy of this datetime with the specified duration taken away.
919         * <p>
920         * If the amount is zero or null, then <code>this</code> is returned.
921         * This datetime instance is immutable and unaffected by this method call.
922         * 
923         * @param duration  the duration to reduce this instant by
924         * @return a copy of this datetime with the duration taken away
925         * @throws ArithmeticException if the new datetime exceeds the capacity of a long
926         */
927        public DateTime minus(ReadableDuration duration) {
928            return withDurationAdded(duration, -1);
929        }
930    
931        /**
932         * Returns a copy of this datetime with the specified period taken away.
933         * <p>
934         * This method will subtract each element of the period one by one, from
935         * largest to smallest, adjusting the datetime to be accurate between each.
936         * <p>
937         * Thus, subtracting a period of one month and one day from 2007-05-31 will
938         * work as follows:
939         * First subtract one month and adjust, resulting in 2007-04-30
940         * Then subtract one day and adjust, resulting in 2007-04-29.
941         * Note that the day has been adjusted by two.
942         * <p>
943         * This method is typically used to subtract complex period instances.
944         * Subtracting one field is best achieved using methods
945         * like {@link #minusYears(int)}.
946         * <p>
947         * If the amount is zero or null, then <code>this</code> is returned.
948         * This datetime instance is immutable and unaffected by this method call.
949         * 
950         * @param period  the period to reduce this instant by
951         * @return a copy of this datetime with the period taken away
952         * @throws ArithmeticException if the new datetime exceeds the capacity of a long
953         */
954        public DateTime minus(ReadablePeriod period) {
955            return withPeriodAdded(period, -1);
956        }
957    
958        //-----------------------------------------------------------------------
959        /**
960         * Returns a copy of this datetime minus the specified number of years.
961         * <p>
962         * The calculation will do its best to only change the year field
963         * retaining the same month of year.
964         * However, in certain circumstances, it may be necessary to alter
965         * smaller fields. For example, 2008-02-29 minus one year cannot result
966         * in 2007-02-29, so the day of month is adjusted to 2007-02-28.
967         * <p>
968         * The following three lines are identical in effect:
969         * <pre>
970         * DateTime subtracted = dt.minusYears(6);
971         * DateTime subtracted = dt.minus(Period.years(6));
972         * DateTime subtracted = dt.withFieldAdded(DurationFieldType.years(), -6);
973         * </pre>
974         * <p>
975         * This datetime instance is immutable and unaffected by this method call.
976         *
977         * @param years  the amount of years to subtract, may be negative
978         * @return the new datetime minus the increased years
979         * @since 1.1
980         */
981        public DateTime minusYears(int years) {
982            if (years == 0) {
983                return this;
984            }
985            long instant = getChronology().years().subtract(getMillis(), years);
986            return withMillis(instant);
987        }
988    
989        /**
990         * Returns a copy of this datetime minus the specified number of months.
991         * <p>
992         * The calculation will do its best to only change the month field
993         * retaining the same day of month.
994         * However, in certain circumstances, it may be necessary to alter
995         * smaller fields. For example, 2007-05-31 minus one month cannot result
996         * in 2007-04-31, so the day of month is adjusted to 2007-04-30.
997         * <p>
998         * The following three lines are identical in effect:
999         * <pre>
1000         * DateTime subtracted = dt.minusMonths(6);
1001         * DateTime subtracted = dt.minus(Period.months(6));
1002         * DateTime subtracted = dt.withFieldAdded(DurationFieldType.months(), -6);
1003         * </pre>
1004         * <p>
1005         * This datetime instance is immutable and unaffected by this method call.
1006         *
1007         * @param months  the amount of months to subtract, may be negative
1008         * @return the new datetime minus the increased months
1009         * @since 1.1
1010         */
1011        public DateTime minusMonths(int months) {
1012            if (months == 0) {
1013                return this;
1014            }
1015            long instant = getChronology().months().subtract(getMillis(), months);
1016            return withMillis(instant);
1017        }
1018    
1019        /**
1020         * Returns a copy of this datetime minus the specified number of weeks.
1021         * <p>
1022         * The calculation operates as if it were subtracting the equivalent in days.
1023         * <p>
1024         * The following three lines are identical in effect:
1025         * <pre>
1026         * DateTime subtracted = dt.minusWeeks(6);
1027         * DateTime subtracted = dt.minus(Period.weeks(6));
1028         * DateTime subtracted = dt.withFieldAdded(DurationFieldType.weeks(), -6);
1029         * </pre>
1030         * <p>
1031         * This datetime instance is immutable and unaffected by this method call.
1032         *
1033         * @param weeks  the amount of weeks to subtract, may be negative
1034         * @return the new datetime minus the increased weeks
1035         * @since 1.1
1036         */
1037        public DateTime minusWeeks(int weeks) {
1038            if (weeks == 0) {
1039                return this;
1040            }
1041            long instant = getChronology().weeks().subtract(getMillis(), weeks);
1042            return withMillis(instant);
1043        }
1044    
1045        /**
1046         * Returns a copy of this datetime minus the specified number of days.
1047         * <p>
1048         * The calculation will do its best to only change the day field
1049         * retaining the same time of day.
1050         * However, in certain circumstances, typically daylight savings cutover,
1051         * it may be necessary to alter the time fields.
1052         * <p>
1053         * In spring an hour is typically removed. If subtracting one day results
1054         * in the time being within the cutover then the time is adjusted to be
1055         * within summer time. For example, if the cutover is from 01:59 to 03:00
1056         * and the result of this method would have been 02:30, then the result
1057         * will be adjusted to 03:30.
1058         * <p>
1059         * The following three lines are identical in effect:
1060         * <pre>
1061         * DateTime subtracted = dt.minusDays(6);
1062         * DateTime subtracted = dt.minus(Period.days(6));
1063         * DateTime subtracted = dt.withFieldAdded(DurationFieldType.days(), -6);
1064         * </pre>
1065         * <p>
1066         * This datetime instance is immutable and unaffected by this method call.
1067         *
1068         * @param days  the amount of days to subtract, may be negative
1069         * @return the new datetime minus the increased days
1070         * @since 1.1
1071         */
1072        public DateTime minusDays(int days) {
1073            if (days == 0) {
1074                return this;
1075            }
1076            long instant = getChronology().days().subtract(getMillis(), days);
1077            return withMillis(instant);
1078        }
1079    
1080        /**
1081         * Returns a copy of this datetime minus the specified number of hours.
1082         * <p>
1083         * The calculation will subtract a duration equivalent to the number of
1084         * hours expressed in milliseconds.
1085         * <p>
1086         * For example, if a spring daylight savings cutover is from 01:59 to 03:00
1087         * then subtracting one hour from 03:30 will result in 01:30. This is a
1088         * duration of one hour earlier, even though the hour field value changed
1089         * from 3 to 1.
1090         * <p>
1091         * The following three lines are identical in effect:
1092         * <pre>
1093         * DateTime subtracted = dt.minusHours(6);
1094         * DateTime subtracted = dt.minus(Period.hours(6));
1095         * DateTime subtracted = dt.withFieldAdded(DurationFieldType.hours(), -6);
1096         * </pre>
1097         * <p>
1098         * This datetime instance is immutable and unaffected by this method call.
1099         *
1100         * @param hours  the amount of hours to subtract, may be negative
1101         * @return the new datetime minus the increased hours
1102         * @since 1.1
1103         */
1104        public DateTime minusHours(int hours) {
1105            if (hours == 0) {
1106                return this;
1107            }
1108            long instant = getChronology().hours().subtract(getMillis(), hours);
1109            return withMillis(instant);
1110        }
1111    
1112        /**
1113         * Returns a copy of this datetime minus the specified number of minutes.
1114         * <p>
1115         * The calculation will subtract a duration equivalent to the number of
1116         * minutes expressed in milliseconds.
1117         * <p>
1118         * The following three lines are identical in effect:
1119         * <pre>
1120         * DateTime subtracted = dt.minusMinutes(6);
1121         * DateTime subtracted = dt.minus(Period.minutes(6));
1122         * DateTime subtracted = dt.withFieldAdded(DurationFieldType.minutes(), -6);
1123         * </pre>
1124         * <p>
1125         * This datetime instance is immutable and unaffected by this method call.
1126         *
1127         * @param minutes  the amount of minutes to subtract, may be negative
1128         * @return the new datetime minus the increased minutes
1129         * @since 1.1
1130         */
1131        public DateTime minusMinutes(int minutes) {
1132            if (minutes == 0) {
1133                return this;
1134            }
1135            long instant = getChronology().minutes().subtract(getMillis(), minutes);
1136            return withMillis(instant);
1137        }
1138    
1139        /**
1140         * Returns a copy of this datetime minus the specified number of seconds.
1141         * <p>
1142         * The calculation will subtract a duration equivalent to the number of
1143         * seconds expressed in milliseconds.
1144         * <p>
1145         * The following three lines are identical in effect:
1146         * <pre>
1147         * DateTime subtracted = dt.minusSeconds(6);
1148         * DateTime subtracted = dt.minus(Period.seconds(6));
1149         * DateTime subtracted = dt.withFieldAdded(DurationFieldType.seconds(), -6);
1150         * </pre>
1151         * <p>
1152         * This datetime instance is immutable and unaffected by this method call.
1153         *
1154         * @param seconds  the amount of seconds to subtract, may be negative
1155         * @return the new datetime minus the increased seconds
1156         * @since 1.1
1157         */
1158        public DateTime minusSeconds(int seconds) {
1159            if (seconds == 0) {
1160                return this;
1161            }
1162            long instant = getChronology().seconds().subtract(getMillis(), seconds);
1163            return withMillis(instant);
1164        }
1165    
1166        /**
1167         * Returns a copy of this datetime minus the specified number of millis.
1168         * <p>
1169         * The calculation will subtract a duration equivalent to the number of
1170         * milliseconds.
1171         * <p>
1172         * The following three lines are identical in effect:
1173         * <pre>
1174         * DateTime subtracted = dt.minusMillis(6);
1175         * DateTime subtracted = dt.minus(Period.millis(6));
1176         * DateTime subtracted = dt.withFieldAdded(DurationFieldType.millis(), -6);
1177         * </pre>
1178         * <p>
1179         * This datetime instance is immutable and unaffected by this method call.
1180         *
1181         * @param millis  the amount of millis to subtract, may be negative
1182         * @return the new datetime minus the increased millis
1183         * @since 1.1
1184         */
1185        public DateTime minusMillis(int millis) {
1186            if (millis == 0) {
1187                return this;
1188            }
1189            long instant = getChronology().millis().subtract(getMillis(), millis);
1190            return withMillis(instant);
1191        }
1192    
1193        //-----------------------------------------------------------------------
1194        /**
1195         * Gets the property object for the specified type, which contains many useful methods.
1196         *
1197         * @param type  the field type to get the chronology for
1198         * @return the property object
1199         * @throws IllegalArgumentException if the field is null or unsupported
1200         */
1201        public Property property(DateTimeFieldType type) {
1202            if (type == null) {
1203                throw new IllegalArgumentException("The DateTimeFieldType must not be null");
1204            }
1205            DateTimeField field = type.getField(getChronology());
1206            if (field.isSupported() == false) {
1207                throw new IllegalArgumentException("Field '" + type + "' is not supported");
1208            }
1209            return new Property(this, field);
1210        }
1211    
1212        //-----------------------------------------------------------------------
1213        /**
1214         * Converts this object to a <code>DateMidnight</code> using the
1215         * same millis and chronology.
1216         * 
1217         * @return a DateMidnight using the same millis and chronology
1218         */
1219        public DateMidnight toDateMidnight() {
1220            return new DateMidnight(getMillis(), getChronology());
1221        }
1222    
1223        /**
1224         * Converts this object to a <code>YearMonthDay</code> using the
1225         * same millis and chronology.
1226         * 
1227         * @return a YearMonthDay using the same millis and chronology
1228         * @deprecated Use LocalDate instead of YearMonthDay
1229         */
1230        public YearMonthDay toYearMonthDay() {
1231            return new YearMonthDay(getMillis(), getChronology());
1232        }
1233    
1234        /**
1235         * Converts this object to a <code>TimeOfDay</code> using the
1236         * same millis and chronology.
1237         * 
1238         * @return a TimeOfDay using the same millis and chronology
1239         * @deprecated Use LocalTime instead of TimeOfDay
1240         */
1241        public TimeOfDay toTimeOfDay() {
1242            return new TimeOfDay(getMillis(), getChronology());
1243        }
1244    
1245        /**
1246         * Converts this object to a <code>LocalDateTime</code> with
1247         * the same datetime and chronology.
1248         *
1249         * @return a LocalDateTime with the same datetime and chronology
1250         * @since 1.3
1251         */
1252        public LocalDateTime toLocalDateTime() {
1253            return new LocalDateTime(getMillis(), getChronology());
1254        }
1255    
1256        /**
1257         * Converts this object to a <code>LocalDate</code> with the
1258         * same date and chronology.
1259         *
1260         * @return a LocalDate with the same date and chronology
1261         * @since 1.3
1262         */
1263        public LocalDate toLocalDate() {
1264            return new LocalDate(getMillis(), getChronology());
1265        }
1266    
1267        /**
1268         * Converts this object to a <code>LocalTime</code> with the
1269         * same time and chronology.
1270         *
1271         * @return a LocalTime with the same time and chronology
1272         * @since 1.3
1273         */
1274        public LocalTime toLocalTime() {
1275            return new LocalTime(getMillis(), getChronology());
1276        }
1277    
1278        //-----------------------------------------------------------------------
1279        /**
1280         * Returns a copy of this datetime with the era field updated.
1281         * <p>
1282         * DateTime is immutable, so there are no set methods.
1283         * Instead, this method returns a new instance with the value of
1284         * era changed.
1285         *
1286         * @param era  the era to set
1287         * @return a copy of this object with the field set
1288         * @throws IllegalArgumentException if the value is invalid
1289         * @since 1.3
1290         */
1291        public DateTime withEra(int era) {
1292            return withMillis(getChronology().era().set(getMillis(), era));
1293        }
1294    
1295        /**
1296         * Returns a copy of this datetime with the century of era field updated.
1297         * <p>
1298         * DateTime is immutable, so there are no set methods.
1299         * Instead, this method returns a new instance with the value of
1300         * century of era changed.
1301         *
1302         * @param centuryOfEra  the centurey of era to set
1303         * @return a copy of this object with the field set
1304         * @throws IllegalArgumentException if the value is invalid
1305         * @since 1.3
1306         */
1307        public DateTime withCenturyOfEra(int centuryOfEra) {
1308            return withMillis(getChronology().centuryOfEra().set(getMillis(), centuryOfEra));
1309        }
1310    
1311        /**
1312         * Returns a copy of this datetime with the year of era field updated.
1313         * <p>
1314         * DateTime is immutable, so there are no set methods.
1315         * Instead, this method returns a new instance with the value of
1316         * year of era changed.
1317         *
1318         * @param yearOfEra  the year of era to set
1319         * @return a copy of this object with the field set
1320         * @throws IllegalArgumentException if the value is invalid
1321         * @since 1.3
1322         */
1323        public DateTime withYearOfEra(int yearOfEra) {
1324            return withMillis(getChronology().yearOfEra().set(getMillis(), yearOfEra));
1325        }
1326    
1327        /**
1328         * Returns a copy of this datetime with the year of century field updated.
1329         * <p>
1330         * DateTime is immutable, so there are no set methods.
1331         * Instead, this method returns a new instance with the value of
1332         * year of century changed.
1333         *
1334         * @param yearOfCentury  the year of century to set
1335         * @return a copy of this object with the field set
1336         * @throws IllegalArgumentException if the value is invalid
1337         * @since 1.3
1338         */
1339        public DateTime withYearOfCentury(int yearOfCentury) {
1340            return withMillis(getChronology().yearOfCentury().set(getMillis(), yearOfCentury));
1341        }
1342    
1343        /**
1344         * Returns a copy of this datetime with the year field updated.
1345         * <p>
1346         * DateTime is immutable, so there are no set methods.
1347         * Instead, this method returns a new instance with the value of
1348         * year changed.
1349         *
1350         * @param year  the year to set
1351         * @return a copy of this object with the field set
1352         * @throws IllegalArgumentException if the value is invalid
1353         * @since 1.3
1354         */
1355        public DateTime withYear(int year) {
1356            return withMillis(getChronology().year().set(getMillis(), year));
1357        }
1358    
1359        /**
1360         * Returns a copy of this datetime with the weekyear field updated.
1361         * <p>
1362         * DateTime is immutable, so there are no set methods.
1363         * Instead, this method returns a new instance with the value of
1364         * weekyear changed.
1365         *
1366         * @param weekyear  the weekyear to set
1367         * @return a copy of this object with the field set
1368         * @throws IllegalArgumentException if the value is invalid
1369         * @since 1.3
1370         */
1371        public DateTime withWeekyear(int weekyear) {
1372            return withMillis(getChronology().weekyear().set(getMillis(), weekyear));
1373        }
1374    
1375        /**
1376         * Returns a copy of this datetime with the month of year field updated.
1377         * <p>
1378         * DateTime is immutable, so there are no set methods.
1379         * Instead, this method returns a new instance with the value of
1380         * month of year changed.
1381         *
1382         * @param monthOfYear  the month of year to set
1383         * @return a copy of this object with the field set
1384         * @throws IllegalArgumentException if the value is invalid
1385         * @since 1.3
1386         */
1387        public DateTime withMonthOfYear(int monthOfYear) {
1388            return withMillis(getChronology().monthOfYear().set(getMillis(), monthOfYear));
1389        }
1390    
1391        /**
1392         * Returns a copy of this datetime with the week of weekyear field updated.
1393         * <p>
1394         * DateTime is immutable, so there are no set methods.
1395         * Instead, this method returns a new instance with the value of
1396         * week of weekyear changed.
1397         *
1398         * @param weekOfWeekyear  the week of weekyear to set
1399         * @return a copy of this object with the field set
1400         * @throws IllegalArgumentException if the value is invalid
1401         * @since 1.3
1402         */
1403        public DateTime withWeekOfWeekyear(int weekOfWeekyear) {
1404            return withMillis(getChronology().weekOfWeekyear().set(getMillis(), weekOfWeekyear));
1405        }
1406    
1407        /**
1408         * Returns a copy of this datetime with the day of year field updated.
1409         * <p>
1410         * DateTime is immutable, so there are no set methods.
1411         * Instead, this method returns a new instance with the value of
1412         * day of year changed.
1413         *
1414         * @param dayOfYear  the day of year to set
1415         * @return a copy of this object with the field set
1416         * @throws IllegalArgumentException if the value is invalid
1417         * @since 1.3
1418         */
1419        public DateTime withDayOfYear(int dayOfYear) {
1420            return withMillis(getChronology().dayOfYear().set(getMillis(), dayOfYear));
1421        }
1422    
1423        /**
1424         * Returns a copy of this datetime with the day of month field updated.
1425         * <p>
1426         * DateTime is immutable, so there are no set methods.
1427         * Instead, this method returns a new instance with the value of
1428         * day of month changed.
1429         *
1430         * @param dayOfMonth  the day of month to set
1431         * @return a copy of this object with the field set
1432         * @throws IllegalArgumentException if the value is invalid
1433         * @since 1.3
1434         */
1435        public DateTime withDayOfMonth(int dayOfMonth) {
1436            return withMillis(getChronology().dayOfMonth().set(getMillis(), dayOfMonth));
1437        }
1438    
1439        /**
1440         * Returns a copy of this datetime with the day of week field updated.
1441         * <p>
1442         * DateTime is immutable, so there are no set methods.
1443         * Instead, this method returns a new instance with the value of
1444         * day of week changed.
1445         *
1446         * @param dayOfWeek  the day of week to set
1447         * @return a copy of this object with the field set
1448         * @throws IllegalArgumentException if the value is invalid
1449         * @since 1.3
1450         */
1451        public DateTime withDayOfWeek(int dayOfWeek) {
1452            return withMillis(getChronology().dayOfWeek().set(getMillis(), dayOfWeek));
1453        }
1454    
1455        //-----------------------------------------------------------------------
1456        /**
1457         * Returns a copy of this datetime with the hour of day field updated.
1458         * <p>
1459         * DateTime is immutable, so there are no set methods.
1460         * Instead, this method returns a new instance with the value of
1461         * hour of day changed.
1462         *
1463         * @param hour  the hour of day to set
1464         * @return a copy of this object with the field set
1465         * @throws IllegalArgumentException if the value is invalid
1466         * @since 1.3
1467         */
1468        public DateTime withHourOfDay(int hour) {
1469            return withMillis(getChronology().hourOfDay().set(getMillis(), hour));
1470        }
1471    
1472        /**
1473         * Returns a copy of this datetime with the minute of hour updated.
1474         * <p>
1475         * DateTime is immutable, so there are no set methods.
1476         * Instead, this method returns a new instance with the value of
1477         * minute of hour changed.
1478         *
1479         * @param minute  the minute of hour to set
1480         * @return a copy of this object with the field set
1481         * @throws IllegalArgumentException if the value is invalid
1482         * @since 1.3
1483         */
1484        public DateTime withMinuteOfHour(int minute) {
1485            return withMillis(getChronology().minuteOfHour().set(getMillis(), minute));
1486        }
1487    
1488        /**
1489         * Returns a copy of this datetime with the second of minute field updated.
1490         * <p>
1491         * DateTime is immutable, so there are no set methods.
1492         * Instead, this method returns a new instance with the value of
1493         * second of minute changed.
1494         *
1495         * @param second  the second of minute to set
1496         * @return a copy of this object with the field set
1497         * @throws IllegalArgumentException if the value is invalid
1498         * @since 1.3
1499         */
1500        public DateTime withSecondOfMinute(int second) {
1501            return withMillis(getChronology().secondOfMinute().set(getMillis(), second));
1502        }
1503    
1504        /**
1505         * Returns a copy of this datetime with the millis of second field updated.
1506         * <p>
1507         * DateTime is immutable, so there are no set methods.
1508         * Instead, this method returns a new instance with the value of
1509         * millis of second changed.
1510         *
1511         * @param millis  the millis of second to set
1512         * @return a copy of this object with the field set
1513         * @throws IllegalArgumentException if the value is invalid
1514         * @since 1.3
1515         */
1516        public DateTime withMillisOfSecond(int millis) {
1517            return withMillis(getChronology().millisOfSecond().set(getMillis(), millis));
1518        }
1519    
1520        /**
1521         * Returns a copy of this datetime with the millis of day field updated.
1522         * <p>
1523         * DateTime is immutable, so there are no set methods.
1524         * Instead, this method returns a new instance with the value of
1525         * millis of day changed.
1526         *
1527         * @param millis  the millis of day to set
1528         * @return a copy of this object with the field set
1529         * @throws IllegalArgumentException if the value is invalid
1530         * @since 1.3
1531         */
1532        public DateTime withMillisOfDay(int millis) {
1533            return withMillis(getChronology().millisOfDay().set(getMillis(), millis));
1534        }
1535    
1536        // Date properties
1537        //-----------------------------------------------------------------------
1538        /**
1539         * Get the era property which provides access to advanced functionality.
1540         * 
1541         * @return the era property
1542         */
1543        public Property era() {
1544            return new Property(this, getChronology().era());
1545        }
1546    
1547        /**
1548         * Get the century of era property which provides access to advanced functionality.
1549         * 
1550         * @return the year of era property
1551         */
1552        public Property centuryOfEra() {
1553            return new Property(this, getChronology().centuryOfEra());
1554        }
1555    
1556        /**
1557         * Get the year of century property which provides access to advanced functionality.
1558         * 
1559         * @return the year of era property
1560         */
1561        public Property yearOfCentury() {
1562            return new Property(this, getChronology().yearOfCentury());
1563        }
1564    
1565        /**
1566         * Get the year of era property which provides access to advanced functionality.
1567         * 
1568         * @return the year of era property
1569         */
1570        public Property yearOfEra() {
1571            return new Property(this, getChronology().yearOfEra());
1572        }
1573    
1574        /**
1575         * Get the year property which provides access to advanced functionality.
1576         * 
1577         * @return the year property
1578         */
1579        public Property year() {
1580            return new Property(this, getChronology().year());
1581        }
1582    
1583        /**
1584         * Get the year of a week based year property which provides access to advanced functionality.
1585         * 
1586         * @return the year of a week based year property
1587         */
1588        public Property weekyear() {
1589            return new Property(this, getChronology().weekyear());
1590        }
1591    
1592        /**
1593         * Get the month of year property which provides access to advanced functionality.
1594         * 
1595         * @return the month of year property
1596         */
1597        public Property monthOfYear() {
1598            return new Property(this, getChronology().monthOfYear());
1599        }
1600    
1601        /**
1602         * Get the week of a week based year property which provides access to advanced functionality.
1603         * 
1604         * @return the week of a week based year property
1605         */
1606        public Property weekOfWeekyear() {
1607            return new Property(this, getChronology().weekOfWeekyear());
1608        }
1609    
1610        /**
1611         * Get the day of year property which provides access to advanced functionality.
1612         * 
1613         * @return the day of year property
1614         */
1615        public Property dayOfYear() {
1616            return new Property(this, getChronology().dayOfYear());
1617        }
1618    
1619        /**
1620         * Get the day of month property which provides access to advanced functionality.
1621         * 
1622         * @return the day of month property
1623         */
1624        public Property dayOfMonth() {
1625            return new Property(this, getChronology().dayOfMonth());
1626        }
1627    
1628        /**
1629         * Get the day of week property which provides access to advanced functionality.
1630         * 
1631         * @return the day of week property
1632         */
1633        public Property dayOfWeek() {
1634            return new Property(this, getChronology().dayOfWeek());
1635        }
1636    
1637        // Time properties
1638        //-----------------------------------------------------------------------
1639        /**
1640         * Get the hour of day field property which provides access to advanced functionality.
1641         * 
1642         * @return the hour of day property
1643         */
1644        public Property hourOfDay() {
1645            return new Property(this, getChronology().hourOfDay());
1646        }
1647    
1648        /**
1649         * Get the minute of day property which provides access to advanced functionality.
1650         * 
1651         * @return the minute of day property
1652         */
1653        public Property minuteOfDay() {
1654            return new Property(this, getChronology().minuteOfDay());
1655        }
1656    
1657        /**
1658         * Get the minute of hour field property which provides access to advanced functionality.
1659         * 
1660         * @return the minute of hour property
1661         */
1662        public Property minuteOfHour() {
1663            return new Property(this, getChronology().minuteOfHour());
1664        }
1665    
1666        /**
1667         * Get the second of day property which provides access to advanced functionality.
1668         * 
1669         * @return the second of day property
1670         */
1671        public Property secondOfDay() {
1672            return new Property(this, getChronology().secondOfDay());
1673        }
1674    
1675        /**
1676         * Get the second of minute field property which provides access to advanced functionality.
1677         * 
1678         * @return the second of minute property
1679         */
1680        public Property secondOfMinute() {
1681            return new Property(this, getChronology().secondOfMinute());
1682        }
1683    
1684        /**
1685         * Get the millis of day property which provides access to advanced functionality.
1686         * 
1687         * @return the millis of day property
1688         */
1689        public Property millisOfDay() {
1690            return new Property(this, getChronology().millisOfDay());
1691        }
1692    
1693        /**
1694         * Get the millis of second property which provides access to advanced functionality.
1695         * 
1696         * @return the millis of second property
1697         */
1698        public Property millisOfSecond() {
1699            return new Property(this, getChronology().millisOfSecond());
1700        }
1701    
1702        //-----------------------------------------------------------------------
1703        /**
1704         * DateTime.Property binds a DateTime to a DateTimeField allowing powerful
1705         * datetime functionality to be easily accessed.
1706         * <p>
1707         * The simplest use of this class is as an alternative get method, here used to
1708         * get the year '1972' (as an int) and the month 'December' (as a String).
1709         * <pre>
1710         * DateTime dt = new DateTime(1972, 12, 3, 0, 0, 0, 0);
1711         * int year = dt.year().get();
1712         * String monthStr = dt.month().getAsText();
1713         * </pre>
1714         * <p>
1715         * Methods are also provided that allow date modification. These return new instances
1716         * of DateTime - they do not modify the original. The example below yields two
1717         * independent immutable date objects 20 years apart.
1718         * <pre>
1719         * DateTime dt = new DateTime(1972, 12, 3, 0, 0, 0, 0);
1720         * DateTime dt20 = dt.year().addToCopy(20);
1721         * </pre>
1722         * Serious modification of dates (ie. more than just changing one or two fields)
1723         * should use the {@link org.joda.time.MutableDateTime MutableDateTime} class.
1724         * <p>
1725         * DateTime.Propery itself is thread-safe and immutable, as well as the
1726         * DateTime being operated on.
1727         *
1728         * @author Stephen Colebourne
1729         * @author Brian S O'Neill
1730         * @since 1.0
1731         */
1732        public static final class Property extends AbstractReadableInstantFieldProperty {
1733            
1734            /** Serialization version */
1735            private static final long serialVersionUID = -6983323811635733510L;
1736            
1737            /** The instant this property is working against */
1738            private DateTime iInstant;
1739            /** The field this property is working against */
1740            private DateTimeField iField;
1741            
1742            /**
1743             * Constructor.
1744             * 
1745             * @param instant  the instant to set
1746             * @param field  the field to use
1747             */
1748            Property(DateTime instant, DateTimeField field) {
1749                super();
1750                iInstant = instant;
1751                iField = field;
1752            }
1753            
1754            /**
1755             * Writes the property in a safe serialization format.
1756             */
1757            private void writeObject(ObjectOutputStream oos) throws IOException {
1758                oos.writeObject(iInstant);
1759                oos.writeObject(iField.getType());
1760            }
1761    
1762            /**
1763             * Reads the property from a safe serialization format.
1764             */
1765            private void readObject(ObjectInputStream oos) throws IOException, ClassNotFoundException {
1766                iInstant = (DateTime) oos.readObject();
1767                DateTimeFieldType type = (DateTimeFieldType) oos.readObject();
1768                iField = type.getField(iInstant.getChronology());
1769            }
1770    
1771            //-----------------------------------------------------------------------
1772            /**
1773             * Gets the field being used.
1774             * 
1775             * @return the field
1776             */
1777            public DateTimeField getField() {
1778                return iField;
1779            }
1780            
1781            /**
1782             * Gets the milliseconds of the datetime that this property is linked to.
1783             * 
1784             * @return the milliseconds
1785             */
1786            protected long getMillis() {
1787                return iInstant.getMillis();
1788            }
1789            
1790            /**
1791             * Gets the chronology of the datetime that this property is linked to.
1792             * 
1793             * @return the chronology
1794             * @since 1.4
1795             */
1796            protected Chronology getChronology() {
1797                return iInstant.getChronology();
1798            }
1799            
1800            /**
1801             * Gets the datetime being used.
1802             * 
1803             * @return the datetime
1804             */
1805            public DateTime getDateTime() {
1806                return iInstant;
1807            }
1808            
1809            //-----------------------------------------------------------------------
1810            /**
1811             * Adds to this field in a copy of this DateTime.
1812             * <p>
1813             * The DateTime attached to this property is unchanged by this call.
1814             * This operation is faster than converting a DateTime to a MutableDateTime
1815             * and back again when setting one field. When setting multiple fields,
1816             * it is generally quicker to make the conversion to MutableDateTime.
1817             * 
1818             * @param value  the value to add to the field in the copy
1819             * @return a copy of the DateTime with the field value changed
1820             * @throws IllegalArgumentException if the value isn't valid
1821             */
1822            public DateTime addToCopy(int value) {
1823                return iInstant.withMillis(iField.add(iInstant.getMillis(), value));
1824            }
1825            
1826            /**
1827             * Adds to this field in a copy of this DateTime.
1828             * <p>
1829             * The DateTime attached to this property is unchanged by this call.
1830             * This operation is faster than converting a DateTime to a MutableDateTime
1831             * and back again when setting one field. When setting multiple fields,
1832             * it is generally quicker to make the conversion to MutableDateTime.
1833             * 
1834             * @param value  the value to add to the field in the copy
1835             * @return a copy of the DateTime with the field value changed
1836             * @throws IllegalArgumentException if the value isn't valid
1837             */
1838            public DateTime addToCopy(long value) {
1839                return iInstant.withMillis(iField.add(iInstant.getMillis(), value));
1840            }
1841            
1842            /**
1843             * Adds to this field, possibly wrapped, in a copy of this DateTime.
1844             * A wrapped operation only changes this field.
1845             * Thus 31st January addWrapField one day goes to the 1st January.
1846             * <p>
1847             * The DateTime attached to this property is unchanged by this call.
1848             * This operation is faster than converting a DateTime to a MutableDateTime
1849             * and back again when setting one field. When setting multiple fields,
1850             * it is generally quicker to make the conversion to MutableDateTime.
1851             * 
1852             * @param value  the value to add to the field in the copy
1853             * @return a copy of the DateTime with the field value changed
1854             * @throws IllegalArgumentException if the value isn't valid
1855             */
1856            public DateTime addWrapFieldToCopy(int value) {
1857                return iInstant.withMillis(iField.addWrapField(iInstant.getMillis(), value));
1858            }
1859            
1860            //-----------------------------------------------------------------------
1861            /**
1862             * Sets this field in a copy of the DateTime.
1863             * <p>
1864             * The DateTime attached to this property is unchanged by this call.
1865             * This operation is faster than converting a DateTime to a MutableDateTime
1866             * and back again when setting one field. When setting multiple fields,
1867             * it is generally quicker to make the conversion to MutableDateTime.
1868             * 
1869             * @param value  the value to set the field in the copy to
1870             * @return a copy of the DateTime with the field value changed
1871             * @throws IllegalArgumentException if the value isn't valid
1872             */
1873            public DateTime setCopy(int value) {
1874                return iInstant.withMillis(iField.set(iInstant.getMillis(), value));
1875            }
1876            
1877            /**
1878             * Sets this field in a copy of the DateTime to a parsed text value.
1879             * <p>
1880             * The DateTime attached to this property is unchanged by this call.
1881             * This operation is faster than converting a DateTime to a MutableDateTime
1882             * and back again when setting one field. When setting multiple fields,
1883             * it is generally quicker to make the conversion to MutableDateTime.
1884             * 
1885             * @param text  the text value to set
1886             * @param locale  optional locale to use for selecting a text symbol
1887             * @return a copy of the DateTime with the field value changed
1888             * @throws IllegalArgumentException if the text value isn't valid
1889             */
1890            public DateTime setCopy(String text, Locale locale) {
1891                return iInstant.withMillis(iField.set(iInstant.getMillis(), text, locale));
1892            }
1893            
1894            /**
1895             * Sets this field in a copy of the DateTime to a parsed text value.
1896             * <p>
1897             * The DateTime attached to this property is unchanged by this call.
1898             * This operation is faster than converting a DateTime to a MutableDateTime
1899             * and back again when setting one field. When setting multiple fields,
1900             * it is generally quicker to make the conversion to MutableDateTime.
1901             * 
1902             * @param text  the text value to set
1903             * @return a copy of the DateTime with the field value changed
1904             * @throws IllegalArgumentException if the text value isn't valid
1905             */
1906            public DateTime setCopy(String text) {
1907                return setCopy(text, null);
1908            }
1909            
1910            //-----------------------------------------------------------------------
1911            /**
1912             * Returns a new DateTime with this field set to the maximum value
1913             * for this field.
1914             * <p>
1915             * This operation is useful for obtaining a DateTime on the last day
1916             * of the month, as month lengths vary.
1917             * <pre>
1918             * DateTime lastDayOfMonth = dt.dayOfMonth().withMaximumValue();
1919             * </pre>
1920             * <p>
1921             * The DateTime attached to this property is unchanged by this call.
1922             *
1923             * @return a copy of the DateTime with this field set to its maximum
1924             * @since 1.2
1925             */
1926            public DateTime withMaximumValue() {
1927                return setCopy(getMaximumValue());
1928            }
1929            
1930            /**
1931             * Returns a new DateTime with this field set to the minimum value
1932             * for this field.
1933             * <p>
1934             * The DateTime attached to this property is unchanged by this call.
1935             *
1936             * @return a copy of the DateTime with this field set to its minimum
1937             * @since 1.2
1938             */
1939            public DateTime withMinimumValue() {
1940                return setCopy(getMinimumValue());
1941            }
1942            
1943            //-----------------------------------------------------------------------
1944            /**
1945             * Rounds to the lowest whole unit of this field on a copy of this DateTime.
1946             *
1947             * @return a copy of the DateTime with the field value changed
1948             */
1949            public DateTime roundFloorCopy() {
1950                return iInstant.withMillis(iField.roundFloor(iInstant.getMillis()));
1951            }
1952            
1953            /**
1954             * Rounds to the highest whole unit of this field on a copy of this DateTime.
1955             *
1956             * @return a copy of the DateTime with the field value changed
1957             */
1958            public DateTime roundCeilingCopy() {
1959                return iInstant.withMillis(iField.roundCeiling(iInstant.getMillis()));
1960            }
1961            
1962            /**
1963             * Rounds to the nearest whole unit of this field on a copy of this DateTime,
1964             * favoring the floor if halfway.
1965             *
1966             * @return a copy of the DateTime with the field value changed
1967             */
1968            public DateTime roundHalfFloorCopy() {
1969                return iInstant.withMillis(iField.roundHalfFloor(iInstant.getMillis()));
1970            }
1971            
1972            /**
1973             * Rounds to the nearest whole unit of this field on a copy of this DateTime,
1974             * favoring the ceiling if halfway.
1975             *
1976             * @return a copy of the DateTime with the field value changed
1977             */
1978            public DateTime roundHalfCeilingCopy() {
1979                return iInstant.withMillis(iField.roundHalfCeiling(iInstant.getMillis()));
1980            }
1981            
1982            /**
1983             * Rounds to the nearest whole unit of this field on a copy of this
1984             * DateTime.  If halfway, the ceiling is favored over the floor only if
1985             * it makes this field's value even.
1986             *
1987             * @return a copy of the DateTime with the field value changed
1988             */
1989            public DateTime roundHalfEvenCopy() {
1990                return iInstant.withMillis(iField.roundHalfEven(iInstant.getMillis()));
1991            }
1992        }
1993    
1994    }