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