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
307 * @param dayOfMonth the day of the month
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
322 * @param dayOfMonth the day of the month
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
338 * @param monthOfYear the month of the year
339 * @param dayOfMonth the day of the month
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 }