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