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