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