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 */
016package org.joda.time;
017
018import java.io.IOException;
019import java.io.ObjectInputStream;
020import java.io.ObjectOutputStream;
021import java.io.Serializable;
022import java.util.Locale;
023
024import org.joda.convert.FromString;
025import org.joda.time.base.BaseDateTime;
026import org.joda.time.chrono.ISOChronology;
027import org.joda.time.field.AbstractReadableInstantFieldProperty;
028import org.joda.time.format.DateTimeFormatter;
029import 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 */
073public 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}