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     */
016    package org.joda.time;
017    
018    import java.io.IOException;
019    import java.io.ObjectInputStream;
020    import java.io.ObjectOutputStream;
021    import java.io.Serializable;
022    import java.util.Calendar;
023    import java.util.Date;
024    import java.util.Locale;
025    
026    import org.joda.time.base.BaseLocal;
027    import org.joda.time.chrono.ISOChronology;
028    import org.joda.time.convert.ConverterManager;
029    import org.joda.time.convert.PartialConverter;
030    import org.joda.time.field.AbstractReadableInstantFieldProperty;
031    import org.joda.time.format.DateTimeFormat;
032    import 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     */
075    public 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    }