KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > joda > time > DateMidnight


1 /*
2  * Copyright 2001-2006 Stephen Colebourne
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.joda.time;
17
18 import java.io.IOException JavaDoc;
19 import java.io.ObjectInputStream JavaDoc;
20 import java.io.ObjectOutputStream JavaDoc;
21 import java.io.Serializable JavaDoc;
22 import java.util.Locale JavaDoc;
23
24 import org.joda.time.base.BaseDateTime;
25 import org.joda.time.field.AbstractReadableInstantFieldProperty;
26 import org.joda.time.format.ISODateTimeFormat;
27
28 /**
29  * DateMidnight defines a date where the time component is fixed at midnight.
30  * The class uses a time zone, thus midnight is local unless a UTC time zone is used.
31  * <p>
32  * It is important to emphasise that this class represents the time of midnight on
33  * any given day.
34  * Note that midnight is defined as 00:00, which is at the very start of a day.
35  * <p>
36  * This class does not represent a day, but the millisecond instant at midnight.
37  * If you need a class that represents the whole day, then an {@link Interval} or
38  * a {@link LocalDate} may be more suitable.
39  * <p>
40  * This class uses a Chronology internally. The Chronology determines how the
41  * millisecond instant value is converted into the date time fields.
42  * The default Chronology is <code>ISOChronology</code> which is the agreed
43  * international standard and compatable with the modern Gregorian calendar.
44  *
45  * <p>Each individual field can be queried in two ways:
46  * <ul>
47  * <li><code>getDayOfMonth()</code>
48  * <li><code>dayOfMonth().get()</code>
49  * </ul>
50  * The second technique also provides access to other useful methods on the
51  * field:
52  * <ul>
53  * <li>numeric value
54  * <li>text value
55  * <li>short text value
56  * <li>maximum/minimum values
57  * <li>add/subtract
58  * <li>set
59  * <li>rounding
60  * </ul>
61  *
62  * <p>
63  * DateMidnight is thread-safe and immutable, provided that the Chronology is as well.
64  * All standard Chronology classes supplied are thread-safe and immutable.
65  *
66  * @author Stephen Colebourne
67  * @since 1.0
68  */

69 public final class DateMidnight
70         extends BaseDateTime
71         implements ReadableDateTime, Serializable JavaDoc {
72     
73     /** Serialization lock */
74     private static final long serialVersionUID = 156371964018738L;
75
76     // Constructors
77
//-----------------------------------------------------------------------
78
/**
79      * Constructs an instance set to the current system millisecond time
80      * using <code>ISOChronology</code> in the default time zone.
81      * The constructed object will have a local time of midnight.
82      */

83     public DateMidnight() {
84         super();
85     }
86
87     /**
88      * Constructs an instance set to the current system millisecond time
89      * using <code>ISOChronology</code> in the specified time zone.
90      * The constructed object will have a local time of midnight.
91      * <p>
92      * If the specified time zone is null, the default zone is used.
93      *
94      * @param zone the time zone, null means default zone
95      */

96     public DateMidnight(DateTimeZone zone) {
97         super(zone);
98     }
99
100     /**
101      * Constructs an instance set to the current system millisecond time
102      * using the specified chronology.
103      * The constructed object will have a local time of midnight.
104      * <p>
105      * If the chronology is null, <code>ISOChronology</code>
106      * in the default time zone is used.
107      *
108      * @param chronology the chronology, null means ISOChronology in default zone
109      */

110     public DateMidnight(Chronology chronology) {
111         super(chronology);
112     }
113
114     //-----------------------------------------------------------------------
115
/**
116      * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z
117      * using <code>ISOChronology</code> in the default time zone.
118      * The constructed object will have a local time of midnight.
119      *
120      * @param instant the milliseconds from 1970-01-01T00:00:00Z
121      */

122     public DateMidnight(long instant) {
123         super(instant);
124     }
125
126     /**
127      * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z
128      * using <code>ISOChronology</code> in the specified time zone.
129      * The constructed object will have a local time of midnight.
130      * <p>
131      * If the specified time zone is null, the default zone is used.
132      *
133      * @param instant the milliseconds from 1970-01-01T00:00:00Z
134      * @param zone the time zone, null means default zone
135      */

136     public DateMidnight(long instant, DateTimeZone zone) {
137         super(instant, zone);
138     }
139
140     /**
141      * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z
142      * using the specified chronology.
143      * The constructed object will have a local time of midnight.
144      * <p>
145      * If the chronology is null, <code>ISOChronology</code>
146      * in the default time zone is used.
147      *
148      * @param instant the milliseconds from 1970-01-01T00:00:00Z
149      * @param chronology the chronology, null means ISOChronology in default zone
150      */

151     public DateMidnight(long instant, Chronology chronology) {
152         super(instant, chronology);
153     }
154
155     //-----------------------------------------------------------------------
156
/**
157      * Constructs an instance from an Object that represents a datetime.
158      * The constructed object will have a local time of midnight.
159      * <p>
160      * If the object implies a chronology (such as GregorianCalendar does),
161      * then that chronology will be used. Otherwise, ISO default is used.
162      * Thus if a GregorianCalendar is passed in, the chronology used will
163      * be GJ, but if a Date is passed in the chronology will be ISO.
164      * <p>
165      * The recognised object types are defined in
166      * {@link org.joda.time.convert.ConverterManager ConverterManager} and
167      * include ReadableInstant, String, Calendar and Date.
168      * The String formats are described by {@link ISODateTimeFormat#dateTimeParser()}.
169      *
170      * @param instant the datetime object, null means now
171      * @throws IllegalArgumentException if the instant is invalid
172      */

173     public DateMidnight(Object JavaDoc instant) {
174         super(instant, (Chronology) null);
175     }
176
177     /**
178      * Constructs an instance from an Object that represents a datetime,
179      * forcing the time zone to that specified.
180      * The constructed object will have a local time of midnight.
181      * <p>
182      * If the object implies a chronology (such as GregorianCalendar does),
183      * then that chronology will be used, but with the time zone adjusted.
184      * Otherwise, ISO is used in the specified time zone.
185      * If the specified time zone is null, the default zone is used.
186      * Thus if a GregorianCalendar is passed in, the chronology used will
187      * be GJ, but if a Date is passed in the chronology will be ISO.
188      * <p>
189      * The recognised object types are defined in
190      * {@link org.joda.time.convert.ConverterManager ConverterManager} and
191      * include ReadableInstant, String, Calendar and Date.
192      * The String formats are described by {@link ISODateTimeFormat#dateTimeParser()}.
193      *
194      * @param instant the datetime object, null means now
195      * @param zone the time zone, null means default time zone
196      * @throws IllegalArgumentException if the instant is invalid
197      */

198     public DateMidnight(Object JavaDoc instant, DateTimeZone zone) {
199         super(instant, zone);
200     }
201
202     /**
203      * Constructs an instance from an Object that represents a datetime,
204      * using the specified chronology.
205      * The constructed object will have a local time of midnight.
206      * <p>
207      * If the chronology is null, ISO in the default time zone is used.
208      * Any chronology implied by the object (such as GregorianCalendar does)
209      * is ignored.
210      * <p>
211      * The recognised object types are defined in
212      * {@link org.joda.time.convert.ConverterManager ConverterManager} and
213      * include ReadableInstant, String, Calendar and Date.
214      * The String formats are described by {@link ISODateTimeFormat#dateTimeParser()}.
215      *
216      * @param instant the datetime object, null means now
217      * @param chronology the chronology, null means ISOChronology in default zone
218      * @throws IllegalArgumentException if the instant is invalid
219      */

220     public DateMidnight(Object JavaDoc instant, Chronology chronology) {
221         super(instant, DateTimeUtils.getChronology(chronology));
222     }
223
224     //-----------------------------------------------------------------------
225
/**
226      * Constructs an instance from datetime field values
227      * using <code>ISOChronology</code> in the default time zone.
228      * The constructed object will have a local time of midnight.
229      *
230      * @param year the year
231      * @param monthOfYear the month of the year
232      * @param dayOfMonth the day of the month
233      */

234     public DateMidnight(int year, int monthOfYear, int dayOfMonth) {
235         super(year, monthOfYear, dayOfMonth, 0, 0, 0, 0);
236     }
237
238     /**
239      * Constructs an instance from datetime field values
240      * using <code>ISOChronology</code> in the specified time zone.
241      * The constructed object will have a local time of midnight.
242      * <p>
243      * If the specified time zone is null, the default zone is used.
244      *
245      * @param year the year
246      * @param monthOfYear the month of the year
247      * @param dayOfMonth the day of the month
248      * @param zone the time zone, null means default time zone
249      */

250     public DateMidnight(int year, int monthOfYear, int dayOfMonth, DateTimeZone zone) {
251         super(year, monthOfYear, dayOfMonth, 0, 0, 0, 0, zone);
252     }
253
254     /**
255      * Constructs an instance from datetime field values
256      * using the specified chronology.
257      * The constructed object will have a local time of midnight.
258      * <p>
259      * If the chronology is null, <code>ISOChronology</code>
260      * in the default time zone is used.
261      *
262      * @param year the year
263      * @param monthOfYear the month of the year
264      * @param dayOfMonth the day of the month
265      * @param chronology the chronology, null means ISOChronology in default zone
266      */

267     public DateMidnight(int year, int monthOfYear, int dayOfMonth, Chronology chronology) {
268         super(year, monthOfYear, dayOfMonth, 0, 0, 0, 0, chronology);
269     }
270
271     /**
272      * Rounds the specified instant to midnight.
273      *
274      * @param instant the milliseconds from 1970-01-01T00:00:00Z to round
275      * @param chronology the chronology to use, not null
276      * @return the updated instant, rounded to midnight
277      */

278     protected long checkInstant(long instant, Chronology chronology) {
279         return chronology.dayOfMonth().roundFloor(instant);
280     }
281
282     //-----------------------------------------------------------------------
283
/**
284      * Returns a copy of this date with a different millisecond instant.
285      * The returned object will have a local time of midnight.
286      * <p>
287      * Only the millis will change, the chronology and time zone are kept.
288      * The returned object will be either be a new instance or <code>this</code>.
289      *
290      * @param newMillis the new millis, from 1970-01-01T00:00:00Z
291      * @return a copy of this instant with different millis
292      */

293     public DateMidnight withMillis(long newMillis) {
294         Chronology chrono = getChronology();
295         newMillis = checkInstant(newMillis, chrono);
296         return (newMillis == getMillis() ? this : new DateMidnight(newMillis, chrono));
297     }
298
299     /**
300      * Returns a copy of this date with a different chronology, potentially
301      * changing the day in unexpected ways.
302      * <p>
303      * This method creates a new DateMidnight using the midnight millisecond value
304      * and the new chronology. If the same or similar chronology is specified, but
305      * with a different time zone, the day may change. This occurs because the new
306      * DateMidnight rounds down the millisecond value to get to midnight, and the
307      * time zone change may result in a rounding down to a different day.
308      * <p>
309      * For example, changing time zone from London (+00:00) to Paris (+01:00) will
310      * retain the same day, but changing from Paris to London will change the day.
311      * (When its midnight in London its the same day in Paris, but when its midnight
312      * in Paris its still the previous day in London)
313      * <p>
314      * To avoid these unusual effects, use {@link #withZoneRetainFields(DateTimeZone)}
315      * to change time zones.
316      *
317      * @param newChronology the new chronology
318      * @return a copy of this instant with a different chronology
319      */

320     public DateMidnight withChronology(Chronology newChronology) {
321         return (newChronology == getChronology() ? this : new DateMidnight(getMillis(), newChronology));
322     }
323
324     /**
325      * Returns a copy of this date with a different time zone, preserving the day
326      * The returned object will have a local time of midnight in the new zone on
327      * the same day as the original instant.
328      *
329      * @param newZone the new time zone, null means default
330      * @return a copy of this instant with a different time zone
331      */

332     public DateMidnight withZoneRetainFields(DateTimeZone newZone) {
333         newZone = DateTimeUtils.getZone(newZone);
334         DateTimeZone originalZone = DateTimeUtils.getZone(getZone());
335         if (newZone == originalZone) {
336             return this;
337         }
338         
339         long millis = originalZone.getMillisKeepLocal(newZone, getMillis());
340         return new DateMidnight(millis, getChronology().withZone(newZone));
341     }
342
343     //-----------------------------------------------------------------------
344
/**
345      * Returns a copy of this date with the partial set of fields replacing those
346      * from this instance.
347      * <p>
348      * For example, if the partial is a <code>LocalDate</code> then the date fields
349      * would be changed in the returned instance.
350      * If the partial is null, then <code>this</code> is returned.
351      *
352      * @param partial the partial set of fields to apply to this datetime, null ignored
353      * @return a copy of this datetime with a different set of fields
354      * @throws IllegalArgumentException if any value is invalid
355      */

356     public DateMidnight withFields(ReadablePartial partial) {
357         if (partial == null) {
358             return this;
359         }
360         return withMillis(getChronology().set(partial, getMillis()));
361     }
362
363     /**
364      * Returns a copy of this date with the specified field set to a new value.
365      * <p>
366      * For example, if the field type is <code>dayOfMonth</code> then the day of month
367      * field would be changed in the returned instance.
368      * If the field type is null, then <code>this</code> is returned.
369      * <p>
370      * These three lines are equivalent:
371      * <pre>
372      * DateTime updated = dt.withField(DateTimeFieldType.dayOfMonth(), 6);
373      * DateTime updated = dt.dayOfMonth().setCopy(6);
374      * DateTime updated = dt.property(DateTimeFieldType.dayOfMonth()).setCopy(6);
375      * </pre>
376      *
377      * @param fieldType the field type to set, not null
378      * @param value the value to set
379      * @return a copy of this datetime with the field set
380      * @throws IllegalArgumentException if the value is null or invalid
381      */

382     public DateMidnight withField(DateTimeFieldType fieldType, int value) {
383         if (fieldType == null) {
384             throw new IllegalArgumentException JavaDoc("Field must not be null");
385         }
386         long instant = fieldType.getField(getChronology()).set(getMillis(), value);
387         return withMillis(instant);
388     }
389
390     /**
391      * Returns a copy of this date with the value of the specified field increased.
392      * <p>
393      * If the addition is zero or the field is null, then <code>this</code> is returned.
394      * <p>
395      * These three lines are equivalent:
396      * <pre>
397      * DateMidnight added = dt.withFieldAdded(DateTimeFieldType.year(), 6);
398      * DateMidnight added = dt.plusYears(6);
399      * DateMidnight added = dt.year().addToCopy(6);
400      * </pre>
401      *
402      * @param fieldType the field type to add to, not null
403      * @param amount the amount to add
404      * @return a copy of this datetime with the field updated
405      * @throws IllegalArgumentException if the value is null or invalid
406      * @throws ArithmeticException if the new datetime exceeds the capacity of a long
407      */

408     public DateMidnight withFieldAdded(DurationFieldType fieldType, int amount) {
409         if (fieldType == null) {
410             throw new IllegalArgumentException JavaDoc("Field must not be null");
411         }
412         if (amount == 0) {
413             return this;
414         }
415         long instant = fieldType.getField(getChronology()).add(getMillis(), amount);
416         return withMillis(instant);
417     }
418
419     //-----------------------------------------------------------------------
420
/**
421      * Returns a copy of this date with the specified duration added.
422      * <p>
423      * If the addition is zero, then <code>this</code> is returned.
424      *
425      * @param durationToAdd the duration to add to this one
426      * @param scalar the amount of times to add, such as -1 to subtract once
427      * @return a copy of this datetime with the duration added
428      * @throws ArithmeticException if the new datetime exceeds the capacity of a long
429      */

430     public DateMidnight withDurationAdded(long durationToAdd, int scalar) {
431         if (durationToAdd == 0 || scalar == 0) {
432             return this;
433         }
434         long instant = getChronology().add(getMillis(), durationToAdd, scalar);
435         return withMillis(instant);
436     }
437
438     /**
439      * Returns a copy of this date with the specified duration added.
440      * <p>
441      * If the addition is zero, then <code>this</code> is returned.
442      *
443      * @param durationToAdd the duration to add to this one, null means zero
444      * @param scalar the amount of times to add, such as -1 to subtract once
445      * @return a copy of this datetime with the duration added
446      * @throws ArithmeticException if the new datetime exceeds the capacity of a long
447      */

448     public DateMidnight withDurationAdded(ReadableDuration durationToAdd, int scalar) {
449         if (durationToAdd == null || scalar == 0) {
450             return this;
451         }
452         return withDurationAdded(durationToAdd.getMillis(), scalar);
453     }
454
455     /**
456      * Returns a copy of this date with the specified period added.
457      * <p>
458      * If the addition is zero, then <code>this</code> is returned.
459      * <p>
460      * This method is typically used to add multiple copies of complex
461      * period instances. Adding one field is best achieved using methods
462      * like {@link #withFieldAdded(DurationFieldType, int)}
463      * or {@link #plusYears(int)}.
464      *
465      * @param period the period to add to this one, null means zero
466      * @param scalar the amount of times to add, such as -1 to subtract once
467      * @return a copy of this datetime with the period added
468      * @throws ArithmeticException if the new datetime exceeds the capacity of a long
469      */

470     public DateMidnight withPeriodAdded(ReadablePeriod period, int scalar) {
471         if (period == null || scalar == 0) {
472             return this;
473         }
474         long instant = getChronology().add(period, getMillis(), scalar);
475         return withMillis(instant);
476     }
477
478     //-----------------------------------------------------------------------
479
/**
480      * Returns a copy of this date with the specified duration added.
481      * <p>
482      * If the amount is zero, then <code>this</code> is returned.
483      *
484      * @param duration the duration, in millis, to add to this one
485      * @return a copy of this datetime with the duration added
486      * @throws ArithmeticException if the new datetime exceeds the capacity of a long
487      */

488     public DateMidnight plus(long duration) {
489         return withDurationAdded(duration, 1);
490     }
491
492     /**
493      * Returns a copy of this date with the specified duration added.
494      * <p>
495      * If the amount is zero or null, then <code>this</code> is returned.
496      *
497      * @param duration the duration to add to this one, null means zero
498      * @return a copy of this datetime with the duration added
499      * @throws ArithmeticException if the new datetime exceeds the capacity of a long
500      */

501     public DateMidnight plus(ReadableDuration duration) {
502         return withDurationAdded(duration, 1);
503     }
504
505     /**
506      * Returns a copy of this date with the specified period added.
507      * <p>
508      * If the amount is zero or null, then <code>this</code> is returned.
509      * <p>
510      * This method is typically used to add complex period instances.
511      * Adding one field is best achieved using methods
512      * like {@link #plusYears(int)}.
513      *
514      * @param period the duration to add to this one, null means zero
515      * @return a copy of this datetime with the period added
516      * @throws ArithmeticException if the new datetime exceeds the capacity of a long
517      */

518     public DateMidnight plus(ReadablePeriod period) {
519         return withPeriodAdded(period, 1);
520     }
521
522     //-----------------------------------------------------------------------
523
/**
524      * Returns a copy of this date plus the specified number of years.
525      * <p>
526      * This datetime instance is immutable and unaffected by this method call.
527      * <p>
528      * The following three lines are identical in effect:
529      * <pre>
530      * DateMidnight added = dt.plusYears(6);
531      * DateMidnight added = dt.plus(Period.years(6));
532      * DateMidnight added = dt.withFieldAdded(DurationFieldType.years(), 6);
533      * </pre>
534      *
535      * @param years the amount of years to add, may be negative
536      * @return the new datetime plus the increased years
537      * @since 1.1
538      */

539     public DateMidnight plusYears(int years) {
540         if (years == 0) {
541             return this;
542         }
543         long instant = getChronology().years().add(getMillis(), years);
544         return withMillis(instant);
545     }
546
547     /**
548      * Returns a copy of this date plus the specified number of months.
549      * <p>
550      * This datetime instance is immutable and unaffected by this method call.
551      * <p>
552      * The following three lines are identical in effect:
553      * <pre>
554      * DateMidnight added = dt.plusMonths(6);
555      * DateMidnight added = dt.plus(Period.months(6));
556      * DateMidnight added = dt.withFieldAdded(DurationFieldType.months(), 6);
557      * </pre>
558      *
559      * @param months the amount of months to add, may be negative
560      * @return the new datetime plus the increased months
561      * @since 1.1
562      */

563     public DateMidnight plusMonths(int months) {
564         if (months == 0) {
565             return this;
566         }
567         long instant = getChronology().months().add(getMillis(), months);
568         return withMillis(instant);
569     }
570
571     /**
572      * Returns a copy of this date plus the specified number of weeks.
573      * <p>
574      * This datetime instance is immutable and unaffected by this method call.
575      * <p>
576      * The following three lines are identical in effect:
577      * <pre>
578      * DateMidnight added = dt.plusWeeks(6);
579      * DateMidnight added = dt.plus(Period.weeks(6));
580      * DateMidnight added = dt.withFieldAdded(DurationFieldType.weeks(), 6);
581      * </pre>
582      *
583      * @param weeks the amount of weeks to add, may be negative
584      * @return the new datetime plus the increased weeks
585      * @since 1.1
586      */

587     public DateMidnight plusWeeks(int weeks) {
588         if (weeks == 0) {
589             return this;
590         }
591         long instant = getChronology().weeks().add(getMillis(), weeks);
592         return withMillis(instant);
593     }
594
595     /**
596      * Returns a copy of this date plus the specified number of days.
597      * <p>
598      * This datetime instance is immutable and unaffected by this method call.
599      * <p>
600      * The following three lines are identical in effect:
601      * <pre>
602      * DateMidnight added = dt.plusDays(6);
603      * DateMidnight added = dt.plus(Period.days(6));
604      * DateMidnight added = dt.withFieldAdded(DurationFieldType.days(), 6);
605      * </pre>
606      *
607      * @param days the amount of days to add, may be negative
608      * @return the new datetime plus the increased days
609      * @since 1.1
610      */

611     public DateMidnight plusDays(int days) {
612         if (days == 0) {
613             return this;
614         }
615         long instant = getChronology().days().add(getMillis(), days);
616         return withMillis(instant);
617     }
618
619     //-----------------------------------------------------------------------
620
/**
621      * Returns a copy of this date with the specified duration taken away.
622      * <p>
623      * If the amount is zero or null, then <code>this</code> is returned.
624      *
625      * @param duration the duration, in millis, to reduce this instant by
626      * @return a copy of this datetime with the duration taken away
627      * @throws ArithmeticException if the new datetime exceeds the capacity of a long
628      */

629     public DateMidnight minus(long duration) {
630         return withDurationAdded(duration, -1);
631     }
632
633     /**
634      * Returns a copy of this date with the specified duration taken away.
635      * <p>
636      * If the amount is zero or null, then <code>this</code> is returned.
637      *
638      * @param duration the duration to reduce this instant by
639      * @return a copy of this datetime with the duration taken away
640      * @throws ArithmeticException if the new datetime exceeds the capacity of a long
641      */

642     public DateMidnight minus(ReadableDuration duration) {
643         return withDurationAdded(duration, -1);
644     }
645
646     /**
647      * Returns a copy of this date with the specified period taken away.
648      * <p>
649      * If the amount is zero or null, then <code>this</code> is returned.
650      * <p>
651      * This method is typically used to subtract complex period instances.
652      * Subtracting one field is best achieved using methods
653      * like {@link #minusYears(int)}.
654      *
655      * @param period the period to reduce this instant by
656      * @return a copy of this datetime with the period taken away
657      * @throws ArithmeticException if the new datetime exceeds the capacity of a long
658      */

659     public DateMidnight minus(ReadablePeriod period) {
660         return withPeriodAdded(period, -1);
661     }
662
663     //-----------------------------------------------------------------------
664
/**
665      * Returns a copy of this date minus the specified number of years.
666      * <p>
667      * This datetime instance is immutable and unaffected by this method call.
668      * <p>
669      * The following three lines are identical in effect:
670      * <pre>
671      * DateTime subtracted = dt.minusYears(6);
672      * DateTime subtracted = dt.minus(Period.years(6));
673      * DateTime subtracted = dt.withFieldAdded(DurationFieldType.years(), -6);
674      * </pre>
675      *
676      * @param years the amount of years to subtract, may be negative
677      * @return the new datetime minus the increased years
678      * @since 1.1
679      */

680     public DateMidnight minusYears(int years) {
681         if (years == 0) {
682             return this;
683         }
684         long instant = getChronology().years().subtract(getMillis(), years);
685         return withMillis(instant);
686     }
687
688     /**
689      * Returns a copy of this date minus the specified number of months.
690      * <p>
691      * This datetime instance is immutable and unaffected by this method call.
692      * <p>
693      * The following three lines are identical in effect:
694      * <pre>
695      * DateMidnight subtracted = dt.minusMonths(6);
696      * DateMidnight subtracted = dt.minus(Period.months(6));
697      * DateMidnight subtracted = dt.withFieldAdded(DurationFieldType.months(), -6);
698      * </pre>
699      *
700      * @param months the amount of months to subtract, may be negative
701      * @return the new datetime minus the increased months
702      * @since 1.1
703      */

704     public DateMidnight minusMonths(int months) {
705         if (months == 0) {
706             return this;
707         }
708         long instant = getChronology().months().subtract(getMillis(), months);
709         return withMillis(instant);
710     }
711
712     /**
713      * Returns a copy of this date minus the specified number of weeks.
714      * <p>
715      * This datetime instance is immutable and unaffected by this method call.
716      * <p>
717      * The following three lines are identical in effect:
718      * <pre>
719      * DateMidnight subtracted = dt.minusWeeks(6);
720      * DateMidnight subtracted = dt.minus(Period.weeks(6));
721      * DateMidnight subtracted = dt.withFieldAdded(DurationFieldType.weeks(), -6);
722      * </pre>
723      *
724      * @param weeks the amount of weeks to subtract, may be negative
725      * @return the new datetime minus the increased weeks
726      * @since 1.1
727      */

728     public DateMidnight minusWeeks(int weeks) {
729         if (weeks == 0) {
730             return this;
731         }
732         long instant = getChronology().weeks().subtract(getMillis(), weeks);
733         return withMillis(instant);
734     }
735
736     /**
737      * Returns a copy of this date minus the specified number of days.
738      * <p>
739      * This datetime instance is immutable and unaffected by this method call.
740      * <p>
741      * The following three lines are identical in effect:
742      * <pre>
743      * DateMidnight subtracted = dt.minusDays(6);
744      * DateMidnight subtracted = dt.minus(Period.days(6));
745      * DateMidnight subtracted = dt.withFieldAdded(DurationFieldType.days(), -6);
746      * </pre>
747      *
748      * @param days the amount of days to subtract, may be negative
749      * @return the new datetime minus the increased days
750      * @since 1.1
751      */

752     public DateMidnight minusDays(int days) {
753         if (days == 0) {
754             return this;
755         }
756         long instant = getChronology().days().subtract(getMillis(), days);
757         return withMillis(instant);
758     }
759
760     //-----------------------------------------------------------------------
761
/**
762      * Gets the property object for the specified type, which contains many useful methods.
763      *
764      * @param type the field type to get the chronology for
765      * @return the property object
766      * @throws IllegalArgumentException if the field is null or unsupported
767      */

768     public Property property(DateTimeFieldType type) {
769         if (type == null) {
770             throw new IllegalArgumentException JavaDoc("The DateTimeFieldType must not be null");
771         }
772         DateTimeField field = type.getField(getChronology());
773         if (field.isSupported() == false) {
774             throw new IllegalArgumentException JavaDoc("Field '" + type + "' is not supported");
775         }
776         return new Property(this, field);
777     }
778
779     //-----------------------------------------------------------------------
780
/**
781      * Converts this object to a <code>YearMonthDay</code> using the
782      * same date and chronology.
783      *
784      * @return a YearMonthDay using the same millis and chronology
785      */

786     public YearMonthDay toYearMonthDay() {
787         return new YearMonthDay(getMillis(), getChronology());
788     }
789
790     /**
791      * Converts this object to a <code>LocalDate</code> with the
792      * same date and chronology.
793      *
794      * @return a LocalDate with the same date and chronology
795      * @since 1.3
796      */

797     public LocalDate toLocalDate() {
798         return new LocalDate(getMillis(), getChronology());
799     }
800
801     /**
802      * Converts this object to an <code>Interval</code> encompassing
803      * the whole of this day.
804      * <p>
805      * The interval starts at midnight 00:00 and ends at 00:00 the following day,
806      * (which is not included in the interval, as intervals are half-open).
807      *
808      * @return an interval over the day
809      */

810     public Interval toInterval() {
811         Chronology chrono = getChronology();
812         long start = getMillis();
813         long end = DurationFieldType.days().getField(chrono).add(start, 1);
814         return new Interval(start, end, chrono);
815     }
816
817     //-----------------------------------------------------------------------
818
/**
819      * Returns a copy of this date with the era field updated.
820      * <p>
821      * DateMidnight is immutable, so there are no set methods.
822      * Instead, this method returns a new instance with the value of
823      * era changed.
824      *
825      * @param era the era to set
826      * @return a copy of this object with the field set
827      * @throws IllegalArgumentException if the value is invalid
828      * @since 1.3
829      */

830     public DateMidnight withEra(int era) {
831         return withMillis(getChronology().era().set(getMillis(), era));
832     }
833
834     /**
835      * Returns a copy of this date with the century of era field updated.
836      * <p>
837      * DateMidnight is immutable, so there are no set methods.
838      * Instead, this method returns a new instance with the value of
839      * century of era changed.
840      *
841      * @param centuryOfEra the centurey of era to set
842      * @return a copy of this object with the field set
843      * @throws IllegalArgumentException if the value is invalid
844      * @since 1.3
845      */

846     public DateMidnight withCenturyOfEra(int centuryOfEra) {
847         return withMillis(getChronology().centuryOfEra().set(getMillis(), centuryOfEra));
848     }
849
850     /**
851      * Returns a copy of this date with the year of era field updated.
852      * <p>
853      * DateMidnight is immutable, so there are no set methods.
854      * Instead, this method returns a new instance with the value of
855      * year of era changed.
856      *
857      * @param yearOfEra the year of era to set
858      * @return a copy of this object with the field set
859      * @throws IllegalArgumentException if the value is invalid
860      * @since 1.3
861      */

862     public DateMidnight withYearOfEra(int yearOfEra) {
863         return withMillis(getChronology().yearOfEra().set(getMillis(), yearOfEra));
864     }
865
866     /**
867      * Returns a copy of this date with the year of century field updated.
868      * <p>
869      * DateMidnight is immutable, so there are no set methods.
870      * Instead, this method returns a new instance with the value of
871      * year of century changed.
872      *
873      * @param yearOfCentury the year of century to set
874      * @return a copy of this object with the field set
875      * @throws IllegalArgumentException if the value is invalid
876      * @since 1.3
877      */

878     public DateMidnight withYearOfCentury(int yearOfCentury) {
879         return withMillis(getChronology().yearOfCentury().set(getMillis(), yearOfCentury));
880     }
881
882     /**
883      * Returns a copy of this date with the year field updated.
884      * <p>
885      * DateMidnight is immutable, so there are no set methods.
886      * Instead, this method returns a new instance with the value of
887      * year changed.
888      *
889      * @param year the year to set
890      * @return a copy of this object with the field set
891      * @throws IllegalArgumentException if the value is invalid
892      * @since 1.3
893      */

894     public DateMidnight withYear(int year) {
895         return withMillis(getChronology().year().set(getMillis(), year));
896     }
897
898     /**
899      * Returns a copy of this date with the weekyear field updated.
900      * <p>
901      * DateMidnight is immutable, so there are no set methods.
902      * Instead, this method returns a new instance with the value of
903      * weekyear changed.
904      *
905      * @param weekyear the weekyear to set
906      * @return a copy of this object with the field set
907      * @throws IllegalArgumentException if the value is invalid
908      * @since 1.3
909      */

910     public DateMidnight withWeekyear(int weekyear) {
911         return withMillis(getChronology().weekyear().set(getMillis(), weekyear));
912     }
913
914     /**
915      * Returns a copy of this date with the month of year field updated.
916      * <p>
917      * DateMidnight is immutable, so there are no set methods.
918      * Instead, this method returns a new instance with the value of
919      * month of year changed.
920      *
921      * @param monthOfYear the month of year to set
922      * @return a copy of this object with the field set
923      * @throws IllegalArgumentException if the value is invalid
924      * @since 1.3
925      */

926     public DateMidnight withMonthOfYear(int monthOfYear) {
927         return withMillis(getChronology().monthOfYear().set(getMillis(), monthOfYear));
928     }
929
930     /**
931      * Returns a copy of this date with the week of weekyear field updated.
932      * <p>
933      * DateMidnight is immutable, so there are no set methods.
934      * Instead, this method returns a new instance with the value of
935      * week of weekyear changed.
936      *
937      * @param weekOfWeekyear the week of weekyear to set
938      * @return a copy of this object with the field set
939      * @throws IllegalArgumentException if the value is invalid
940      * @since 1.3
941      */

942     public DateMidnight withWeekOfWeekyear(int weekOfWeekyear) {
943         return withMillis(getChronology().weekOfWeekyear().set(getMillis(), weekOfWeekyear));
944     }
945
946     /**
947      * Returns a copy of this date with the day of year field updated.
948      * <p>
949      * DateMidnight is immutable, so there are no set methods.
950      * Instead, this method returns a new instance with the value of
951      * day of year changed.
952      *
953      * @param dayOfYear the day of year to set
954      * @return a copy of this object with the field set
955      * @throws IllegalArgumentException if the value is invalid
956      * @since 1.3
957      */

958     public DateMidnight withDayOfYear(int dayOfYear) {
959         return withMillis(getChronology().dayOfYear().set(getMillis(), dayOfYear));
960     }
961
962     /**
963      * Returns a copy of this date with the day of month field updated.
964      * <p>
965      * DateMidnight is immutable, so there are no set methods.
966      * Instead, this method returns a new instance with the value of
967      * day of month changed.
968      *
969      * @param dayOfMonth the day of month to set
970      * @return a copy of this object with the field set
971      * @throws IllegalArgumentException if the value is invalid
972      * @since 1.3
973      */

974     public DateMidnight withDayOfMonth(int dayOfMonth) {
975         return withMillis(getChronology().dayOfMonth().set(getMillis(), dayOfMonth));
976     }
977
978     /**
979      * Returns a copy of this date with the day of week field updated.
980      * <p>
981      * DateMidnight is immutable, so there are no set methods.
982      * Instead, this method returns a new instance with the value of
983      * day of week changed.
984      *
985      * @param dayOfWeek the day of week to set
986      * @return a copy of this object with the field set
987      * @throws IllegalArgumentException if the value is invalid
988      * @since 1.3
989      */

990     public DateMidnight withDayOfWeek(int dayOfWeek) {
991         return withMillis(getChronology().dayOfWeek().set(getMillis(), dayOfWeek));
992     }
993
994     // Date properties
995
//-----------------------------------------------------------------------
996
/**
997      * Get the era property which provides access to advanced functionality.
998      *
999      * @return the era property
1000     */

1001    public Property era() {
1002        return new Property(this, getChronology().era());
1003    }
1004
1005    /**
1006     * Get the century of era property which provides access to advanced functionality.
1007     *
1008     * @return the year of era property
1009     */

1010    public Property centuryOfEra() {
1011        return new Property(this, getChronology().centuryOfEra());
1012    }
1013
1014    /**
1015     * Get the year of century property which provides access to advanced functionality.
1016     *
1017     * @return the year of era property
1018     */

1019    public Property yearOfCentury() {
1020        return new Property(this, getChronology().yearOfCentury());
1021    }
1022
1023    /**
1024     * Get the year of era property which provides access to advanced functionality.
1025     *
1026     * @return the year of era property
1027     */

1028    public Property yearOfEra() {
1029        return new Property(this, getChronology().yearOfEra());
1030    }
1031
1032    /**
1033     * Get the year property which provides access to advanced functionality.
1034     *
1035     * @return the year property
1036     */

1037    public Property year() {
1038        return new Property(this, getChronology().year());
1039    }
1040
1041    /**
1042     * Get the year of a week based year property which provides access to advanced functionality.
1043     *
1044     * @return the year of a week based year property
1045     */

1046    public Property weekyear() {
1047        return new Property(this, getChronology().weekyear());
1048    }
1049
1050    /**
1051     * Get the month of year property which provides access to advanced functionality.
1052     *
1053     * @return the month of year property
1054     */

1055    public Property monthOfYear() {
1056        return new Property(this, getChronology().monthOfYear());
1057    }
1058
1059    /**
1060     * Get the week of a week based year property which provides access to advanced functionality.
1061     *
1062     * @return the week of a week based year property
1063     */

1064    public Property weekOfWeekyear() {
1065        return new Property(this, getChronology().weekOfWeekyear());
1066    }
1067
1068    /**
1069     * Get the day of year property which provides access to advanced functionality.
1070     *
1071     * @return the day of year property
1072     */

1073    public Property dayOfYear() {
1074        return new Property(this, getChronology().dayOfYear());
1075    }
1076
1077    /**
1078     * Get the day of month property which provides access to advanced functionality.
1079     *
1080     * @return the day of month property
1081     */

1082    public Property dayOfMonth() {
1083        return new Property(this, getChronology().dayOfMonth());
1084    }
1085
1086    /**
1087     * Get the day of week property which provides access to advanced functionality.
1088     *
1089     * @return the day of week property
1090     */

1091    public Property dayOfWeek() {
1092        return new Property(this, getChronology().dayOfWeek());
1093    }
1094
1095    //-----------------------------------------------------------------------
1096
/**
1097     * DateMidnight.Property binds a DateMidnight to a DateTimeField allowing powerful
1098     * datetime functionality to be easily accessed.
1099     * <p>
1100     * The simplest use of this class is as an alternative get method, here used to
1101     * get the year '1972' (as an int) and the month 'December' (as a String).
1102     * <pre>
1103     * DateMidnight dt = new DateMidnight(1972, 12, 3);
1104     * int year = dt.year().get();
1105     * String monthStr = dt.monthOfYear().getAsText();
1106     * </pre>
1107     * <p>
1108     * Methods are also provided that allow date modification. These return new instances
1109     * of DateMidnight - they do not modify the original. The example below yields two
1110     * independent immutable date objects 20 years apart.
1111     * <pre>
1112     * DateMidnight dt = new DateMidnight(1972, 12, 3);
1113     * DateMidnight dt20 = dt.year().addToCopy(20);
1114     * </pre>
1115     * Serious modification of dates (ie. more than just changing one or two fields)
1116     * should use the {@link org.joda.time.MutableDateTime MutableDateTime} class.
1117     * <p>
1118     * DateMidnight.Property itself is thread-safe and immutable.
1119     *
1120     * @author Stephen Colebourne
1121     * @author Brian S O'Neill
1122     * @since 1.0
1123     */

1124    public static final class Property extends AbstractReadableInstantFieldProperty {
1125    
1126        /** Serialization lock */
1127        private static final long serialVersionUID = 257629620L;
1128        
1129        /** The instant this property is working against */
1130        private DateMidnight iInstant;
1131        /** The field this property is working against */
1132        private DateTimeField iField;
1133        
1134        /**
1135         * Constructor.
1136         *
1137         * @param instant the instant to set
1138         * @param field the field to use
1139         */

1140        Property(DateMidnight instant, DateTimeField field) {
1141            super();
1142            iInstant = instant;
1143            iField = field;
1144        }
1145
1146        /**
1147         * Writes the property in a safe serialization format.
1148         */

1149        private void writeObject(ObjectOutputStream JavaDoc oos) throws IOException JavaDoc {
1150            oos.writeObject(iInstant);
1151            oos.writeObject(iField.getType());
1152        }
1153
1154        /**
1155         * Reads the property from a safe serialization format.
1156         */

1157        private void readObject(ObjectInputStream JavaDoc oos) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
1158            iInstant = (DateMidnight) oos.readObject();
1159            DateTimeFieldType type = (DateTimeFieldType) oos.readObject();
1160            iField = type.getField(iInstant.getChronology());
1161        }
1162
1163        //-----------------------------------------------------------------------
1164
/**
1165         * Gets the field being used.
1166         *
1167         * @return the field
1168         */

1169        public DateTimeField getField() {
1170            return iField;
1171        }
1172
1173        /**
1174         * Gets the milliseconds of the datetime that this property is linked to.
1175         *
1176         * @return the milliseconds
1177         */

1178        protected long getMillis() {
1179            return iInstant.getMillis();
1180        }
1181
1182        /**
1183         * Gets the chronology of the datetime that this property is linked to.
1184         *
1185         * @return the chronology
1186         * @since 1.4
1187         */

1188        protected Chronology getChronology() {
1189            return iInstant.getChronology();
1190        }
1191
1192        /**
1193         * Gets the datetime being used.
1194         *
1195         * @return the datetime
1196         */

1197        public DateMidnight getDateMidnight() {
1198            return iInstant;
1199        }
1200
1201        //-----------------------------------------------------------------------
1202
/**
1203         * Adds to this field in a copy of this DateMidnight.
1204         * <p>
1205         * The DateMidnight attached to this property is unchanged by this call.
1206         * This operation is faster than converting a DateMidnight to a MutableDateTime
1207         * and back again when setting one field. When setting multiple fields,
1208         * it is generally quicker to make the conversion to MutableDateTime.
1209         *
1210         * @param value the value to add to the field in the copy
1211         * @return a copy of the DateMidnight with the field value changed
1212         * @throws IllegalArgumentException if the value isn't valid
1213         */

1214        public DateMidnight addToCopy(int value) {
1215            return iInstant.withMillis(iField.add(iInstant.getMillis(), value));
1216        }
1217
1218        /**
1219         * Adds to this field in a copy of this DateMidnight.
1220         * <p>
1221         * The DateMidnight attached to this property is unchanged by this call.
1222         * This operation is faster than converting a DateMidnight to a MutableDateTime
1223         * and back again when setting one field. When setting multiple fields,
1224         * it is generally quicker to make the conversion to MutableDateTime.
1225         *
1226         * @param value the value to add to the field in the copy
1227         * @return a copy of the DateMidnight with the field value changed
1228         * @throws IllegalArgumentException if the value isn't valid
1229         */

1230        public DateMidnight addToCopy(long value) {
1231            return iInstant.withMillis(iField.add(iInstant.getMillis(), value));
1232        }
1233
1234        /**
1235         * Adds to this field, possibly wrapped, in a copy of this DateMidnight.
1236         * A wrapped operation only changes this field.
1237         * Thus 31st January addWrapField one day goes to the 1st January.
1238         * <p>
1239         * The DateMidnight attached to this property is unchanged by this call.
1240         * This operation is faster than converting a DateMidnight to a MutableDateTime
1241         * and back again when setting one field. When setting multiple fields,
1242         * it is generally quicker to make the conversion to MutableDateTime.
1243         *
1244         * @param value the value to add to the field in the copy
1245         * @return a copy of the DateMidnight with the field value changed
1246         * @throws IllegalArgumentException if the value isn't valid
1247         */

1248        public DateMidnight addWrapFieldToCopy(int value) {
1249            return iInstant.withMillis(iField.addWrapField(iInstant.getMillis(), value));
1250        }
1251
1252        //-----------------------------------------------------------------------
1253
/**
1254         * Sets this field in a copy of the DateMidnight.
1255         * <p>
1256         * The DateMidnight attached to this property is unchanged by this call.
1257         * This operation is faster than converting a DateMidnight to a MutableDateTime
1258         * and back again when setting one field. When setting multiple fields,
1259         * it is generally quicker to make the conversion to MutableDateTime.
1260         *
1261         * @param value the value to set the field in the copy to
1262         * @return a copy of the DateMidnight with the field value changed
1263         * @throws IllegalArgumentException if the value isn't valid
1264         */

1265        public DateMidnight setCopy(int value) {
1266            return iInstant.withMillis(iField.set(iInstant.getMillis(), value));
1267        }
1268    
1269        /**
1270         * Sets this field in a copy of the DateMidnight to a parsed text value.
1271         * <p>
1272         * The DateMidnight attached to this property is unchanged by this call.
1273         * This operation is faster than converting a DateMidnight to a MutableDateTime
1274         * and back again when setting one field. When setting multiple fields,
1275         * it is generally quicker to make the conversion to MutableDateTime.
1276         *
1277         * @param text the text value to set
1278         * @param locale optional locale to use for selecting a text symbol
1279         * @return a copy of the DateMidnight with the field value changed
1280         * @throws IllegalArgumentException if the text value isn't valid
1281         */

1282        public DateMidnight setCopy(String JavaDoc text, Locale JavaDoc locale) {
1283            return iInstant.withMillis(iField.set(iInstant.getMillis(), text, locale));
1284        }
1285
1286        /**
1287         * Sets this field in a copy of the DateMidnight to a parsed text value.
1288         * <p>
1289         * The DateMidnight attached to this property is unchanged by this call.
1290         * This operation is faster than converting a DateMidnight to a MutableDateTime
1291         * and back again when setting one field. When setting multiple fields,
1292         * it is generally quicker to make the conversion to MutableDateTime.
1293         *
1294         * @param text the text value to set
1295         * @return a copy of the DateMidnight with the field value changed
1296         * @throws IllegalArgumentException if the text value isn't valid
1297         */

1298        public DateMidnight setCopy(String JavaDoc text) {
1299            return setCopy(text, null);
1300        }
1301
1302        //-----------------------------------------------------------------------
1303
/**
1304         * Returns a new DateMidnight with this field set to the maximum value
1305         * for this field.
1306         * <p>
1307         * This operation is useful for obtaining a DateTime on the last day
1308         * of the month, as month lengths vary.
1309         * <pre>
1310         * DateMidnight lastDayOfMonth = dt.dayOfMonth().withMaximumValue();
1311         * </pre>
1312         * <p>
1313         * The DateMidnight attached to this property is unchanged by this call.
1314         *
1315         * @return a copy of the DateMidnight with this field set to its maximum
1316         * @since 1.2
1317         */

1318        public DateMidnight withMaximumValue() {
1319            return setCopy(getMaximumValue());
1320        }
1321        
1322        /**
1323         * Returns a new DateMidnight with this field set to the minimum value
1324         * for this field.
1325         * <p>
1326         * The DateMidnight attached to this property is unchanged by this call.
1327         *
1328         * @return a copy of the DateMidnight with this field set to its minimum
1329         * @since 1.2
1330         */

1331        public DateMidnight withMinimumValue() {
1332            return setCopy(getMinimumValue());
1333        }
1334        
1335        //-----------------------------------------------------------------------
1336
/**
1337         * Rounds to the lowest whole unit of this field on a copy of this DateMidnight.
1338         *
1339         * @return a copy of the DateMidnight with the field value changed
1340         */

1341        public DateMidnight roundFloorCopy() {
1342            return iInstant.withMillis(iField.roundFloor(iInstant.getMillis()));
1343        }
1344
1345        /**
1346         * Rounds to the highest whole unit of this field on a copy of this DateMidnight.
1347         *
1348         * @return a copy of the DateMidnight with the field value changed
1349         */

1350        public DateMidnight roundCeilingCopy() {
1351            return iInstant.withMillis(iField.roundCeiling(iInstant.getMillis()));
1352        }
1353
1354        /**
1355         * Rounds to the nearest whole unit of this field on a copy of this DateMidnight,
1356         * favoring the floor if halfway.
1357         *
1358         * @return a copy of the DateMidnight with the field value changed
1359         */

1360        public DateMidnight roundHalfFloorCopy() {
1361            return iInstant.withMillis(iField.roundHalfFloor(iInstant.getMillis()));
1362        }
1363
1364        /**
1365         * Rounds to the nearest whole unit of this field on a copy of this DateMidnight,
1366         * favoring the ceiling if halfway.
1367         *
1368         * @return a copy of the DateMidnight with the field value changed
1369         */

1370        public DateMidnight roundHalfCeilingCopy() {
1371            return iInstant.withMillis(iField.roundHalfCeiling(iInstant.getMillis()));
1372        }
1373
1374        /**
1375         * Rounds to the nearest whole unit of this field on a copy of this DateMidnight.
1376         * If halfway, the ceiling is favored over the floor only if it makes this field's value even.
1377         *
1378         * @return a copy of the DateMidnight with the field value changed
1379         */

1380        public DateMidnight roundHalfEvenCopy() {
1381            return iInstant.withMillis(iField.roundHalfEven(iInstant.getMillis()));
1382        }
1383
1384    }
1385}
1386
Popular Tags