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.Locale; 023 024 import org.joda.convert.FromString; 025 import org.joda.time.base.BaseDateTime; 026 import org.joda.time.field.AbstractReadableInstantFieldProperty; 027 import org.joda.time.format.DateTimeFormatter; 028 import org.joda.time.format.ISODateTimeFormat; 029 030 /** 031 * DateMidnight defines a date where the time component is fixed at midnight. 032 * The class uses a time zone, thus midnight is local unless a UTC time zone is used. 033 * <p> 034 * It is important to emphasise that this class represents the time of midnight on 035 * any given day. 036 * Note that midnight is defined as 00:00, which is at the very start of a day. 037 * <p> 038 * This class does not represent a day, but the millisecond instant at midnight. 039 * If you need a class that represents the whole day, then an {@link Interval} or 040 * a {@link LocalDate} may be more suitable. 041 * <p> 042 * This class uses a Chronology internally. The Chronology determines how the 043 * millisecond instant value is converted into the date time fields. 044 * The default Chronology is <code>ISOChronology</code> which is the agreed 045 * international standard and compatable with the modern Gregorian calendar. 046 * 047 * <p>Each individual field can be queried in two ways: 048 * <ul> 049 * <li><code>getDayOfMonth()</code> 050 * <li><code>dayOfMonth().get()</code> 051 * </ul> 052 * The second technique also provides access to other useful methods on the 053 * field: 054 * <ul> 055 * <li>numeric value 056 * <li>text value 057 * <li>short text value 058 * <li>maximum/minimum values 059 * <li>add/subtract 060 * <li>set 061 * <li>rounding 062 * </ul> 063 * 064 * <p> 065 * DateMidnight is thread-safe and immutable, provided that the Chronology is as well. 066 * All standard Chronology classes supplied are thread-safe and immutable. 067 * 068 * @author Stephen Colebourne 069 * @since 1.0 070 */ 071 public final class DateMidnight 072 extends BaseDateTime 073 implements ReadableDateTime, Serializable { 074 075 /** Serialization lock */ 076 private static final long serialVersionUID = 156371964018738L; 077 078 //----------------------------------------------------------------------- 079 /** 080 * Obtains a {@code DateMidnight} set to the current system millisecond time 081 * using <code>ISOChronology</code> in the default time zone. 082 * The constructed object will have a local time of midnight. 083 * 084 * @return the current date, not null 085 * @since 2.0 086 */ 087 public static DateMidnight now() { 088 return new DateMidnight(); 089 } 090 091 /** 092 * Obtains a {@code DateMidnight} set to the current system millisecond time 093 * using <code>ISOChronology</code> in the specified time zone. 094 * The constructed object will have a local time of midnight. 095 * 096 * @param zone the time zone, not null 097 * @return the current date, not null 098 * @since 2.0 099 */ 100 public static DateMidnight now(DateTimeZone zone) { 101 if (zone == null) { 102 throw new NullPointerException("Zone must not be null"); 103 } 104 return new DateMidnight(zone); 105 } 106 107 /** 108 * Obtains a {@code DateMidnight} set to the current system millisecond time 109 * using the specified chronology. 110 * The constructed object will have a local time of midnight. 111 * 112 * @param chronology the chronology, not null 113 * @return the current date, not null 114 * @since 2.0 115 */ 116 public static DateMidnight now(Chronology chronology) { 117 if (chronology == null) { 118 throw new NullPointerException("Chronology must not be null"); 119 } 120 return new DateMidnight(chronology); 121 } 122 123 //----------------------------------------------------------------------- 124 /** 125 * Parses a {@code DateMidnight} from the specified string. 126 * <p> 127 * This uses {@link ISODateTimeFormat#dateTimeParser()}. 128 * 129 * @param str the string to parse, not null 130 * @since 2.0 131 */ 132 @FromString 133 public static DateMidnight parse(String str) { 134 return parse(str, ISODateTimeFormat.dateTimeParser().withOffsetParsed()); 135 } 136 137 /** 138 * Parses a {@code DateMidnight} from the specified string using a formatter. 139 * 140 * @param str the string to parse, not null 141 * @param formatter the formatter to use, not null 142 * @since 2.0 143 */ 144 public static DateMidnight parse(String str, DateTimeFormatter formatter) { 145 return formatter.parseDateTime(str).toDateMidnight(); 146 } 147 148 //----------------------------------------------------------------------- 149 /** 150 * Constructs an instance set to the current system millisecond time 151 * using <code>ISOChronology</code> in the default time zone. 152 * The constructed object will have a local time of midnight. 153 * 154 * @see #now() 155 */ 156 public DateMidnight() { 157 super(); 158 } 159 160 /** 161 * Constructs an instance set to the current system millisecond time 162 * using <code>ISOChronology</code> in the specified time zone. 163 * The constructed object will have a local time of midnight. 164 * <p> 165 * If the specified time zone is null, the default zone is used. 166 * 167 * @param zone the time zone, null means default zone 168 * @see #now(DateTimeZone) 169 */ 170 public DateMidnight(DateTimeZone zone) { 171 super(zone); 172 } 173 174 /** 175 * Constructs an instance set to the current system millisecond time 176 * using the specified chronology. 177 * The constructed object will have a local time of midnight. 178 * <p> 179 * If the chronology is null, <code>ISOChronology</code> 180 * in the default time zone is used. 181 * 182 * @param chronology the chronology, null means ISOChronology in default zone 183 * @see #now(Chronology) 184 */ 185 public DateMidnight(Chronology chronology) { 186 super(chronology); 187 } 188 189 //----------------------------------------------------------------------- 190 /** 191 * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z 192 * using <code>ISOChronology</code> in the default time zone. 193 * The constructed object will have a local time of midnight. 194 * 195 * @param instant the milliseconds from 1970-01-01T00:00:00Z 196 */ 197 public DateMidnight(long instant) { 198 super(instant); 199 } 200 201 /** 202 * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z 203 * using <code>ISOChronology</code> in the specified time zone. 204 * The constructed object will have a local time of midnight. 205 * <p> 206 * If the specified time zone is null, the default zone is used. 207 * 208 * @param instant the milliseconds from 1970-01-01T00:00:00Z 209 * @param zone the time zone, null means default zone 210 */ 211 public DateMidnight(long instant, DateTimeZone zone) { 212 super(instant, zone); 213 } 214 215 /** 216 * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z 217 * using the specified chronology. 218 * The constructed object will have a local time of midnight. 219 * <p> 220 * If the chronology is null, <code>ISOChronology</code> 221 * in the default time zone is used. 222 * 223 * @param instant the milliseconds from 1970-01-01T00:00:00Z 224 * @param chronology the chronology, null means ISOChronology in default zone 225 */ 226 public DateMidnight(long instant, Chronology chronology) { 227 super(instant, chronology); 228 } 229 230 //----------------------------------------------------------------------- 231 /** 232 * Constructs an instance from an Object that represents a datetime. 233 * The constructed object will have a local time of midnight. 234 * <p> 235 * If the object implies a chronology (such as GregorianCalendar does), 236 * then that chronology will be used. Otherwise, ISO default is used. 237 * Thus if a GregorianCalendar is passed in, the chronology used will 238 * be GJ, but if a Date is passed in the chronology will be ISO. 239 * <p> 240 * The recognised object types are defined in 241 * {@link org.joda.time.convert.ConverterManager ConverterManager} and 242 * include ReadableInstant, String, Calendar and Date. 243 * The String formats are described by {@link ISODateTimeFormat#dateTimeParser()}. 244 * 245 * @param instant the datetime object, null means now 246 * @throws IllegalArgumentException if the instant is invalid 247 */ 248 public DateMidnight(Object instant) { 249 super(instant, (Chronology) null); 250 } 251 252 /** 253 * Constructs an instance from an Object that represents a datetime, 254 * forcing the time zone to that specified. 255 * The constructed object will have a local time of midnight. 256 * <p> 257 * If the object implies a chronology (such as GregorianCalendar does), 258 * then that chronology will be used, but with the time zone adjusted. 259 * Otherwise, ISO is used in the specified time zone. 260 * If the specified time zone is null, the default zone is used. 261 * Thus if a GregorianCalendar is passed in, the chronology used will 262 * be GJ, but if a Date is passed in the chronology will be ISO. 263 * <p> 264 * The recognised object types are defined in 265 * {@link org.joda.time.convert.ConverterManager ConverterManager} and 266 * include ReadableInstant, String, Calendar and Date. 267 * The String formats are described by {@link ISODateTimeFormat#dateTimeParser()}. 268 * 269 * @param instant the datetime object, null means now 270 * @param zone the time zone, null means default time zone 271 * @throws IllegalArgumentException if the instant is invalid 272 */ 273 public DateMidnight(Object instant, DateTimeZone zone) { 274 super(instant, zone); 275 } 276 277 /** 278 * Constructs an instance from an Object that represents a datetime, 279 * using the specified chronology. 280 * The constructed object will have a local time of midnight. 281 * <p> 282 * If the chronology is null, ISO in the default time zone is used. 283 * Any chronology implied by the object (such as GregorianCalendar does) 284 * is ignored. 285 * <p> 286 * The recognised object types are defined in 287 * {@link org.joda.time.convert.ConverterManager ConverterManager} and 288 * include ReadableInstant, String, Calendar and Date. 289 * The String formats are described by {@link ISODateTimeFormat#dateTimeParser()}. 290 * 291 * @param instant the datetime object, null means now 292 * @param chronology the chronology, null means ISOChronology in default zone 293 * @throws IllegalArgumentException if the instant is invalid 294 */ 295 public DateMidnight(Object instant, Chronology chronology) { 296 super(instant, DateTimeUtils.getChronology(chronology)); 297 } 298 299 //----------------------------------------------------------------------- 300 /** 301 * Constructs an instance from datetime field values 302 * using <code>ISOChronology</code> in the default time zone. 303 * The constructed object will have a local time of midnight. 304 * 305 * @param year the year 306 * @param monthOfYear the month of the year, from 1 to 12 307 * @param dayOfMonth the day of the month, from 1 to 31 308 */ 309 public DateMidnight(int year, int monthOfYear, int dayOfMonth) { 310 super(year, monthOfYear, dayOfMonth, 0, 0, 0, 0); 311 } 312 313 /** 314 * Constructs an instance from datetime field values 315 * using <code>ISOChronology</code> in the specified time zone. 316 * The constructed object will have a local time of midnight. 317 * <p> 318 * If the specified time zone is null, the default zone is used. 319 * 320 * @param year the year 321 * @param monthOfYear the month of the year, from 1 to 12 322 * @param dayOfMonth the day of the month, from 1 to 31 323 * @param zone the time zone, null means default time zone 324 */ 325 public DateMidnight(int year, int monthOfYear, int dayOfMonth, DateTimeZone zone) { 326 super(year, monthOfYear, dayOfMonth, 0, 0, 0, 0, zone); 327 } 328 329 /** 330 * Constructs an instance from datetime field values 331 * using the specified chronology. 332 * The constructed object will have a local time of midnight. 333 * <p> 334 * If the chronology is null, <code>ISOChronology</code> 335 * in the default time zone is used. 336 * 337 * @param year the year, valid values defined by the chronology 338 * @param monthOfYear the month of the year, valid values defined by the chronology 339 * @param dayOfMonth the day of the month, valid values defined by the chronology 340 * @param chronology the chronology, null means ISOChronology in default zone 341 */ 342 public DateMidnight(int year, int monthOfYear, int dayOfMonth, Chronology chronology) { 343 super(year, monthOfYear, dayOfMonth, 0, 0, 0, 0, chronology); 344 } 345 346 /** 347 * Rounds the specified instant to midnight. 348 * 349 * @param instant the milliseconds from 1970-01-01T00:00:00Z to round 350 * @param chronology the chronology to use, not null 351 * @return the updated instant, rounded to midnight 352 */ 353 protected long checkInstant(long instant, Chronology chronology) { 354 return chronology.dayOfMonth().roundFloor(instant); 355 } 356 357 //----------------------------------------------------------------------- 358 /** 359 * Returns a copy of this date with a different millisecond instant. 360 * The returned object will have a local time of midnight. 361 * <p> 362 * Only the millis will change, the chronology and time zone are kept. 363 * The returned object will be either be a new instance or <code>this</code>. 364 * 365 * @param newMillis the new millis, from 1970-01-01T00:00:00Z 366 * @return a copy of this instant with different millis 367 */ 368 public DateMidnight withMillis(long newMillis) { 369 Chronology chrono = getChronology(); 370 newMillis = checkInstant(newMillis, chrono); 371 return (newMillis == getMillis() ? this : new DateMidnight(newMillis, chrono)); 372 } 373 374 /** 375 * Returns a copy of this date with a different chronology, potentially 376 * changing the day in unexpected ways. 377 * <p> 378 * This method creates a new DateMidnight using the midnight millisecond value 379 * and the new chronology. If the same or similar chronology is specified, but 380 * with a different time zone, the day may change. This occurs because the new 381 * DateMidnight rounds down the millisecond value to get to midnight, and the 382 * time zone change may result in a rounding down to a different day. 383 * <p> 384 * For example, changing time zone from London (+00:00) to Paris (+01:00) will 385 * retain the same day, but changing from Paris to London will change the day. 386 * (When its midnight in London its the same day in Paris, but when its midnight 387 * in Paris its still the previous day in London) 388 * <p> 389 * To avoid these unusual effects, use {@link #withZoneRetainFields(DateTimeZone)} 390 * to change time zones. 391 * 392 * @param newChronology the new chronology 393 * @return a copy of this instant with a different chronology 394 */ 395 public DateMidnight withChronology(Chronology newChronology) { 396 return (newChronology == getChronology() ? this : new DateMidnight(getMillis(), newChronology)); 397 } 398 399 /** 400 * Returns a copy of this date with a different time zone, preserving the day 401 * The returned object will have a local time of midnight in the new zone on 402 * the same day as the original instant. 403 * 404 * @param newZone the new time zone, null means default 405 * @return a copy of this instant with a different time zone 406 */ 407 public DateMidnight withZoneRetainFields(DateTimeZone newZone) { 408 newZone = DateTimeUtils.getZone(newZone); 409 DateTimeZone originalZone = DateTimeUtils.getZone(getZone()); 410 if (newZone == originalZone) { 411 return this; 412 } 413 414 long millis = originalZone.getMillisKeepLocal(newZone, getMillis()); 415 return new DateMidnight(millis, getChronology().withZone(newZone)); 416 } 417 418 //----------------------------------------------------------------------- 419 /** 420 * Returns a copy of this date with the partial set of fields replacing those 421 * from this instance. 422 * <p> 423 * For example, if the partial is a <code>LocalDate</code> then the date fields 424 * would be changed in the returned instance. 425 * If the partial is null, then <code>this</code> is returned. 426 * 427 * @param partial the partial set of fields to apply to this datetime, null ignored 428 * @return a copy of this datetime with a different set of fields 429 * @throws IllegalArgumentException if any value is invalid 430 */ 431 public DateMidnight withFields(ReadablePartial partial) { 432 if (partial == null) { 433 return this; 434 } 435 return withMillis(getChronology().set(partial, getMillis())); 436 } 437 438 /** 439 * Returns a copy of this date with the specified field set to a new value. 440 * <p> 441 * For example, if the field type is <code>dayOfMonth</code> then the day of month 442 * field would be changed in the returned instance. 443 * If the field type is null, then <code>this</code> is returned. 444 * <p> 445 * These three lines are equivalent: 446 * <pre> 447 * DateTime updated = dt.withField(DateTimeFieldType.dayOfMonth(), 6); 448 * DateTime updated = dt.dayOfMonth().setCopy(6); 449 * DateTime updated = dt.property(DateTimeFieldType.dayOfMonth()).setCopy(6); 450 * </pre> 451 * 452 * @param fieldType the field type to set, not null 453 * @param value the value to set 454 * @return a copy of this datetime with the field set 455 * @throws IllegalArgumentException if the value is null or invalid 456 */ 457 public DateMidnight withField(DateTimeFieldType fieldType, int value) { 458 if (fieldType == null) { 459 throw new IllegalArgumentException("Field must not be null"); 460 } 461 long instant = fieldType.getField(getChronology()).set(getMillis(), value); 462 return withMillis(instant); 463 } 464 465 /** 466 * Returns a copy of this date with the value of the specified field increased. 467 * <p> 468 * If the addition is zero or the field is null, then <code>this</code> is returned. 469 * <p> 470 * These three lines are equivalent: 471 * <pre> 472 * DateMidnight added = dt.withFieldAdded(DateTimeFieldType.year(), 6); 473 * DateMidnight added = dt.plusYears(6); 474 * DateMidnight added = dt.year().addToCopy(6); 475 * </pre> 476 * 477 * @param fieldType the field type to add to, not null 478 * @param amount the amount to add 479 * @return a copy of this datetime with the field updated 480 * @throws IllegalArgumentException if the value is null or invalid 481 * @throws ArithmeticException if the new datetime exceeds the capacity of a long 482 */ 483 public DateMidnight withFieldAdded(DurationFieldType fieldType, int amount) { 484 if (fieldType == null) { 485 throw new IllegalArgumentException("Field must not be null"); 486 } 487 if (amount == 0) { 488 return this; 489 } 490 long instant = fieldType.getField(getChronology()).add(getMillis(), amount); 491 return withMillis(instant); 492 } 493 494 //----------------------------------------------------------------------- 495 /** 496 * Returns a copy of this date with the specified duration added. 497 * <p> 498 * If the addition is zero, then <code>this</code> is returned. 499 * 500 * @param durationToAdd the duration to add to this one 501 * @param scalar the amount of times to add, such as -1 to subtract once 502 * @return a copy of this datetime with the duration added 503 * @throws ArithmeticException if the new datetime exceeds the capacity of a long 504 */ 505 public DateMidnight withDurationAdded(long durationToAdd, int scalar) { 506 if (durationToAdd == 0 || scalar == 0) { 507 return this; 508 } 509 long instant = getChronology().add(getMillis(), durationToAdd, scalar); 510 return withMillis(instant); 511 } 512 513 /** 514 * Returns a copy of this date with the specified duration added. 515 * <p> 516 * If the addition is zero, then <code>this</code> is returned. 517 * 518 * @param durationToAdd the duration to add to this one, null means zero 519 * @param scalar the amount of times to add, such as -1 to subtract once 520 * @return a copy of this datetime with the duration added 521 * @throws ArithmeticException if the new datetime exceeds the capacity of a long 522 */ 523 public DateMidnight withDurationAdded(ReadableDuration durationToAdd, int scalar) { 524 if (durationToAdd == null || scalar == 0) { 525 return this; 526 } 527 return withDurationAdded(durationToAdd.getMillis(), scalar); 528 } 529 530 /** 531 * Returns a copy of this date with the specified period added. 532 * <p> 533 * If the addition is zero, then <code>this</code> is returned. 534 * <p> 535 * This method is typically used to add multiple copies of complex 536 * period instances. Adding one field is best achieved using methods 537 * like {@link #withFieldAdded(DurationFieldType, int)} 538 * or {@link #plusYears(int)}. 539 * 540 * @param period the period to add to this one, null means zero 541 * @param scalar the amount of times to add, such as -1 to subtract once 542 * @return a copy of this datetime with the period added 543 * @throws ArithmeticException if the new datetime exceeds the capacity of a long 544 */ 545 public DateMidnight withPeriodAdded(ReadablePeriod period, int scalar) { 546 if (period == null || scalar == 0) { 547 return this; 548 } 549 long instant = getChronology().add(period, getMillis(), scalar); 550 return withMillis(instant); 551 } 552 553 //----------------------------------------------------------------------- 554 /** 555 * Returns a copy of this date with the specified duration added. 556 * <p> 557 * If the amount is zero, then <code>this</code> is returned. 558 * 559 * @param duration the duration, in millis, to add to this one 560 * @return a copy of this datetime with the duration added 561 * @throws ArithmeticException if the new datetime exceeds the capacity of a long 562 */ 563 public DateMidnight plus(long duration) { 564 return withDurationAdded(duration, 1); 565 } 566 567 /** 568 * Returns a copy of this date with the specified duration added. 569 * <p> 570 * If the amount is zero or null, then <code>this</code> is returned. 571 * 572 * @param duration the duration to add to this one, null means zero 573 * @return a copy of this datetime with the duration added 574 * @throws ArithmeticException if the new datetime exceeds the capacity of a long 575 */ 576 public DateMidnight plus(ReadableDuration duration) { 577 return withDurationAdded(duration, 1); 578 } 579 580 /** 581 * Returns a copy of this date with the specified period added. 582 * <p> 583 * If the amount is zero or null, then <code>this</code> is returned. 584 * <p> 585 * This method is typically used to add complex period instances. 586 * Adding one field is best achieved using methods 587 * like {@link #plusYears(int)}. 588 * 589 * @param period the duration to add to this one, null means zero 590 * @return a copy of this datetime with the period added 591 * @throws ArithmeticException if the new datetime exceeds the capacity of a long 592 */ 593 public DateMidnight plus(ReadablePeriod period) { 594 return withPeriodAdded(period, 1); 595 } 596 597 //----------------------------------------------------------------------- 598 /** 599 * Returns a copy of this date plus the specified number of years. 600 * <p> 601 * This datetime instance is immutable and unaffected by this method call. 602 * <p> 603 * The following three lines are identical in effect: 604 * <pre> 605 * DateMidnight added = dt.plusYears(6); 606 * DateMidnight added = dt.plus(Period.years(6)); 607 * DateMidnight added = dt.withFieldAdded(DurationFieldType.years(), 6); 608 * </pre> 609 * 610 * @param years the amount of years to add, may be negative 611 * @return the new datetime plus the increased years 612 * @since 1.1 613 */ 614 public DateMidnight plusYears(int years) { 615 if (years == 0) { 616 return this; 617 } 618 long instant = getChronology().years().add(getMillis(), years); 619 return withMillis(instant); 620 } 621 622 /** 623 * Returns a copy of this date plus the specified number of months. 624 * <p> 625 * This datetime instance is immutable and unaffected by this method call. 626 * <p> 627 * The following three lines are identical in effect: 628 * <pre> 629 * DateMidnight added = dt.plusMonths(6); 630 * DateMidnight added = dt.plus(Period.months(6)); 631 * DateMidnight added = dt.withFieldAdded(DurationFieldType.months(), 6); 632 * </pre> 633 * 634 * @param months the amount of months to add, may be negative 635 * @return the new datetime plus the increased months 636 * @since 1.1 637 */ 638 public DateMidnight plusMonths(int months) { 639 if (months == 0) { 640 return this; 641 } 642 long instant = getChronology().months().add(getMillis(), months); 643 return withMillis(instant); 644 } 645 646 /** 647 * Returns a copy of this date plus the specified number of weeks. 648 * <p> 649 * This datetime instance is immutable and unaffected by this method call. 650 * <p> 651 * The following three lines are identical in effect: 652 * <pre> 653 * DateMidnight added = dt.plusWeeks(6); 654 * DateMidnight added = dt.plus(Period.weeks(6)); 655 * DateMidnight added = dt.withFieldAdded(DurationFieldType.weeks(), 6); 656 * </pre> 657 * 658 * @param weeks the amount of weeks to add, may be negative 659 * @return the new datetime plus the increased weeks 660 * @since 1.1 661 */ 662 public DateMidnight plusWeeks(int weeks) { 663 if (weeks == 0) { 664 return this; 665 } 666 long instant = getChronology().weeks().add(getMillis(), weeks); 667 return withMillis(instant); 668 } 669 670 /** 671 * Returns a copy of this date plus the specified number of days. 672 * <p> 673 * This datetime instance is immutable and unaffected by this method call. 674 * <p> 675 * The following three lines are identical in effect: 676 * <pre> 677 * DateMidnight added = dt.plusDays(6); 678 * DateMidnight added = dt.plus(Period.days(6)); 679 * DateMidnight added = dt.withFieldAdded(DurationFieldType.days(), 6); 680 * </pre> 681 * 682 * @param days the amount of days to add, may be negative 683 * @return the new datetime plus the increased days 684 * @since 1.1 685 */ 686 public DateMidnight plusDays(int days) { 687 if (days == 0) { 688 return this; 689 } 690 long instant = getChronology().days().add(getMillis(), days); 691 return withMillis(instant); 692 } 693 694 //----------------------------------------------------------------------- 695 /** 696 * Returns a copy of this date with the specified duration taken away. 697 * <p> 698 * If the amount is zero or null, then <code>this</code> is returned. 699 * 700 * @param duration the duration, in millis, to reduce this instant by 701 * @return a copy of this datetime with the duration taken away 702 * @throws ArithmeticException if the new datetime exceeds the capacity of a long 703 */ 704 public DateMidnight minus(long duration) { 705 return withDurationAdded(duration, -1); 706 } 707 708 /** 709 * Returns a copy of this date with the specified duration taken away. 710 * <p> 711 * If the amount is zero or null, then <code>this</code> is returned. 712 * 713 * @param duration the duration to reduce this instant by 714 * @return a copy of this datetime with the duration taken away 715 * @throws ArithmeticException if the new datetime exceeds the capacity of a long 716 */ 717 public DateMidnight minus(ReadableDuration duration) { 718 return withDurationAdded(duration, -1); 719 } 720 721 /** 722 * Returns a copy of this date with the specified period taken away. 723 * <p> 724 * If the amount is zero or null, then <code>this</code> is returned. 725 * <p> 726 * This method is typically used to subtract complex period instances. 727 * Subtracting one field is best achieved using methods 728 * like {@link #minusYears(int)}. 729 * 730 * @param period the period to reduce this instant by 731 * @return a copy of this datetime with the period taken away 732 * @throws ArithmeticException if the new datetime exceeds the capacity of a long 733 */ 734 public DateMidnight minus(ReadablePeriod period) { 735 return withPeriodAdded(period, -1); 736 } 737 738 //----------------------------------------------------------------------- 739 /** 740 * Returns a copy of this date minus the specified number of years. 741 * <p> 742 * This datetime instance is immutable and unaffected by this method call. 743 * <p> 744 * The following three lines are identical in effect: 745 * <pre> 746 * DateTime subtracted = dt.minusYears(6); 747 * DateTime subtracted = dt.minus(Period.years(6)); 748 * DateTime subtracted = dt.withFieldAdded(DurationFieldType.years(), -6); 749 * </pre> 750 * 751 * @param years the amount of years to subtract, may be negative 752 * @return the new datetime minus the increased years 753 * @since 1.1 754 */ 755 public DateMidnight minusYears(int years) { 756 if (years == 0) { 757 return this; 758 } 759 long instant = getChronology().years().subtract(getMillis(), years); 760 return withMillis(instant); 761 } 762 763 /** 764 * Returns a copy of this date minus the specified number of months. 765 * <p> 766 * This datetime instance is immutable and unaffected by this method call. 767 * <p> 768 * The following three lines are identical in effect: 769 * <pre> 770 * DateMidnight subtracted = dt.minusMonths(6); 771 * DateMidnight subtracted = dt.minus(Period.months(6)); 772 * DateMidnight subtracted = dt.withFieldAdded(DurationFieldType.months(), -6); 773 * </pre> 774 * 775 * @param months the amount of months to subtract, may be negative 776 * @return the new datetime minus the increased months 777 * @since 1.1 778 */ 779 public DateMidnight minusMonths(int months) { 780 if (months == 0) { 781 return this; 782 } 783 long instant = getChronology().months().subtract(getMillis(), months); 784 return withMillis(instant); 785 } 786 787 /** 788 * Returns a copy of this date minus the specified number of weeks. 789 * <p> 790 * This datetime instance is immutable and unaffected by this method call. 791 * <p> 792 * The following three lines are identical in effect: 793 * <pre> 794 * DateMidnight subtracted = dt.minusWeeks(6); 795 * DateMidnight subtracted = dt.minus(Period.weeks(6)); 796 * DateMidnight subtracted = dt.withFieldAdded(DurationFieldType.weeks(), -6); 797 * </pre> 798 * 799 * @param weeks the amount of weeks to subtract, may be negative 800 * @return the new datetime minus the increased weeks 801 * @since 1.1 802 */ 803 public DateMidnight minusWeeks(int weeks) { 804 if (weeks == 0) { 805 return this; 806 } 807 long instant = getChronology().weeks().subtract(getMillis(), weeks); 808 return withMillis(instant); 809 } 810 811 /** 812 * Returns a copy of this date minus the specified number of days. 813 * <p> 814 * This datetime instance is immutable and unaffected by this method call. 815 * <p> 816 * The following three lines are identical in effect: 817 * <pre> 818 * DateMidnight subtracted = dt.minusDays(6); 819 * DateMidnight subtracted = dt.minus(Period.days(6)); 820 * DateMidnight subtracted = dt.withFieldAdded(DurationFieldType.days(), -6); 821 * </pre> 822 * 823 * @param days the amount of days to subtract, may be negative 824 * @return the new datetime minus the increased days 825 * @since 1.1 826 */ 827 public DateMidnight minusDays(int days) { 828 if (days == 0) { 829 return this; 830 } 831 long instant = getChronology().days().subtract(getMillis(), days); 832 return withMillis(instant); 833 } 834 835 //----------------------------------------------------------------------- 836 /** 837 * Gets the property object for the specified type, which contains many useful methods. 838 * 839 * @param type the field type to get the chronology for 840 * @return the property object 841 * @throws IllegalArgumentException if the field is null or unsupported 842 */ 843 public Property property(DateTimeFieldType type) { 844 if (type == null) { 845 throw new IllegalArgumentException("The DateTimeFieldType must not be null"); 846 } 847 DateTimeField field = type.getField(getChronology()); 848 if (field.isSupported() == false) { 849 throw new IllegalArgumentException("Field '" + type + "' is not supported"); 850 } 851 return new Property(this, field); 852 } 853 854 //----------------------------------------------------------------------- 855 /** 856 * Converts this object to a <code>YearMonthDay</code> using the 857 * same date and chronology. 858 * 859 * @return a YearMonthDay using the same millis and chronology 860 * @deprecated Use LocalDate instead of YearMonthDay 861 */ 862 @Deprecated 863 public YearMonthDay toYearMonthDay() { 864 return new YearMonthDay(getMillis(), getChronology()); 865 } 866 867 /** 868 * Converts this object to a <code>LocalDate</code> with the 869 * same date and chronology. 870 * 871 * @return a LocalDate with the same date and chronology 872 * @since 1.3 873 */ 874 public LocalDate toLocalDate() { 875 return new LocalDate(getMillis(), getChronology()); 876 } 877 878 /** 879 * Converts this object to an <code>Interval</code> encompassing 880 * the whole of this day. 881 * <p> 882 * The interval starts at midnight 00:00 and ends at 00:00 the following day, 883 * (which is not included in the interval, as intervals are half-open). 884 * 885 * @return an interval over the day 886 */ 887 public Interval toInterval() { 888 Chronology chrono = getChronology(); 889 long start = getMillis(); 890 long end = DurationFieldType.days().getField(chrono).add(start, 1); 891 return new Interval(start, end, chrono); 892 } 893 894 //----------------------------------------------------------------------- 895 /** 896 * Returns a copy of this date with the era field updated. 897 * <p> 898 * DateMidnight is immutable, so there are no set methods. 899 * Instead, this method returns a new instance with the value of 900 * era changed. 901 * 902 * @param era the era to set 903 * @return a copy of this object with the field set 904 * @throws IllegalArgumentException if the value is invalid 905 * @since 1.3 906 */ 907 public DateMidnight withEra(int era) { 908 return withMillis(getChronology().era().set(getMillis(), era)); 909 } 910 911 /** 912 * Returns a copy of this date with the century of era field updated. 913 * <p> 914 * DateMidnight is immutable, so there are no set methods. 915 * Instead, this method returns a new instance with the value of 916 * century of era changed. 917 * 918 * @param centuryOfEra the centurey of era to set 919 * @return a copy of this object with the field set 920 * @throws IllegalArgumentException if the value is invalid 921 * @since 1.3 922 */ 923 public DateMidnight withCenturyOfEra(int centuryOfEra) { 924 return withMillis(getChronology().centuryOfEra().set(getMillis(), centuryOfEra)); 925 } 926 927 /** 928 * Returns a copy of this date with the year of era field updated. 929 * <p> 930 * DateMidnight is immutable, so there are no set methods. 931 * Instead, this method returns a new instance with the value of 932 * year of era changed. 933 * 934 * @param yearOfEra the year of era to set 935 * @return a copy of this object with the field set 936 * @throws IllegalArgumentException if the value is invalid 937 * @since 1.3 938 */ 939 public DateMidnight withYearOfEra(int yearOfEra) { 940 return withMillis(getChronology().yearOfEra().set(getMillis(), yearOfEra)); 941 } 942 943 /** 944 * Returns a copy of this date with the year of century field updated. 945 * <p> 946 * DateMidnight is immutable, so there are no set methods. 947 * Instead, this method returns a new instance with the value of 948 * year of century changed. 949 * 950 * @param yearOfCentury the year of century to set 951 * @return a copy of this object with the field set 952 * @throws IllegalArgumentException if the value is invalid 953 * @since 1.3 954 */ 955 public DateMidnight withYearOfCentury(int yearOfCentury) { 956 return withMillis(getChronology().yearOfCentury().set(getMillis(), yearOfCentury)); 957 } 958 959 /** 960 * Returns a copy of this date with the year field updated. 961 * <p> 962 * DateMidnight is immutable, so there are no set methods. 963 * Instead, this method returns a new instance with the value of 964 * year changed. 965 * 966 * @param year the year to set 967 * @return a copy of this object with the field set 968 * @throws IllegalArgumentException if the value is invalid 969 * @since 1.3 970 */ 971 public DateMidnight withYear(int year) { 972 return withMillis(getChronology().year().set(getMillis(), year)); 973 } 974 975 /** 976 * Returns a copy of this date with the weekyear field updated. 977 * <p> 978 * The weekyear is the year that matches with the weekOfWeekyear field. 979 * In the standard ISO8601 week algorithm, the first week of the year 980 * is that in which at least 4 days are in the year. As a result of this 981 * definition, day 1 of the first week may be in the previous year. 982 * The weekyear allows you to query the effective year for that day. 983 * <p> 984 * DateMidnight is immutable, so there are no set methods. 985 * Instead, this method returns a new instance with the value of 986 * weekyear changed. 987 * 988 * @param weekyear the weekyear to set 989 * @return a copy of this object with the field set 990 * @throws IllegalArgumentException if the value is invalid 991 * @since 1.3 992 */ 993 public DateMidnight withWeekyear(int weekyear) { 994 return withMillis(getChronology().weekyear().set(getMillis(), weekyear)); 995 } 996 997 /** 998 * Returns a copy of this date with the month of year field updated. 999 * <p> 1000 * DateMidnight is immutable, so there are no set methods. 1001 * Instead, this method returns a new instance with the value of 1002 * month of year changed. 1003 * 1004 * @param monthOfYear the month of year to set 1005 * @return a copy of this object with the field set 1006 * @throws IllegalArgumentException if the value is invalid 1007 * @since 1.3 1008 */ 1009 public DateMidnight withMonthOfYear(int monthOfYear) { 1010 return withMillis(getChronology().monthOfYear().set(getMillis(), monthOfYear)); 1011 } 1012 1013 /** 1014 * Returns a copy of this date with the week of weekyear field updated. 1015 * <p> 1016 * This field is associated with the "weekyear" via {@link #withWeekyear(int)}. 1017 * In the standard ISO8601 week algorithm, the first week of the year 1018 * is that in which at least 4 days are in the year. As a result of this 1019 * definition, day 1 of the first week may be in the previous year. 1020 * <p> 1021 * DateMidnight is immutable, so there are no set methods. 1022 * Instead, this method returns a new instance with the value of 1023 * week of weekyear changed. 1024 * 1025 * @param weekOfWeekyear the week of weekyear to set 1026 * @return a copy of this object with the field set 1027 * @throws IllegalArgumentException if the value is invalid 1028 * @since 1.3 1029 */ 1030 public DateMidnight withWeekOfWeekyear(int weekOfWeekyear) { 1031 return withMillis(getChronology().weekOfWeekyear().set(getMillis(), weekOfWeekyear)); 1032 } 1033 1034 /** 1035 * Returns a copy of this date with the day of year field updated. 1036 * <p> 1037 * DateMidnight is immutable, so there are no set methods. 1038 * Instead, this method returns a new instance with the value of 1039 * day of year changed. 1040 * 1041 * @param dayOfYear the day of year to set 1042 * @return a copy of this object with the field set 1043 * @throws IllegalArgumentException if the value is invalid 1044 * @since 1.3 1045 */ 1046 public DateMidnight withDayOfYear(int dayOfYear) { 1047 return withMillis(getChronology().dayOfYear().set(getMillis(), dayOfYear)); 1048 } 1049 1050 /** 1051 * Returns a copy of this date with the day of month field updated. 1052 * <p> 1053 * DateMidnight is immutable, so there are no set methods. 1054 * Instead, this method returns a new instance with the value of 1055 * day of month changed. 1056 * 1057 * @param dayOfMonth the day of month to set 1058 * @return a copy of this object with the field set 1059 * @throws IllegalArgumentException if the value is invalid 1060 * @since 1.3 1061 */ 1062 public DateMidnight withDayOfMonth(int dayOfMonth) { 1063 return withMillis(getChronology().dayOfMonth().set(getMillis(), dayOfMonth)); 1064 } 1065 1066 /** 1067 * Returns a copy of this date with the day of week field updated. 1068 * <p> 1069 * DateMidnight is immutable, so there are no set methods. 1070 * Instead, this method returns a new instance with the value of 1071 * day of week changed. 1072 * 1073 * @param dayOfWeek the day of week to set 1074 * @return a copy of this object with the field set 1075 * @throws IllegalArgumentException if the value is invalid 1076 * @since 1.3 1077 */ 1078 public DateMidnight withDayOfWeek(int dayOfWeek) { 1079 return withMillis(getChronology().dayOfWeek().set(getMillis(), dayOfWeek)); 1080 } 1081 1082 // Date properties 1083 //----------------------------------------------------------------------- 1084 /** 1085 * Get the era property which provides access to advanced functionality. 1086 * 1087 * @return the era property 1088 */ 1089 public Property era() { 1090 return new Property(this, getChronology().era()); 1091 } 1092 1093 /** 1094 * Get the century of era property which provides access to advanced functionality. 1095 * 1096 * @return the year of era property 1097 */ 1098 public Property centuryOfEra() { 1099 return new Property(this, getChronology().centuryOfEra()); 1100 } 1101 1102 /** 1103 * Get the year of century property which provides access to advanced functionality. 1104 * 1105 * @return the year of era property 1106 */ 1107 public Property yearOfCentury() { 1108 return new Property(this, getChronology().yearOfCentury()); 1109 } 1110 1111 /** 1112 * Get the year of era property which provides access to advanced functionality. 1113 * 1114 * @return the year of era property 1115 */ 1116 public Property yearOfEra() { 1117 return new Property(this, getChronology().yearOfEra()); 1118 } 1119 1120 /** 1121 * Get the year property which provides access to advanced functionality. 1122 * 1123 * @return the year property 1124 */ 1125 public Property year() { 1126 return new Property(this, getChronology().year()); 1127 } 1128 1129 /** 1130 * Get the year of a week based year property which provides access to advanced functionality. 1131 * 1132 * @return the year of a week based year property 1133 */ 1134 public Property weekyear() { 1135 return new Property(this, getChronology().weekyear()); 1136 } 1137 1138 /** 1139 * Get the month of year property which provides access to advanced functionality. 1140 * 1141 * @return the month of year property 1142 */ 1143 public Property monthOfYear() { 1144 return new Property(this, getChronology().monthOfYear()); 1145 } 1146 1147 /** 1148 * Get the week of a week based year property which provides access to advanced functionality. 1149 * 1150 * @return the week of a week based year property 1151 */ 1152 public Property weekOfWeekyear() { 1153 return new Property(this, getChronology().weekOfWeekyear()); 1154 } 1155 1156 /** 1157 * Get the day of year property which provides access to advanced functionality. 1158 * 1159 * @return the day of year property 1160 */ 1161 public Property dayOfYear() { 1162 return new Property(this, getChronology().dayOfYear()); 1163 } 1164 1165 /** 1166 * Get the day of month property which provides access to advanced functionality. 1167 * 1168 * @return the day of month property 1169 */ 1170 public Property dayOfMonth() { 1171 return new Property(this, getChronology().dayOfMonth()); 1172 } 1173 1174 /** 1175 * Get the day of week property which provides access to advanced functionality. 1176 * 1177 * @return the day of week property 1178 */ 1179 public Property dayOfWeek() { 1180 return new Property(this, getChronology().dayOfWeek()); 1181 } 1182 1183 //----------------------------------------------------------------------- 1184 /** 1185 * DateMidnight.Property binds a DateMidnight to a DateTimeField allowing powerful 1186 * datetime functionality to be easily accessed. 1187 * <p> 1188 * The simplest use of this class is as an alternative get method, here used to 1189 * get the year '1972' (as an int) and the month 'December' (as a String). 1190 * <pre> 1191 * DateMidnight dt = new DateMidnight(1972, 12, 3); 1192 * int year = dt.year().get(); 1193 * String monthStr = dt.monthOfYear().getAsText(); 1194 * </pre> 1195 * <p> 1196 * Methods are also provided that allow date modification. These return new instances 1197 * of DateMidnight - they do not modify the original. The example below yields two 1198 * independent immutable date objects 20 years apart. 1199 * <pre> 1200 * DateMidnight dt = new DateMidnight(1972, 12, 3); 1201 * DateMidnight dt20 = dt.year().addToCopy(20); 1202 * </pre> 1203 * Serious modification of dates (ie. more than just changing one or two fields) 1204 * should use the {@link org.joda.time.MutableDateTime MutableDateTime} class. 1205 * <p> 1206 * DateMidnight.Property itself is thread-safe and immutable. 1207 * 1208 * @author Stephen Colebourne 1209 * @author Brian S O'Neill 1210 * @since 1.0 1211 */ 1212 public static final class Property extends AbstractReadableInstantFieldProperty { 1213 1214 /** Serialization lock */ 1215 private static final long serialVersionUID = 257629620L; 1216 1217 /** The instant this property is working against */ 1218 private DateMidnight iInstant; 1219 /** The field this property is working against */ 1220 private DateTimeField iField; 1221 1222 /** 1223 * Constructor. 1224 * 1225 * @param instant the instant to set 1226 * @param field the field to use 1227 */ 1228 Property(DateMidnight instant, DateTimeField field) { 1229 super(); 1230 iInstant = instant; 1231 iField = field; 1232 } 1233 1234 /** 1235 * Writes the property in a safe serialization format. 1236 */ 1237 private void writeObject(ObjectOutputStream oos) throws IOException { 1238 oos.writeObject(iInstant); 1239 oos.writeObject(iField.getType()); 1240 } 1241 1242 /** 1243 * Reads the property from a safe serialization format. 1244 */ 1245 private void readObject(ObjectInputStream oos) throws IOException, ClassNotFoundException { 1246 iInstant = (DateMidnight) oos.readObject(); 1247 DateTimeFieldType type = (DateTimeFieldType) oos.readObject(); 1248 iField = type.getField(iInstant.getChronology()); 1249 } 1250 1251 //----------------------------------------------------------------------- 1252 /** 1253 * Gets the field being used. 1254 * 1255 * @return the field 1256 */ 1257 public DateTimeField getField() { 1258 return iField; 1259 } 1260 1261 /** 1262 * Gets the milliseconds of the datetime that this property is linked to. 1263 * 1264 * @return the milliseconds 1265 */ 1266 protected long getMillis() { 1267 return iInstant.getMillis(); 1268 } 1269 1270 /** 1271 * Gets the chronology of the datetime that this property is linked to. 1272 * 1273 * @return the chronology 1274 * @since 1.4 1275 */ 1276 protected Chronology getChronology() { 1277 return iInstant.getChronology(); 1278 } 1279 1280 /** 1281 * Gets the datetime being used. 1282 * 1283 * @return the datetime 1284 */ 1285 public DateMidnight getDateMidnight() { 1286 return iInstant; 1287 } 1288 1289 //----------------------------------------------------------------------- 1290 /** 1291 * Adds to this field in a copy of this DateMidnight. 1292 * <p> 1293 * The DateMidnight attached to this property is unchanged by this call. 1294 * This operation is faster than converting a DateMidnight to a MutableDateTime 1295 * and back again when setting one field. When setting multiple fields, 1296 * it is generally quicker to make the conversion to MutableDateTime. 1297 * 1298 * @param value the value to add to the field in the copy 1299 * @return a copy of the DateMidnight with the field value changed 1300 * @throws IllegalArgumentException if the value isn't valid 1301 */ 1302 public DateMidnight addToCopy(int value) { 1303 return iInstant.withMillis(iField.add(iInstant.getMillis(), value)); 1304 } 1305 1306 /** 1307 * Adds to this field in a copy of this DateMidnight. 1308 * <p> 1309 * The DateMidnight attached to this property is unchanged by this call. 1310 * This operation is faster than converting a DateMidnight to a MutableDateTime 1311 * and back again when setting one field. When setting multiple fields, 1312 * it is generally quicker to make the conversion to MutableDateTime. 1313 * 1314 * @param value the value to add to the field in the copy 1315 * @return a copy of the DateMidnight with the field value changed 1316 * @throws IllegalArgumentException if the value isn't valid 1317 */ 1318 public DateMidnight addToCopy(long value) { 1319 return iInstant.withMillis(iField.add(iInstant.getMillis(), value)); 1320 } 1321 1322 /** 1323 * Adds to this field, possibly wrapped, in a copy of this DateMidnight. 1324 * A wrapped operation only changes this field. 1325 * Thus 31st January addWrapField one day goes to the 1st January. 1326 * <p> 1327 * The DateMidnight attached to this property is unchanged by this call. 1328 * This operation is faster than converting a DateMidnight to a MutableDateTime 1329 * and back again when setting one field. When setting multiple fields, 1330 * it is generally quicker to make the conversion to MutableDateTime. 1331 * 1332 * @param value the value to add to the field in the copy 1333 * @return a copy of the DateMidnight with the field value changed 1334 * @throws IllegalArgumentException if the value isn't valid 1335 */ 1336 public DateMidnight addWrapFieldToCopy(int value) { 1337 return iInstant.withMillis(iField.addWrapField(iInstant.getMillis(), value)); 1338 } 1339 1340 //----------------------------------------------------------------------- 1341 /** 1342 * Sets this field in a copy of the DateMidnight. 1343 * <p> 1344 * The DateMidnight attached to this property is unchanged by this call. 1345 * This operation is faster than converting a DateMidnight to a MutableDateTime 1346 * and back again when setting one field. When setting multiple fields, 1347 * it is generally quicker to make the conversion to MutableDateTime. 1348 * 1349 * @param value the value to set the field in the copy to 1350 * @return a copy of the DateMidnight with the field value changed 1351 * @throws IllegalArgumentException if the value isn't valid 1352 */ 1353 public DateMidnight setCopy(int value) { 1354 return iInstant.withMillis(iField.set(iInstant.getMillis(), value)); 1355 } 1356 1357 /** 1358 * Sets this field in a copy of the DateMidnight to a parsed text value. 1359 * <p> 1360 * The DateMidnight attached to this property is unchanged by this call. 1361 * This operation is faster than converting a DateMidnight to a MutableDateTime 1362 * and back again when setting one field. When setting multiple fields, 1363 * it is generally quicker to make the conversion to MutableDateTime. 1364 * 1365 * @param text the text value to set 1366 * @param locale optional locale to use for selecting a text symbol 1367 * @return a copy of the DateMidnight with the field value changed 1368 * @throws IllegalArgumentException if the text value isn't valid 1369 */ 1370 public DateMidnight setCopy(String text, Locale locale) { 1371 return iInstant.withMillis(iField.set(iInstant.getMillis(), text, locale)); 1372 } 1373 1374 /** 1375 * Sets this field in a copy of the DateMidnight to a parsed text value. 1376 * <p> 1377 * The DateMidnight attached to this property is unchanged by this call. 1378 * This operation is faster than converting a DateMidnight to a MutableDateTime 1379 * and back again when setting one field. When setting multiple fields, 1380 * it is generally quicker to make the conversion to MutableDateTime. 1381 * 1382 * @param text the text value to set 1383 * @return a copy of the DateMidnight with the field value changed 1384 * @throws IllegalArgumentException if the text value isn't valid 1385 */ 1386 public DateMidnight setCopy(String text) { 1387 return setCopy(text, null); 1388 } 1389 1390 //----------------------------------------------------------------------- 1391 /** 1392 * Returns a new DateMidnight with this field set to the maximum value 1393 * for this field. 1394 * <p> 1395 * This operation is useful for obtaining a DateTime on the last day 1396 * of the month, as month lengths vary. 1397 * <pre> 1398 * DateMidnight lastDayOfMonth = dt.dayOfMonth().withMaximumValue(); 1399 * </pre> 1400 * <p> 1401 * The DateMidnight attached to this property is unchanged by this call. 1402 * 1403 * @return a copy of the DateMidnight with this field set to its maximum 1404 * @since 1.2 1405 */ 1406 public DateMidnight withMaximumValue() { 1407 return setCopy(getMaximumValue()); 1408 } 1409 1410 /** 1411 * Returns a new DateMidnight with this field set to the minimum value 1412 * for this field. 1413 * <p> 1414 * The DateMidnight attached to this property is unchanged by this call. 1415 * 1416 * @return a copy of the DateMidnight with this field set to its minimum 1417 * @since 1.2 1418 */ 1419 public DateMidnight withMinimumValue() { 1420 return setCopy(getMinimumValue()); 1421 } 1422 1423 //----------------------------------------------------------------------- 1424 /** 1425 * Rounds to the lowest whole unit of this field on a copy of this DateMidnight. 1426 * 1427 * @return a copy of the DateMidnight with the field value changed 1428 */ 1429 public DateMidnight roundFloorCopy() { 1430 return iInstant.withMillis(iField.roundFloor(iInstant.getMillis())); 1431 } 1432 1433 /** 1434 * Rounds to the highest whole unit of this field on a copy of this DateMidnight. 1435 * 1436 * @return a copy of the DateMidnight with the field value changed 1437 */ 1438 public DateMidnight roundCeilingCopy() { 1439 return iInstant.withMillis(iField.roundCeiling(iInstant.getMillis())); 1440 } 1441 1442 /** 1443 * Rounds to the nearest whole unit of this field on a copy of this DateMidnight, 1444 * favoring the floor if halfway. 1445 * 1446 * @return a copy of the DateMidnight with the field value changed 1447 */ 1448 public DateMidnight roundHalfFloorCopy() { 1449 return iInstant.withMillis(iField.roundHalfFloor(iInstant.getMillis())); 1450 } 1451 1452 /** 1453 * Rounds to the nearest whole unit of this field on a copy of this DateMidnight, 1454 * favoring the ceiling if halfway. 1455 * 1456 * @return a copy of the DateMidnight with the field value changed 1457 */ 1458 public DateMidnight roundHalfCeilingCopy() { 1459 return iInstant.withMillis(iField.roundHalfCeiling(iInstant.getMillis())); 1460 } 1461 1462 /** 1463 * Rounds to the nearest whole unit of this field on a copy of this DateMidnight. 1464 * If halfway, the ceiling is favored over the floor only if it makes this field's value even. 1465 * 1466 * @return a copy of the DateMidnight with the field value changed 1467 */ 1468 public DateMidnight roundHalfEvenCopy() { 1469 return iInstant.withMillis(iField.roundHalfEven(iInstant.getMillis())); 1470 } 1471 1472 } 1473 }