KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * Copyright 2001-2005 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.chrono.ISOChronology;
26 import org.joda.time.field.AbstractReadableInstantFieldProperty;
27 import org.joda.time.field.FieldUtils;
28 import org.joda.time.format.ISODateTimeFormat;
29
30 /**
31  * MutableDateTime is the standard implementation of a modifiable datetime class.
32  * It holds the datetime as milliseconds from the Java epoch of 1970-01-01T00:00:00Z.
33  * <p>
34  * This class uses a Chronology internally. The Chronology determines how the
35  * millisecond instant value is converted into the date time fields.
36  * The default Chronology is <code>ISOChronology</code> which is the agreed
37  * international standard and compatable with the modern Gregorian calendar.
38  * <p>
39  * Each individual field can be accessed in two ways:
40  * <ul>
41  * <li><code>getHourOfDay()</code>
42  * <li><code>hourOfDay().get()</code>
43  * </ul>
44  * The second technique also provides access to other useful methods on the
45  * field:
46  * <ul>
47  * <li>get numeric value
48  * <li>set numeric value
49  * <li>add to numeric value
50  * <li>add to numeric value wrapping with the field
51  * <li>get text vlaue
52  * <li>get short text value
53  * <li>set text value
54  * <li>field maximum value
55  * <li>field minimum value
56  * </ul>
57  *
58  * <p>
59  * MutableDateTime is mutable and not thread-safe, unless concurrent threads
60  * are not invoking mutator methods.
61  *
62  * @author Guy Allard
63  * @author Brian S O'Neill
64  * @author Stephen Colebourne
65  * @author Mike Schrag
66  * @since 1.0
67  * @see DateTime
68  */

69 public class MutableDateTime
70         extends BaseDateTime
71         implements ReadWritableDateTime, Cloneable JavaDoc, Serializable JavaDoc {
72
73     /** Serialization version */
74     private static final long serialVersionUID = 2852608688135209575L;
75
76     /** Rounding is disabled */
77     public static final int ROUND_NONE = 0;
78     /** Rounding mode as described by {@link DateTimeField#roundFloor} */
79     public static final int ROUND_FLOOR = 1;
80     /** Rounding mode as described by {@link DateTimeField#roundCeiling} */
81     public static final int ROUND_CEILING = 2;
82     /** Rounding mode as described by {@link DateTimeField#roundHalfFloor} */
83     public static final int ROUND_HALF_FLOOR = 3;
84     /** Rounding mode as described by {@link DateTimeField#roundHalfCeiling} */
85     public static final int ROUND_HALF_CEILING = 4;
86     /** Rounding mode as described by {@link DateTimeField#roundHalfEven} */
87     public static final int ROUND_HALF_EVEN = 5;
88
89     /** The field to round on */
90     private DateTimeField iRoundingField;
91     /** The mode of rounding */
92     private int iRoundingMode;
93
94     //-----------------------------------------------------------------------
95
/**
96      * Constructs an instance set to the current system millisecond time
97      * using <code>ISOChronology</code> in the default time zone.
98      */

99     public MutableDateTime() {
100         super();
101     }
102
103     /**
104      * Constructs an instance set to the current system millisecond time
105      * using <code>ISOChronology</code> in the specified time zone.
106      * <p>
107      * If the specified time zone is null, the default zone is used.
108      *
109      * @param zone the time zone, null means default zone
110      */

111     public MutableDateTime(DateTimeZone zone) {
112         super(zone);
113     }
114
115     /**
116      * Constructs an instance set to the current system millisecond time
117      * using the specified chronology.
118      * <p>
119      * If the chronology is null, <code>ISOChronology</code>
120      * in the default time zone is used.
121      *
122      * @param chronology the chronology, null means ISOChronology in default zone
123      */

124     public MutableDateTime(Chronology chronology) {
125         super(chronology);
126     }
127
128     //-----------------------------------------------------------------------
129
/**
130      * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z
131      * using <code>ISOChronology</code> in the default time zone.
132      *
133      * @param instant the milliseconds from 1970-01-01T00:00:00Z
134      */

135     public MutableDateTime(long instant) {
136         super(instant);
137     }
138
139     /**
140      * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z
141      * using <code>ISOChronology</code> in the specified time zone.
142      * <p>
143      * If the specified time zone is null, the default zone is used.
144      *
145      * @param instant the milliseconds from 1970-01-01T00:00:00Z
146      * @param zone the time zone, null means default zone
147      */

148     public MutableDateTime(long instant, DateTimeZone zone) {
149         super(instant, zone);
150     }
151
152     /**
153      * Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z
154      * using the specified chronology.
155      * <p>
156      * If the chronology is null, <code>ISOChronology</code>
157      * in the default time zone is used.
158      *
159      * @param instant the milliseconds from 1970-01-01T00:00:00Z
160      * @param chronology the chronology, null means ISOChronology in default zone
161      */

162     public MutableDateTime(long instant, Chronology chronology) {
163         super(instant, chronology);
164     }
165
166     //-----------------------------------------------------------------------
167
/**
168      * Constructs an instance from an Object that represents a datetime.
169      * <p>
170      * If the object implies a chronology (such as GregorianCalendar does),
171      * then that chronology will be used. Otherwise, ISO default is used.
172      * Thus if a GregorianCalendar is passed in, the chronology used will
173      * be GJ, but if a Date is passed in the chronology will be ISO.
174      * <p>
175      * The recognised object types are defined in
176      * {@link org.joda.time.convert.ConverterManager ConverterManager} and
177      * include ReadableInstant, String, Calendar and Date.
178      *
179      * @param instant the datetime object, null means now
180      * @throws IllegalArgumentException if the instant is invalid
181      */

182     public MutableDateTime(Object JavaDoc instant) {
183         super(instant, (Chronology) null);
184     }
185
186     /**
187      * Constructs an instance from an Object that represents a datetime,
188      * forcing the time zone to that specified.
189      * <p>
190      * If the object implies a chronology (such as GregorianCalendar does),
191      * then that chronology will be used, but with the time zone adjusted.
192      * Otherwise, ISO is used in the specified time zone.
193      * If the specified time zone is null, the default zone is used.
194      * Thus if a GregorianCalendar is passed in, the chronology used will
195      * be GJ, but if a Date is passed in the chronology will be ISO.
196      * <p>
197      * The recognised object types are defined in
198      * {@link org.joda.time.convert.ConverterManager ConverterManager} and
199      * include ReadableInstant, String, Calendar and Date.
200      *
201      * @param instant the datetime object, null means now
202      * @param zone the time zone, null means default time zone
203      * @throws IllegalArgumentException if the instant is invalid
204      */

205     public MutableDateTime(Object JavaDoc instant, DateTimeZone zone) {
206         super(instant, zone);
207     }
208
209     /**
210      * Constructs an instance from an Object that represents a datetime,
211      * using the specified chronology.
212      * <p>
213      * If the chronology is null, ISO in the default time zone is used.
214      * Any chronology implied by the object (such as GregorianCalendar does)
215      * is ignored.
216      * <p>
217      * The recognised object types are defined in
218      * {@link org.joda.time.convert.ConverterManager ConverterManager} and
219      * include ReadableInstant, String, Calendar and Date.
220      *
221      * @param instant the datetime object, null means now
222      * @param chronology the chronology, null means ISOChronology in default zone
223      * @throws IllegalArgumentException if the instant is invalid
224      */

225     public MutableDateTime(Object JavaDoc instant, Chronology chronology) {
226         super(instant, DateTimeUtils.getChronology(chronology));
227     }
228
229     //-----------------------------------------------------------------------
230
/**
231      * Constructs an instance from datetime field values
232      * using <code>ISOChronology</code> in the default time zone.
233      *
234      * @param year the year
235      * @param monthOfYear the month of the year
236      * @param dayOfMonth the day of the month
237      * @param hourOfDay the hour of the day
238      * @param minuteOfHour the minute of the hour
239      * @param secondOfMinute the second of the minute
240      * @param millisOfSecond the millisecond of the second
241      */

242     public MutableDateTime(
243             int year,
244             int monthOfYear,
245             int dayOfMonth,
246             int hourOfDay,
247             int minuteOfHour,
248             int secondOfMinute,
249             int millisOfSecond) {
250         super(year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond);
251     }
252
253     /**
254      * Constructs an instance from datetime field values
255      * using <code>ISOChronology</code> in the specified time zone.
256      * <p>
257      * If the specified time zone is null, the default zone is used.
258      *
259      * @param year the year
260      * @param monthOfYear the month of the year
261      * @param dayOfMonth the day of the month
262      * @param hourOfDay the hour of the day
263      * @param minuteOfHour the minute of the hour
264      * @param secondOfMinute the second of the minute
265      * @param millisOfSecond the millisecond of the second
266      * @param zone the time zone, null means default time zone
267      */

268     public MutableDateTime(
269             int year,
270             int monthOfYear,
271             int dayOfMonth,
272             int hourOfDay,
273             int minuteOfHour,
274             int secondOfMinute,
275             int millisOfSecond,
276             DateTimeZone zone) {
277         super(year, monthOfYear, dayOfMonth,
278               hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond, zone);
279     }
280
281     /**
282      * Constructs an instance from datetime field values
283      * using the specified chronology.
284      * <p>
285      * If the chronology is null, <code>ISOChronology</code>
286      * in the default time zone is used.
287      *
288      * @param year the year
289      * @param monthOfYear the month of the year
290      * @param dayOfMonth the day of the month
291      * @param hourOfDay the hour of the day
292      * @param minuteOfHour the minute of the hour
293      * @param secondOfMinute the second of the minute
294      * @param millisOfSecond the millisecond of the second
295      * @param chronology the chronology, null means ISOChronology in default zone
296      */

297     public MutableDateTime(
298             int year,
299             int monthOfYear,
300             int dayOfMonth,
301             int hourOfDay,
302             int minuteOfHour,
303             int secondOfMinute,
304             int millisOfSecond,
305             Chronology chronology) {
306         super(year, monthOfYear, dayOfMonth,
307               hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond, chronology);
308     }
309
310     //-----------------------------------------------------------------------
311
/**
312      * Gets the field used for rounding this instant, returning null if rounding
313      * is not enabled.
314      *
315      * @return the rounding field
316      */

317     public DateTimeField getRoundingField() {
318         return iRoundingField;
319     }
320
321     /**
322      * Gets the rounding mode for this instant, returning ROUND_NONE if rounding
323      * is not enabled.
324      *
325      * @return the rounding mode constant
326      */

327     public int getRoundingMode() {
328         return iRoundingMode;
329     }
330
331     /**
332      * Sets the status of rounding to use the specified field and ROUND_FLOOR mode.
333      * A null field will disable rounding.
334      * Once set, the instant is then rounded using the new field and mode.
335      * <p>
336      * Enabling rounding will cause all subsequent calls to {@link #setMillis(long)}
337      * to be rounded. This can be used to control the precision of the instant,
338      * for example by setting a rounding field of minuteOfDay, the seconds and
339      * milliseconds will always be zero.
340      *
341      * @param field rounding field or null to disable
342      */

343     public void setRounding(DateTimeField field) {
344         setRounding(field, MutableDateTime.ROUND_FLOOR);
345     }
346
347     /**
348      * Sets the status of rounding to use the specified field and mode.
349      * A null field or mode of ROUND_NONE will disable rounding.
350      * Once set, the instant is then rounded using the new field and mode.
351      * <p>
352      * Enabling rounding will cause all subsequent calls to {@link #setMillis(long)}
353      * to be rounded. This can be used to control the precision of the instant,
354      * for example by setting a rounding field of minuteOfDay, the seconds and
355      * milliseconds will always be zero.
356      *
357      * @param field rounding field or null to disable
358      * @param mode rounding mode or ROUND_NONE to disable
359      * @throws IllegalArgumentException if mode is unknown, no exception if field is null
360      */

361     public void setRounding(DateTimeField field, int mode) {
362         if (field != null && (mode < ROUND_NONE || mode > ROUND_HALF_EVEN)) {
363             throw new IllegalArgumentException JavaDoc("Illegal rounding mode: " + mode);
364         }
365         iRoundingField = (mode == ROUND_NONE ? null : field);
366         iRoundingMode = (field == null ? ROUND_NONE : mode);
367         setMillis(getMillis());
368     }
369
370     //-----------------------------------------------------------------------
371
/**
372      * Set the milliseconds of the datetime.
373      * <p>
374      * All changes to the millisecond field occurs via this method.
375      *
376      * @param instant the milliseconds since 1970-01-01T00:00:00Z to set the
377      * datetime to
378      */

379     public void setMillis(long instant) {
380         switch (iRoundingMode) {
381             case ROUND_NONE:
382                 break;
383             case ROUND_FLOOR:
384                 instant = iRoundingField.roundFloor(instant);
385                 break;
386             case ROUND_CEILING:
387                 instant = iRoundingField.roundCeiling(instant);
388                 break;
389             case ROUND_HALF_FLOOR:
390                 instant = iRoundingField.roundHalfFloor(instant);
391                 break;
392             case ROUND_HALF_CEILING:
393                 instant = iRoundingField.roundHalfCeiling(instant);
394                 break;
395             case ROUND_HALF_EVEN:
396                 instant = iRoundingField.roundHalfEven(instant);
397                 break;
398         }
399
400         super.setMillis(instant);
401     }
402
403     /**
404      * Sets the millisecond instant of this instant from another.
405      * <p>
406      * This method does not change the chronology of this instant, just the
407      * millisecond instant.
408      *
409      * @param instant the instant to use, null means now
410      */

411     public void setMillis(ReadableInstant instant) {
412         long instantMillis = DateTimeUtils.getInstantMillis(instant);
413         setMillis(instantMillis); // set via this class not super
414
}
415
416     //-----------------------------------------------------------------------
417
/**
418      * Add an amount of time to the datetime.
419      *
420      * @param duration the millis to add
421      * @throws ArithmeticException if the result exceeds the capacity of the instant
422      */

423     public void add(long duration) {
424         setMillis(FieldUtils.safeAdd(getMillis(), duration)); // set via this class not super
425
}
426
427     /**
428      * Adds a duration to this instant.
429      * <p>
430      * This will typically change the value of most fields.
431      *
432      * @param duration the duration to add, null means add zero
433      * @throws ArithmeticException if the result exceeds the capacity of the instant
434      */

435     public void add(ReadableDuration duration) {
436         add(duration, 1);
437     }
438
439     /**
440      * Adds a duration to this instant specifying how many times to add.
441      * <p>
442      * This will typically change the value of most fields.
443      *
444      * @param duration the duration to add, null means add zero
445      * @param scalar direction and amount to add, which may be negative
446      * @throws ArithmeticException if the result exceeds the capacity of the instant
447      */

448     public void add(ReadableDuration duration, int scalar) {
449         if (duration != null) {
450             add(FieldUtils.safeMultiply(duration.getMillis(), scalar));
451         }
452     }
453
454     /**
455      * Adds a period to this instant.
456      * <p>
457      * This will typically change the value of most fields.
458      *
459      * @param period the period to add, null means add zero
460      * @throws ArithmeticException if the result exceeds the capacity of the instant
461      */

462     public void add(ReadablePeriod period) {
463         add(period, 1);
464     }
465
466     /**
467      * Adds a period to this instant specifying how many times to add.
468      * <p>
469      * This will typically change the value of most fields.
470      *
471      * @param period the period to add, null means add zero
472      * @param scalar direction and amount to add, which may be negative
473      * @throws ArithmeticException if the result exceeds the capacity of the instant
474      */

475     public void add(ReadablePeriod period, int scalar) {
476         if (period != null) {
477             setMillis(getChronology().add(period, getMillis(), scalar)); // set via this class not super
478
}
479     }
480
481     //-----------------------------------------------------------------------
482
/**
483      * Set the chronology of the datetime.
484      * <p>
485      * All changes to the chronology occur via this method.
486      *
487      * @param chronology the chronology to use, null means ISOChronology in default zone
488      */

489     public void setChronology(Chronology chronology) {
490         super.setChronology(chronology);
491     }
492
493     //-----------------------------------------------------------------------
494
/**
495      * Sets the time zone of the datetime, changing the chronology and field values.
496      * <p>
497      * Changing the zone using this method retains the millisecond instant.
498      * The millisecond instant is adjusted in the new zone to compensate.
499      *
500      * chronology. Setting the time zone does not affect the millisecond value
501      * of this instant.
502      * <p>
503      * If the chronology already has this time zone, no change occurs.
504      *
505      * @param newZone the time zone to use, null means default zone
506      * @see #setZoneRetainFields
507      */

508     public void setZone(DateTimeZone newZone) {
509         newZone = DateTimeUtils.getZone(newZone);
510         Chronology chrono = getChronology();
511         if (chrono.getZone() != newZone) {
512             setChronology(chrono.withZone(newZone)); // set via this class not super
513
}
514     }
515
516     /**
517      * Sets the time zone of the datetime, changing the chronology and millisecond.
518      * <p>
519      * Changing the zone using this method retains the field values.
520      * The millisecond instant is adjusted in the new zone to compensate.
521      * <p>
522      * If the chronology already has this time zone, no change occurs.
523      *
524      * @param newZone the time zone to use, null means default zone
525      * @see #setZone
526      */

527     public void setZoneRetainFields(DateTimeZone newZone) {
528         newZone = DateTimeUtils.getZone(newZone);
529         DateTimeZone originalZone = DateTimeUtils.getZone(getZone());
530         if (newZone == originalZone) {
531             return;
532         }
533         
534         long millis = originalZone.getMillisKeepLocal(newZone, getMillis());
535         setChronology(getChronology().withZone(newZone)); // set via this class not super
536
setMillis(millis);
537     }
538
539     //-----------------------------------------------------------------------
540
/**
541      * Sets the value of one of the fields of the instant, such as hourOfDay.
542      *
543      * @param type a field type, usually obtained from DateTimeFieldType, not null
544      * @param value the value to set the field to
545      * @throws IllegalArgumentException if the value is null or invalid
546      */

547     public void set(DateTimeFieldType type, int value) {
548         if (type == null) {
549             throw new IllegalArgumentException JavaDoc("Field must not be null");
550         }
551         setMillis(type.getField(getChronology()).set(getMillis(), value));
552     }
553
554     /**
555      * Adds to the instant specifying the duration and multiple to add.
556      *
557      * @param type a field type, usually obtained from DateTimeFieldType, not null
558      * @param amount the amount to add of this duration
559      * @throws IllegalArgumentException if the value is null or invalid
560      * @throws ArithmeticException if the result exceeds the capacity of the instant
561      */

562     public void add(DurationFieldType type, int amount) {
563         if (type == null) {
564             throw new IllegalArgumentException JavaDoc("Field must not be null");
565         }
566         setMillis(type.getField(getChronology()).add(getMillis(), amount));
567     }
568
569     //-----------------------------------------------------------------------
570
/**
571      * Set the year to the specified value.
572      *
573      * @param year the year
574      * @throws IllegalArgumentException if the value is invalid
575      */

576     public void setYear(final int year) {
577         setMillis(getChronology().year().set(getMillis(), year));
578     }
579
580     /**
581      * Add a number of years to the date.
582      *
583      * @param years the years to add
584      * @throws IllegalArgumentException if the value is invalid
585      */

586     public void addYears(final int years) {
587         setMillis(getChronology().years().add(getMillis(), years));
588     }
589
590     //-----------------------------------------------------------------------
591
/**
592      * Set the weekyear to the specified value.
593      *
594      * @param weekyear the weekyear
595      * @throws IllegalArgumentException if the value is invalid
596      */

597     public void setWeekyear(final int weekyear) {
598         setMillis(getChronology().weekyear().set(getMillis(), weekyear));
599     }
600
601     /**
602      * Add a number of weekyears to the date.
603      *
604      * @param weekyears the weekyears to add
605      * @throws IllegalArgumentException if the value is invalid
606      */

607     public void addWeekyears(final int weekyears) {
608         setMillis(getChronology().weekyears().add(getMillis(), weekyears));
609     }
610
611     //-----------------------------------------------------------------------
612
/**
613      * Set the month of the year to the specified value.
614      *
615      * @param monthOfYear the month of the year
616      * @throws IllegalArgumentException if the value is invalid
617      */

618     public void setMonthOfYear(final int monthOfYear) {
619         setMillis(getChronology().monthOfYear().set(getMillis(), monthOfYear));
620     }
621
622     /**
623      * Add a number of months to the date.
624      *
625      * @param months the months to add
626      * @throws IllegalArgumentException if the value is invalid
627      */

628     public void addMonths(final int months) {
629         setMillis(getChronology().months().add(getMillis(), months));
630     }
631
632     //-----------------------------------------------------------------------
633
/**
634      * Set the week of weekyear to the specified value.
635      *
636      * @param weekOfWeekyear the week of the weekyear
637      * @throws IllegalArgumentException if the value is invalid
638      */

639     public void setWeekOfWeekyear(final int weekOfWeekyear) {
640         setMillis(getChronology().weekOfWeekyear().set(getMillis(), weekOfWeekyear));
641     }
642
643     /**
644      * Add a number of weeks to the date.
645      *
646      * @param weeks the weeks to add
647      * @throws IllegalArgumentException if the value is invalid
648      */

649     public void addWeeks(final int weeks) {
650         setMillis(getChronology().weeks().add(getMillis(), weeks));
651     }
652
653     //-----------------------------------------------------------------------
654
/**
655      * Set the day of year to the specified value.
656      *
657      * @param dayOfYear the day of the year
658      * @throws IllegalArgumentException if the value is invalid
659      */

660     public void setDayOfYear(final int dayOfYear) {
661         setMillis(getChronology().dayOfYear().set(getMillis(), dayOfYear));
662     }
663
664     /**
665      * Set the day of the month to the specified value.
666      *
667      * @param dayOfMonth the day of the month
668      * @throws IllegalArgumentException if the value is invalid
669      */

670     public void setDayOfMonth(final int dayOfMonth) {
671         setMillis(getChronology().dayOfMonth().set(getMillis(), dayOfMonth));
672     }
673
674     /**
675      * Set the day of week to the specified value.
676      *
677      * @param dayOfWeek the day of the week
678      * @throws IllegalArgumentException if the value is invalid
679      */

680     public void setDayOfWeek(final int dayOfWeek) {
681         setMillis(getChronology().dayOfWeek().set(getMillis(), dayOfWeek));
682     }
683
684     /**
685      * Add a number of days to the date.
686      *
687      * @param days the days to add
688      * @throws IllegalArgumentException if the value is invalid
689      */

690     public void addDays(final int days) {
691         setMillis(getChronology().days().add(getMillis(), days));
692     }
693
694     //-----------------------------------------------------------------------
695
/**
696      * Set the hour of the day to the specified value.
697      *
698      * @param hourOfDay the hour of day
699      * @throws IllegalArgumentException if the value is invalid
700      */

701     public void setHourOfDay(final int hourOfDay) {
702         setMillis(getChronology().hourOfDay().set(getMillis(), hourOfDay));
703     }
704
705     /**
706      * Add a number of hours to the date.
707      *
708      * @param hours the hours to add
709      * @throws IllegalArgumentException if the value is invalid
710      */

711     public void addHours(final int hours) {
712         setMillis(getChronology().hours().add(getMillis(), hours));
713     }
714     
715     //-----------------------------------------------------------------------
716
/**
717      * Set the minute of the day to the specified value.
718      *
719      * @param minuteOfDay the minute of day
720      * @throws IllegalArgumentException if the value is invalid
721      */

722     public void setMinuteOfDay(final int minuteOfDay) {
723         setMillis(getChronology().minuteOfDay().set(getMillis(), minuteOfDay));
724     }
725
726     /**
727      * Set the minute of the hour to the specified value.
728      *
729      * @param minuteOfHour the minute of hour
730      * @throws IllegalArgumentException if the value is invalid
731      */

732     public void setMinuteOfHour(final int minuteOfHour) {
733         setMillis(getChronology().minuteOfHour().set(getMillis(), minuteOfHour));
734     }
735
736     /**
737      * Add a number of minutes to the date.
738      *
739      * @param minutes the minutes to add
740      * @throws IllegalArgumentException if the value is invalid
741      */

742     public void addMinutes(final int minutes) {
743         setMillis(getChronology().minutes().add(getMillis(), minutes));
744     }
745
746     //-----------------------------------------------------------------------
747
/**
748      * Set the second of the day to the specified value.
749      *
750      * @param secondOfDay the second of day
751      * @throws IllegalArgumentException if the value is invalid
752      */

753     public void setSecondOfDay(final int secondOfDay) {
754         setMillis(getChronology().secondOfDay().set(getMillis(), secondOfDay));
755     }
756
757     /**
758      * Set the second of the minute to the specified value.
759      *
760      * @param secondOfMinute the second of minute
761      * @throws IllegalArgumentException if the value is invalid
762      */

763     public void setSecondOfMinute(final int secondOfMinute) {
764         setMillis(getChronology().secondOfMinute().set(getMillis(), secondOfMinute));
765     }
766
767     /**
768      * Add a number of seconds to the date.
769      *
770      * @param seconds the seconds to add
771      * @throws IllegalArgumentException if the value is invalid
772      */

773     public void addSeconds(final int seconds) {
774         setMillis(getChronology().seconds().add(getMillis(), seconds));
775     }
776
777     //-----------------------------------------------------------------------
778
/**
779      * Set the millis of the day to the specified value.
780      *
781      * @param millisOfDay the millis of day
782      * @throws IllegalArgumentException if the value is invalid
783      */

784     public void setMillisOfDay(final int millisOfDay) {
785         setMillis(getChronology().millisOfDay().set(getMillis(), millisOfDay));
786     }
787
788     /**
789      * Set the millis of the second to the specified value.
790      *
791      * @param millisOfSecond the millis of second
792      * @throws IllegalArgumentException if the value is invalid
793      */

794     public void setMillisOfSecond(final int millisOfSecond) {
795         setMillis(getChronology().millisOfSecond().set(getMillis(), millisOfSecond));
796     }
797
798     /**
799      * Add a number of milliseconds to the date. The implementation of this
800      * method differs from the {@link #add(long)} method in that a
801      * DateTimeField performs the addition.
802      *
803      * @param millis the milliseconds to add
804      * @throws IllegalArgumentException if the value is invalid
805      */

806     public void addMillis(final int millis) {
807         setMillis(getChronology().millis().add(getMillis(), millis));
808     }
809
810     //-----------------------------------------------------------------------
811
/**
812      * Set the date from milliseconds.
813      * The time part of this object will be unaffected.
814      *
815      * @param instant an instant to copy the date from, time part ignored
816      * @throws IllegalArgumentException if the value is invalid
817      */

818     public void setDate(final long instant) {
819         setMillis(getChronology().millisOfDay().set(instant, getMillisOfDay()));
820     }
821
822     /**
823      * Set the date from another instant.
824      * The time part of this object will be unaffected.
825      *
826      * @param instant an instant to copy the date from, time part ignored
827      * @throws IllegalArgumentException if the object is invalid
828      */

829     public void setDate(final ReadableInstant instant) {
830         long instantMillis = DateTimeUtils.getInstantMillis(instant);
831         Chronology instantChrono = DateTimeUtils.getInstantChronology(instant);
832         DateTimeZone zone = instantChrono.getZone();
833         if (zone != null) {
834             instantMillis = zone.getMillisKeepLocal(DateTimeZone.UTC, instantMillis);
835         }
836         setDate(instantMillis);
837     }
838
839     /**
840      * Set the date from fields.
841      * The time part of this object will be unaffected.
842      *
843      * @param year the year
844      * @param monthOfYear the month of the year
845      * @param dayOfMonth the day of the month
846      * @throws IllegalArgumentException if the value is invalid
847      */

848     public void setDate(
849             final int year,
850             final int monthOfYear,
851             final int dayOfMonth) {
852         Chronology c = getChronology();
853         long instantMidnight = c.getDateTimeMillis(year, monthOfYear, dayOfMonth, 0);
854         setDate(instantMidnight);
855     }
856
857     //-----------------------------------------------------------------------
858
/**
859      * Set the time from milliseconds.
860      * The date part of this object will be unaffected.
861      *
862      * @param millis an instant to copy the time from, date part ignored
863      * @throws IllegalArgumentException if the value is invalid
864      */

865     public void setTime(final long millis) {
866         int millisOfDay = ISOChronology.getInstanceUTC().millisOfDay().get(millis);
867         setMillis(getChronology().millisOfDay().set(getMillis(), millisOfDay));
868     }
869
870     /**
871      * Set the time from another instant.
872      * The date part of this object will be unaffected.
873      *
874      * @param instant an instant to copy the time from, date part ignored
875      * @throws IllegalArgumentException if the object is invalid
876      */

877     public void setTime(final ReadableInstant instant) {
878         long instantMillis = DateTimeUtils.getInstantMillis(instant);
879         Chronology instantChrono = DateTimeUtils.getInstantChronology(instant);
880         DateTimeZone zone = instantChrono.getZone();
881         if (zone != null) {
882             instantMillis = zone.getMillisKeepLocal(DateTimeZone.UTC, instantMillis);
883         }
884         setTime(instantMillis);
885     }
886
887     /**
888      * Set the time from fields.
889      * The date part of this object will be unaffected.
890      *
891      * @param hour the hour
892      * @param minuteOfHour the minute of the hour
893      * @param secondOfMinute the second of the minute
894      * @param millisOfSecond the millisecond of the second
895      * @throws IllegalArgumentException if the value is invalid
896      */

897     public void setTime(
898             final int hour,
899             final int minuteOfHour,
900             final int secondOfMinute,
901             final int millisOfSecond) {
902         long instant = getChronology().getDateTimeMillis(
903             getMillis(), hour, minuteOfHour, secondOfMinute, millisOfSecond);
904         setMillis(instant);
905     }
906
907     /**
908      * Set the date and time from fields.
909      *
910      * @param year the year
911      * @param monthOfYear the month of the year
912      * @param dayOfMonth the day of the month
913      * @param hourOfDay the hour of the day
914      * @param minuteOfHour the minute of the hour
915      * @param secondOfMinute the second of the minute
916      * @param millisOfSecond the millisecond of the second
917      * @throws IllegalArgumentException if the value is invalid
918      */

919     public void setDateTime(
920             final int year,
921             final int monthOfYear,
922             final int dayOfMonth,
923             final int hourOfDay,
924             final int minuteOfHour,
925             final int secondOfMinute,
926             final int millisOfSecond) {
927         long instant = getChronology().getDateTimeMillis(
928             year, monthOfYear, dayOfMonth, hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond);
929         setMillis(instant);
930     }
931
932     //-----------------------------------------------------------------------
933
/**
934      * Gets the property object for the specified type, which contains many useful methods.
935      *
936      * @param type the field type to get the chronology for
937      * @return the property object
938      * @throws IllegalArgumentException if the field is null or unsupported
939      * @since 1.2
940      */

941     public Property property(DateTimeFieldType type) {
942         if (type == null) {
943             throw new IllegalArgumentException JavaDoc("The DateTimeFieldType must not be null");
944         }
945         DateTimeField field = type.getField(getChronology());
946         if (field.isSupported() == false) {
947             throw new IllegalArgumentException JavaDoc("Field '" + type + "' is not supported");
948         }
949         return new Property(this, field);
950     }
951
952     /**
953      * Get the era property.
954      *
955      * @return the era property
956      */

957     public Property era() {
958         return new Property(this, getChronology().era());
959     }
960
961     /**
962      * Get the century of era property.
963      *
964      * @return the year of era property
965      */

966     public Property centuryOfEra() {
967         return new Property(this, getChronology().centuryOfEra());
968     }
969
970     /**
971      * Get the year of century property.
972      *
973      * @return the year of era property
974      */

975     public Property yearOfCentury() {
976         return new Property(this, getChronology().yearOfCentury());
977     }
978
979     /**
980      * Get the year of era property.
981      *
982      * @return the year of era property
983      */

984     public Property yearOfEra() {
985         return new Property(this, getChronology().yearOfEra());
986     }
987
988     /**
989      * Get the year property.
990      *
991      * @return the year property
992      */

993     public Property year() {
994         return new Property(this, getChronology().year());
995     }
996
997     /**
998      * Get the year of a week based year property.
999      *
1000     * @return the year of a week based year property
1001     */

1002    public Property weekyear() {
1003        return new Property(this, getChronology().weekyear());
1004    }
1005
1006    /**
1007     * Get the month of year property.
1008     *
1009     * @return the month of year property
1010     */

1011    public Property monthOfYear() {
1012        return new Property(this, getChronology().monthOfYear());
1013    }
1014
1015    /**
1016     * Get the week of a week based year property.
1017     *
1018     * @return the week of a week based year property
1019     */

1020    public Property weekOfWeekyear() {
1021        return new Property(this, getChronology().weekOfWeekyear());
1022    }
1023
1024    /**
1025     * Get the day of year property.
1026     *
1027     * @return the day of year property
1028     */

1029    public Property dayOfYear() {
1030        return new Property(this, getChronology().dayOfYear());
1031    }
1032
1033    /**
1034     * Get the day of month property.
1035     * <p>
1036     * The values for day of month are defined in {@link DateTimeConstants}.
1037     *
1038     * @return the day of month property
1039     */

1040    public Property dayOfMonth() {
1041        return new Property(this, getChronology().dayOfMonth());
1042    }
1043
1044    /**
1045     * Get the day of week property.
1046     * <p>
1047     * The values for day of week are defined in {@link DateTimeConstants}.
1048     *
1049     * @return the day of week property
1050     */

1051    public Property dayOfWeek() {
1052        return new Property(this, getChronology().dayOfWeek());
1053    }
1054
1055    //-----------------------------------------------------------------------
1056
/**
1057     * Get the hour of day field property
1058     *
1059     * @return the hour of day property
1060     */

1061    public Property hourOfDay() {
1062        return new Property(this, getChronology().hourOfDay());
1063    }
1064
1065    /**
1066     * Get the minute of day property
1067     *
1068     * @return the minute of day property
1069     */

1070    public Property minuteOfDay() {
1071        return new Property(this, getChronology().minuteOfDay());
1072    }
1073
1074    /**
1075     * Get the minute of hour field property
1076     *
1077     * @return the minute of hour property
1078     */

1079    public Property minuteOfHour() {
1080        return new Property(this, getChronology().minuteOfHour());
1081    }
1082
1083    /**
1084     * Get the second of day property
1085     *
1086     * @return the second of day property
1087     */

1088    public Property secondOfDay() {
1089        return new Property(this, getChronology().secondOfDay());
1090    }
1091
1092    /**
1093     * Get the second of minute field property
1094     *
1095     * @return the second of minute property
1096     */

1097    public Property secondOfMinute() {
1098        return new Property(this, getChronology().secondOfMinute());
1099    }
1100
1101    /**
1102     * Get the millis of day property
1103     *
1104     * @return the millis of day property
1105     */

1106    public Property millisOfDay() {
1107        return new Property(this, getChronology().millisOfDay());
1108    }
1109
1110    /**
1111     * Get the millis of second property
1112     *
1113     * @return the millis of second property
1114     */

1115    public Property millisOfSecond() {
1116        return new Property(this, getChronology().millisOfSecond());
1117    }
1118
1119    //-----------------------------------------------------------------------
1120
/**
1121     * Clone this object without having to cast the returned object.
1122     *
1123     * @return a clone of the this object.
1124     */

1125    public MutableDateTime copy() {
1126        return (MutableDateTime) clone();
1127    }
1128
1129    //-----------------------------------------------------------------------
1130
/**
1131     * Clone this object.
1132     *
1133     * @return a clone of this object.
1134     */

1135    public Object JavaDoc clone() {
1136        try {
1137            return super.clone();
1138        } catch (CloneNotSupportedException JavaDoc ex) {
1139            throw new InternalError JavaDoc("Clone error");
1140        }
1141    }
1142
1143    /**
1144     * Output the date time in ISO8601 format (yyyy-MM-ddTHH:mm:ss.SSSZ).
1145     *
1146     * @return ISO8601 time formatted string.
1147     */

1148    public String JavaDoc toString() {
1149        return ISODateTimeFormat.dateTime().print(this);
1150    }
1151
1152    /**
1153     * MutableDateTime.Property binds a MutableDateTime to a
1154     * DateTimeField allowing powerful datetime functionality to be easily
1155     * accessed.
1156     * <p>
1157     * The example below shows how to use the property to change the value of a
1158     * MutableDateTime object.
1159     * <pre>
1160     * MutableDateTime dt = new MutableDateTime(1972, 12, 3, 13, 32, 19, 123);
1161     * dt.year().add(20);
1162     * dt.second().roundFloor().minute().set(10);
1163     * </pre>
1164     * <p>
1165     * MutableDateTime.Propery itself is thread-safe and immutable, but the
1166     * MutableDateTime being operated on is not.
1167     *
1168     * @author Stephen Colebourne
1169     * @author Brian S O'Neill
1170     * @since 1.0
1171     */

1172    public static final class Property extends AbstractReadableInstantFieldProperty {
1173        
1174        /** Serialization version */
1175        private static final long serialVersionUID = -4481126543819298617L;
1176        
1177        /** The instant this property is working against */
1178        private MutableDateTime iInstant;
1179        /** The field this property is working against */
1180        private DateTimeField iField;
1181        
1182        /**
1183         * Constructor.
1184         *
1185         * @param instant the instant to set
1186         * @param field the field to use
1187         */

1188        Property(MutableDateTime instant, DateTimeField field) {
1189            super();
1190            iInstant = instant;
1191            iField = field;
1192        }
1193        
1194        /**
1195         * Writes the property in a safe serialization format.
1196         */

1197        private void writeObject(ObjectOutputStream JavaDoc oos) throws IOException JavaDoc {
1198            oos.writeObject(iInstant);
1199            oos.writeObject(iField.getType());
1200        }
1201
1202        /**
1203         * Reads the property from a safe serialization format.
1204         */

1205        private void readObject(ObjectInputStream JavaDoc oos) throws IOException JavaDoc, ClassNotFoundException JavaDoc {
1206            iInstant = (MutableDateTime) oos.readObject();
1207            DateTimeFieldType type = (DateTimeFieldType) oos.readObject();
1208            iField = type.getField(iInstant.getChronology());
1209        }
1210
1211        //-----------------------------------------------------------------------
1212
/**
1213         * Gets the field being used.
1214         *
1215         * @return the field
1216         */

1217        public DateTimeField getField() {
1218            return iField;
1219        }
1220        
1221        /**
1222         * Gets the milliseconds of the datetime that this property is linked to.
1223         *
1224         * @return the milliseconds
1225         */

1226        protected long getMillis() {
1227            return iInstant.getMillis();
1228        }
1229        
1230        /**
1231         * Gets the chronology of the datetime that this property is linked to.
1232         *
1233         * @return the chronology
1234         * @since 1.4
1235         */

1236        protected Chronology getChronology() {
1237            return iInstant.getChronology();
1238        }
1239        
1240        /**
1241         * Gets the mutable datetime being used.
1242         *
1243         * @return the mutable datetime
1244         */

1245        public MutableDateTime getMutableDateTime() {
1246            return iInstant;
1247        }
1248        
1249        //-----------------------------------------------------------------------
1250
/**
1251         * Adds a value to the millis value.
1252         *
1253         * @param value the value to add
1254         * @return the mutable datetime being used, so calls can be chained
1255         * @see DateTimeField#add(long,int)
1256         */

1257        public MutableDateTime add(int value) {
1258            iInstant.setMillis(getField().add(iInstant.getMillis(), value));
1259            return iInstant;
1260        }
1261        
1262        /**
1263         * Adds a value to the millis value.
1264         *
1265         * @param value the value to add
1266         * @return the mutable datetime being used, so calls can be chained
1267         * @see DateTimeField#add(long,long)
1268         */

1269        public MutableDateTime add(long value) {
1270            iInstant.setMillis(getField().add(iInstant.getMillis(), value));
1271            return iInstant;
1272        }
1273        
1274        /**
1275         * Adds a value, possibly wrapped, to the millis value.
1276         *
1277         * @param value the value to add
1278         * @return the mutable datetime being used, so calls can be chained
1279         * @see DateTimeField#addWrapField
1280         */

1281        public MutableDateTime addWrapField(int value) {
1282            iInstant.setMillis(getField().addWrapField(iInstant.getMillis(), value));
1283            return iInstant;
1284        }
1285        
1286        //-----------------------------------------------------------------------
1287
/**
1288         * Sets a value.
1289         *
1290         * @param value the value to set.
1291         * @return the mutable datetime being used, so calls can be chained
1292         * @see DateTimeField#set(long,int)
1293         */

1294        public MutableDateTime set(int value) {
1295            iInstant.setMillis(getField().set(iInstant.getMillis(), value));
1296            return iInstant;
1297        }
1298        
1299        /**
1300         * Sets a text value.
1301         *
1302         * @param text the text value to set
1303         * @param locale optional locale to use for selecting a text symbol
1304         * @return the mutable datetime being used, so calls can be chained
1305         * @throws IllegalArgumentException if the text value isn't valid
1306         * @see DateTimeField#set(long,java.lang.String,java.util.Locale)
1307         */

1308        public MutableDateTime set(String JavaDoc text, Locale JavaDoc locale) {
1309            iInstant.setMillis(getField().set(iInstant.getMillis(), text, locale));
1310            return iInstant;
1311        }
1312        
1313        /**
1314         * Sets a text value.
1315         *
1316         * @param text the text value to set
1317         * @return the mutable datetime being used, so calls can be chained
1318         * @throws IllegalArgumentException if the text value isn't valid
1319         * @see DateTimeField#set(long,java.lang.String)
1320         */

1321        public MutableDateTime set(String JavaDoc text) {
1322            set(text, null);
1323            return iInstant;
1324        }
1325        
1326        //-----------------------------------------------------------------------
1327
/**
1328         * Round to the lowest whole unit of this field.
1329         *
1330         * @return the mutable datetime being used, so calls can be chained
1331         * @see DateTimeField#roundFloor
1332         */

1333        public MutableDateTime roundFloor() {
1334            iInstant.setMillis(getField().roundFloor(iInstant.getMillis()));
1335            return iInstant;
1336        }
1337
1338        /**
1339         * Round to the highest whole unit of this field.
1340         *
1341         * @return the mutable datetime being used, so calls can be chained
1342         * @see DateTimeField#roundCeiling
1343         */

1344        public MutableDateTime roundCeiling() {
1345            iInstant.setMillis(getField().roundCeiling(iInstant.getMillis()));
1346            return iInstant;
1347        }
1348        
1349        /**
1350         * Round to the nearest whole unit of this field, favoring the floor if
1351         * halfway.
1352         *
1353         * @return the mutable datetime being used, so calls can be chained
1354         * @see DateTimeField#roundHalfFloor
1355         */

1356        public MutableDateTime roundHalfFloor() {
1357            iInstant.setMillis(getField().roundHalfFloor(iInstant.getMillis()));
1358            return iInstant;
1359        }
1360        
1361        /**
1362         * Round to the nearest whole unit of this field, favoring the ceiling if
1363         * halfway.
1364         *
1365         * @return the mutable datetime being used, so calls can be chained
1366         * @see DateTimeField#roundHalfCeiling
1367         */

1368        public MutableDateTime roundHalfCeiling() {
1369            iInstant.setMillis(getField().roundHalfCeiling(iInstant.getMillis()));
1370            return iInstant;
1371        }
1372
1373        /**
1374         * Round to the nearest whole unit of this field. If halfway, the ceiling
1375         * is favored over the floor only if it makes this field's value even.
1376         *
1377         * @return the mutable datetime being used, so calls can be chained
1378         * @see DateTimeField#roundHalfEven
1379         */

1380        public MutableDateTime roundHalfEven() {
1381            iInstant.setMillis(getField().roundHalfEven(iInstant.getMillis()));
1382            return iInstant;
1383        }
1384    }
1385
1386}
1387
Popular Tags