KickJava   Java API By Example, From Geeks To Geeks.

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


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.Serializable JavaDoc;
19 import java.util.Calendar JavaDoc;
20 import java.util.Date JavaDoc;
21 import java.util.Locale JavaDoc;
22
23 import org.joda.time.base.BasePartial;
24 import org.joda.time.chrono.ISOChronology;
25 import org.joda.time.field.AbstractPartialFieldProperty;
26 import org.joda.time.field.FieldUtils;
27 import org.joda.time.format.ISODateTimeFormat;
28
29 /**
30  * TimeOfDay is an immutable partial supporting the hour, minute, second
31  * and millisecond fields.
32  * <p>
33  * NOTE: This class is effectively deprecated. New applications should
34  * use {@link LocalTime} which has a better internal implementation.
35  * This class has not yet been formally deprecated due to the large number
36  * of existing users.
37  * <p>
38  * NOTE: This class only supports the four fields listed above. Thus, you
39  * cannot query the millisOfDay or secondOfDay fields for example.
40  * The new <code>LocalTime</code> class removes this restriction.
41  * <p>
42  * Calculations on TimeOfDay are performed using a {@link Chronology}.
43  * This chronology is set to be in the UTC time zone for all calculations.
44  * <p>
45  * Each individual field can be queried in two ways:
46  * <ul>
47  * <li><code>getHourOfDay()</code>
48  * <li><code>hourOfDay().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 - <code>hourOfDay().get()</code>
54  * <li>text value - <code>hourOfDay().getAsText()</code>
55  * <li>short text value - <code>hourOfDay().getAsShortText()</code>
56  * <li>maximum/minimum values - <code>hourOfDay().getMaximumValue()</code>
57  * <li>add/subtract - <code>hourOfDay().addToCopy()</code>
58  * <li>set - <code>hourOfDay().setCopy()</code>
59  * </ul>
60  * <p>
61  * TimeOfDay is thread-safe and immutable, provided that the Chronology is as well.
62  * All standard Chronology classes supplied are thread-safe and immutable.
63  *
64  * @author Stephen Colebourne
65  * @author Brian S O'Neill
66  * @since 1.0
67  */

68 public final class TimeOfDay
69         extends BasePartial
70         implements ReadablePartial, Serializable JavaDoc {
71     // NOTE: No toDateTime(YearMonthDay) as semantics are confusing when
72
// different chronologies
73

74     /** Serialization version */
75     private static final long serialVersionUID = 3633353405803318660L;
76     /** The singleton set of field types */
77     private static final DateTimeFieldType[] FIELD_TYPES = new DateTimeFieldType[] {
78         DateTimeFieldType.hourOfDay(),
79         DateTimeFieldType.minuteOfHour(),
80         DateTimeFieldType.secondOfMinute(),
81         DateTimeFieldType.millisOfSecond(),
82     };
83
84     /** Constant for midnight. */
85     public static final TimeOfDay MIDNIGHT = new TimeOfDay(0, 0, 0, 0);
86
87     /** The index of the hourOfDay field in the field array */
88     public static final int HOUR_OF_DAY = 0;
89     /** The index of the minuteOfHour field in the field array */
90     public static final int MINUTE_OF_HOUR = 1;
91     /** The index of the secondOfMinute field in the field array */
92     public static final int SECOND_OF_MINUTE = 2;
93     /** The index of the millisOfSecond field in the field array */
94     public static final int MILLIS_OF_SECOND = 3;
95
96     //-----------------------------------------------------------------------
97
/**
98      * Constructs a TimeOfDay from a <code>java.util.Calendar</code>
99      * using exactly the same field values avoiding any time zone effects.
100      * <p>
101      * Each field is queried from the Calendar and assigned to the TimeOfDay.
102      * This is useful to ensure that the field values are the same in the
103      * created TimeOfDay no matter what the time zone is. For example, if
104      * the Calendar states that the time is 04:29, then the created TimeOfDay
105      * will always have the time 04:29 irrespective of time zone issues.
106      * <p>
107      * This factory method ignores the type of the calendar and always
108      * creates a TimeOfDay with ISO chronology.
109      *
110      * @param calendar the Calendar to extract fields from
111      * @return the created TimeOfDay
112      * @throws IllegalArgumentException if the calendar is null
113      * @throws IllegalArgumentException if the time is invalid for the ISO chronology
114      * @since 1.2
115      */

116     public static TimeOfDay fromCalendarFields(Calendar JavaDoc calendar) {
117         if (calendar == null) {
118             throw new IllegalArgumentException JavaDoc("The calendar must not be null");
119         }
120         return new TimeOfDay(
121             calendar.get(Calendar.HOUR_OF_DAY),
122             calendar.get(Calendar.MINUTE),
123             calendar.get(Calendar.SECOND),
124             calendar.get(Calendar.MILLISECOND)
125         );
126     }
127
128     /**
129      * Constructs a TimeOfDay from a <code>java.util.Date</code>
130      * using exactly the same field values avoiding any time zone effects.
131      * <p>
132      * Each field is queried from the Date and assigned to the TimeOfDay.
133      * This is useful to ensure that the field values are the same in the
134      * created TimeOfDay no matter what the time zone is. For example, if
135      * the Calendar states that the time is 04:29, then the created TimeOfDay
136      * will always have the time 04:29 irrespective of time zone issues.
137      * <p>
138      * This factory method always creates a TimeOfDay with ISO chronology.
139      *
140      * @param date the Date to extract fields from
141      * @return the created TimeOfDay
142      * @throws IllegalArgumentException if the calendar is null
143      * @throws IllegalArgumentException if the date is invalid for the ISO chronology
144      * @since 1.2
145      */

146     public static TimeOfDay fromDateFields(Date JavaDoc date) {
147         if (date == null) {
148             throw new IllegalArgumentException JavaDoc("The date must not be null");
149         }
150         return new TimeOfDay(
151             date.getHours(),
152             date.getMinutes(),
153             date.getSeconds(),
154             (int) (date.getTime() % 1000)
155         );
156     }
157
158     //-----------------------------------------------------------------------
159
/**
160      * Constructs a TimeOfDay from the specified millis of day using the
161      * ISO chronology.
162      * <p>
163      * The millisOfDay value may exceed the number of millis in one day,
164      * but additional days will be ignored.
165      * This method uses the UTC time zone internally.
166      *
167      * @param millisOfDay the number of milliseconds into a day to convert
168      */

169     public static TimeOfDay fromMillisOfDay(long millisOfDay) {
170         return fromMillisOfDay(millisOfDay, null);
171     }
172
173     /**
174      * Constructs a TimeOfDay from the specified millis of day using the
175      * specified chronology.
176      * <p>
177      * The millisOfDay value may exceed the number of millis in one day,
178      * but additional days will be ignored.
179      * This method uses the UTC time zone internally.
180      *
181      * @param millisOfDay the number of milliseconds into a day to convert
182      * @param chrono the chronology, null means ISO chronology
183      */

184     public static TimeOfDay fromMillisOfDay(long millisOfDay, Chronology chrono) {
185         chrono = DateTimeUtils.getChronology(chrono);
186         chrono = chrono.withUTC();
187         return new TimeOfDay(millisOfDay, chrono);
188     }
189
190     // Constructors
191
//-----------------------------------------------------------------------
192
/**
193      * Constructs a TimeOfDay with the current time, using ISOChronology in
194      * the default zone to extract the fields.
195      * <p>
196      * The constructor uses the default time zone, resulting in the local time
197      * being initialised. Once the constructor is complete, all further calculations
198      * are performed without reference to a timezone (by switching to UTC).
199      */

200     public TimeOfDay() {
201         super();
202     }
203
204     /**
205      * Constructs a TimeOfDay with the current time, using ISOChronology in
206      * the specified zone to extract the fields.
207      * <p>
208      * The constructor uses the specified time zone to obtain the current time.
209      * Once the constructor is complete, all further calculations
210      * are performed without reference to a timezone (by switching to UTC).
211      *
212      * @param zone the zone to use, null means default zone
213      * @since 1.1
214      */

215     public TimeOfDay(DateTimeZone zone) {
216         super(ISOChronology.getInstance(zone));
217     }
218
219     /**
220      * Constructs a TimeOfDay with the current time, using the specified chronology
221      * and zone to extract the fields.
222      * <p>
223      * The constructor uses the time zone of the chronology specified.
224      * Once the constructor is complete, all further calculations are performed
225      * without reference to a timezone (by switching to UTC).
226      *
227      * @param chronology the chronology, null means ISOChronology in the default zone
228      */

229     public TimeOfDay(Chronology chronology) {
230         super(chronology);
231     }
232
233     /**
234      * Constructs a TimeOfDay extracting the partial fields from the specified
235      * milliseconds using the ISOChronology in the default zone.
236      * <p>
237      * The constructor uses the default time zone, resulting in the local time
238      * being initialised. Once the constructor is complete, all further calculations
239      * are performed without reference to a timezone (by switching to UTC).
240      *
241      * @param instant the milliseconds from 1970-01-01T00:00:00Z
242      */

243     public TimeOfDay(long instant) {
244         super(instant);
245     }
246
247     /**
248      * Constructs a TimeOfDay extracting the partial fields from the specified
249      * milliseconds using the chronology provided.
250      * <p>
251      * The constructor uses the time zone of the chronology specified.
252      * Once the constructor is complete, all further calculations are performed
253      * without reference to a timezone (by switching to UTC).
254      *
255      * @param instant the milliseconds from 1970-01-01T00:00:00Z
256      * @param chronology the chronology, null means ISOChronology in the default zone
257      */

258     public TimeOfDay(long instant, Chronology chronology) {
259         super(instant, chronology);
260     }
261
262     /**
263      * Constructs a TimeOfDay from an Object that represents a time.
264      * <p>
265      * The recognised object types are defined in
266      * {@link org.joda.time.convert.ConverterManager ConverterManager} and
267      * include ReadableInstant, String, Calendar and Date.
268      * The String formats are described by {@link ISODateTimeFormat#timeParser()}.
269      * <p>
270      * The chronology used will be derived from the object, defaulting to ISO.
271      * <p>
272      * NOTE: Prior to v1.3 the string format was described by
273      * {@link ISODateTimeFormat#dateTimeParser()}. Dates are now rejected.
274      *
275      * @param instant the datetime object, null means now
276      * @throws IllegalArgumentException if the instant is invalid
277      */

278     public TimeOfDay(Object JavaDoc instant) {
279         super(instant, null, ISODateTimeFormat.timeParser());
280     }
281
282     /**
283      * Constructs a TimeOfDay from an Object that represents a time, using the
284      * specified chronology.
285      * <p>
286      * The recognised object types are defined in
287      * {@link org.joda.time.convert.ConverterManager ConverterManager} and
288      * include ReadableInstant, String, Calendar and Date.
289      * The String formats are described by {@link ISODateTimeFormat#timeParser()}.
290      * <p>
291      * The constructor uses the time zone of the chronology specified.
292      * Once the constructor is complete, all further calculations are performed
293      * without reference to a timezone (by switching to UTC).
294      * The specified chronology overrides that of the object.
295      * <p>
296      * NOTE: Prior to v1.3 the string format was described by
297      * {@link ISODateTimeFormat#dateTimeParser()}. Dates are now rejected.
298      *
299      * @param instant the datetime object, null means now
300      * @param chronology the chronology, null means ISO default
301      * @throws IllegalArgumentException if the instant is invalid
302      */

303     public TimeOfDay(Object JavaDoc instant, Chronology chronology) {
304         super(instant, DateTimeUtils.getChronology(chronology), ISODateTimeFormat.timeParser());
305     }
306
307     /**
308      * Constructs a TimeOfDay with specified hour and minute and zero seconds and milliseconds
309      * using <code>ISOChronology</code> in the default zone.
310      * <p>
311      * The constructor uses the no time zone initialising the fields as provided.
312      * Once the constructor is complete, all further calculations
313      * are performed without reference to a timezone (by switching to UTC).
314      *
315      * @param hourOfDay the hour of the day
316      * @param minuteOfHour the minute of the hour
317      */

318     public TimeOfDay(int hourOfDay, int minuteOfHour) {
319         this(hourOfDay, minuteOfHour, 0, 0, null);
320     }
321
322     /**
323      * Constructs a TimeOfDay with specified hour and minute and zero seconds and milliseconds.
324      * <p>
325      * The constructor uses the time zone of the chronology specified.
326      * Once the constructor is complete, all further calculations are performed
327      * without reference to a timezone (by switching to UTC).
328      *
329      * @param hourOfDay the hour of the day
330      * @param minuteOfHour the minute of the hour
331      * @param chronology the chronology, null means ISOChronology in the default zone
332      */

333     public TimeOfDay(int hourOfDay, int minuteOfHour, Chronology chronology) {
334         this(hourOfDay, minuteOfHour, 0, 0, chronology);
335     }
336
337     /**
338      * Constructs a TimeOfDay with specified time field values and zero milliseconds
339      * using <code>ISOChronology</code> in the default zone.
340      * <p>
341      * The constructor uses the no time zone initialising the fields as provided.
342      * Once the constructor is complete, all further calculations
343      * are performed without reference to a timezone (by switching to UTC).
344      *
345      * @param hourOfDay the hour of the day
346      * @param minuteOfHour the minute of the hour
347      * @param secondOfMinute the second of the minute
348      */

349     public TimeOfDay(int hourOfDay, int minuteOfHour, int secondOfMinute) {
350         this(hourOfDay, minuteOfHour, secondOfMinute, 0, null);
351     }
352
353     /**
354      * Constructs a TimeOfDay with specified time field values and zero milliseconds.
355      * <p>
356      * The constructor uses the time zone of the chronology specified.
357      * Once the constructor is complete, all further calculations are performed
358      * without reference to a timezone (by switching to UTC).
359      *
360      * @param hourOfDay the hour of the day
361      * @param minuteOfHour the minute of the hour
362      * @param secondOfMinute the second of the minute
363      * @param chronology the chronology, null means ISOChronology in the default zone
364      */

365     public TimeOfDay(int hourOfDay, int minuteOfHour, int secondOfMinute, Chronology chronology) {
366         this(hourOfDay, minuteOfHour, secondOfMinute, 0, chronology);
367     }
368
369     /**
370      * Constructs a TimeOfDay with specified time field values using
371      * <code>ISOChronology</code> in the default zone.
372      * <p>
373      * The constructor uses the no time zone initialising the fields as provided.
374      * Once the constructor is complete, all further calculations
375      * are performed without reference to a timezone (by switching to UTC).
376      *
377      * @param hourOfDay the hour of the day
378      * @param minuteOfHour the minute of the hour
379      * @param secondOfMinute the second of the minute
380      * @param millisOfSecond the millisecond of the second
381      */

382     public TimeOfDay(int hourOfDay, int minuteOfHour, int secondOfMinute, int millisOfSecond) {
383         this(hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond, null);
384     }
385
386     /**
387      * Constructs a TimeOfDay with specified time field values and chronology.
388      * <p>
389      * The constructor uses the time zone of the chronology specified.
390      * Once the constructor is complete, all further calculations are performed
391      * without reference to a timezone (by switching to UTC).
392      *
393      * @param hourOfDay the hour of the day
394      * @param minuteOfHour the minute of the hour
395      * @param secondOfMinute the second of the minute
396      * @param millisOfSecond the millisecond of the second
397      * @param chronology the chronology, null means ISOChronology in the default zone
398      */

399     public TimeOfDay(int hourOfDay, int minuteOfHour,
400             int secondOfMinute, int millisOfSecond, Chronology chronology) {
401         super(new int[] {hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond}, chronology);
402     }
403
404     /**
405      * Constructs a TimeOfDay with chronology from this instance and new values.
406      *
407      * @param partial the partial to base this new instance on
408      * @param values the new set of values
409      */

410     TimeOfDay(TimeOfDay partial, int[] values) {
411         super(partial, values);
412     }
413
414     /**
415      * Constructs a TimeOfDay with values from this instance and a new chronology.
416      *
417      * @param partial the partial to base this new instance on
418      * @param chrono the new chronology
419      */

420     TimeOfDay(TimeOfDay partial, Chronology chrono) {
421         super(partial, chrono);
422     }
423
424     //-----------------------------------------------------------------------
425
/**
426      * Gets the number of fields in this partial.
427      *
428      * @return the field count
429      */

430     public int size() {
431         return 4;
432     }
433
434     /**
435      * Gets the field for a specific index in the chronology specified.
436      * <p>
437      * This method must not use any instance variables.
438      *
439      * @param index the index to retrieve
440      * @param chrono the chronology to use
441      * @return the field
442      */

443     protected DateTimeField getField(int index, Chronology chrono) {
444         switch (index) {
445             case HOUR_OF_DAY:
446                 return chrono.hourOfDay();
447             case MINUTE_OF_HOUR:
448                 return chrono.minuteOfHour();
449             case SECOND_OF_MINUTE:
450                 return chrono.secondOfMinute();
451             case MILLIS_OF_SECOND:
452                 return chrono.millisOfSecond();
453             default:
454                 throw new IndexOutOfBoundsException JavaDoc("Invalid index: " + index);
455         }
456     }
457
458     /**
459      * Gets the field type at the specified index.
460      *
461      * @param index the index to retrieve
462      * @return the field at the specified index
463      * @throws IndexOutOfBoundsException if the index is invalid
464      */

465     public DateTimeFieldType getFieldType(int index) {
466         return FIELD_TYPES[index];
467     }
468
469     /**
470      * Gets an array of the field type of each of the fields that this partial supports.
471      * <p>
472      * The fields are returned largest to smallest, Hour, Minute, Second, Millis.
473      *
474      * @return the array of field types (cloned), largest to smallest
475      */

476     public DateTimeFieldType[] getFieldTypes() {
477         return (DateTimeFieldType[]) FIELD_TYPES.clone();
478     }
479
480     //-----------------------------------------------------------------------
481
/**
482      * Returns a copy of this time with the specified chronology.
483      * This instance is immutable and unaffected by this method call.
484      * <p>
485      * This method retains the values of the fields, thus the result will
486      * typically refer to a different instant.
487      * <p>
488      * The time zone of the specified chronology is ignored, as TimeOfDay
489      * operates without a time zone.
490      *
491      * @param newChronology the new chronology, null means ISO
492      * @return a copy of this datetime with a different chronology
493      * @throws IllegalArgumentException if the values are invalid for the new chronology
494      */

495     public TimeOfDay withChronologyRetainFields(Chronology newChronology) {
496         newChronology = DateTimeUtils.getChronology(newChronology);
497         newChronology = newChronology.withUTC();
498         if (newChronology == getChronology()) {
499             return this;
500         } else {
501             TimeOfDay newTimeOfDay = new TimeOfDay(this, newChronology);
502             newChronology.validate(newTimeOfDay, getValues());
503             return newTimeOfDay;
504         }
505     }
506
507     /**
508      * Returns a copy of this time with the specified field set to a new value.
509      * <p>
510      * For example, if the field type is <code>minuteOfHour</code> then the day
511      * would be changed in the returned instance.
512      * <p>
513      * These three lines are equivalent:
514      * <pre>
515      * TimeOfDay updated = tod.withField(DateTimeFieldType.minuteOfHour(), 6);
516      * TimeOfDay updated = tod.minuteOfHour().setCopy(6);
517      * TimeOfDay updated = tod.property(DateTimeFieldType.minuteOfHour()).setCopy(6);
518      * </pre>
519      *
520      * @param fieldType the field type to set, not null
521      * @param value the value to set
522      * @return a copy of this instance with the field set
523      * @throws IllegalArgumentException if the value is null or invalid
524      */

525     public TimeOfDay withField(DateTimeFieldType fieldType, int value) {
526         int index = indexOfSupported(fieldType);
527         if (value == getValue(index)) {
528             return this;
529         }
530         int[] newValues = getValues();
531         newValues = getField(index).set(this, index, newValues, value);
532         return new TimeOfDay(this, newValues);
533     }
534
535     /**
536      * Returns a copy of this time with the value of the specified field increased,
537      * wrapping to what would be a new day if required.
538      * <p>
539      * If the addition is zero, then <code>this</code> is returned.
540      * <p>
541      * These three lines are equivalent:
542      * <pre>
543      * TimeOfDay added = tod.withFieldAdded(DurationFieldType.minutes(), 6);
544      * TimeOfDay added = tod.plusMinutes(6);
545      * TimeOfDay added = tod.minuteOfHour().addToCopy(6);
546      * </pre>
547      *
548      * @param fieldType the field type to add to, not null
549      * @param amount the amount to add
550      * @return a copy of this instance with the field updated
551      * @throws IllegalArgumentException if the value is null or invalid
552      * @throws ArithmeticException if the new datetime exceeds the capacity
553      */

554     public TimeOfDay withFieldAdded(DurationFieldType fieldType, int amount) {
555         int index = indexOfSupported(fieldType);
556         if (amount == 0) {
557             return this;
558         }
559         int[] newValues = getValues();
560         newValues = getField(index).addWrapPartial(this, index, newValues, amount);
561         return new TimeOfDay(this, newValues);
562     }
563
564     /**
565      * Returns a copy of this time with the specified period added,
566      * wrapping to what would be a new day if required.
567      * <p>
568      * If the addition is zero, then <code>this</code> is returned.
569      * Fields in the period that aren't present in the partial are ignored.
570      * <p>
571      * This method is typically used to add multiple copies of complex
572      * period instances. Adding one field is best achieved using methods
573      * like {@link #withFieldAdded(DurationFieldType, int)}
574      * or {@link #plusHours(int)}.
575      *
576      * @param period the period to add to this one, null means zero
577      * @param scalar the amount of times to add, such as -1 to subtract once
578      * @return a copy of this instance with the period added
579      * @throws ArithmeticException if the new datetime exceeds the capacity
580      */

581     public TimeOfDay withPeriodAdded(ReadablePeriod period, int scalar) {
582         if (period == null || scalar == 0) {
583             return this;
584         }
585         int[] newValues = getValues();
586         for (int i = 0; i < period.size(); i++) {
587             DurationFieldType fieldType = period.getFieldType(i);
588             int index = indexOf(fieldType);
589             if (index >= 0) {
590                 newValues = getField(index).addWrapPartial(this, index, newValues,
591                         FieldUtils.safeMultiply(period.getValue(i), scalar));
592             }
593         }
594         return new TimeOfDay(this, newValues);
595     }
596
597     //-----------------------------------------------------------------------
598
/**
599      * Returns a copy of this time with the specified period added,
600      * wrapping to what would be a new day if required.
601      * <p>
602      * If the amount is zero or null, then <code>this</code> is returned.
603      * <p>
604      * This method is typically used to add complex period instances.
605      * Adding one field is best achieved using methods
606      * like {@link #plusHours(int)}.
607      *
608      * @param period the duration to add to this one, null means zero
609      * @return a copy of this instance with the period added
610      * @throws ArithmeticException if the new datetime exceeds the capacity of a long
611      */

612     public TimeOfDay plus(ReadablePeriod period) {
613         return withPeriodAdded(period, 1);
614     }
615
616     //-----------------------------------------------------------------------
617
/**
618      * Returns a copy of this time plus the specified number of hours.
619      * <p>
620      * This time instance is immutable and unaffected by this method call.
621      * <p>
622      * The following three lines are identical in effect:
623      * <pre>
624      * TimeOfDay added = dt.plusHours(6);
625      * TimeOfDay added = dt.plus(Period.hours(6));
626      * TimeOfDay added = dt.withFieldAdded(DurationFieldType.hours(), 6);
627      * </pre>
628      *
629      * @param hours the amount of hours to add, may be negative
630      * @return the new time plus the increased hours
631      * @since 1.1
632      */

633     public TimeOfDay plusHours(int hours) {
634         return withFieldAdded(DurationFieldType.hours(), hours);
635     }
636
637     /**
638      * Returns a copy of this time plus the specified number of minutes.
639      * <p>
640      * This time instance is immutable and unaffected by this method call.
641      * <p>
642      * The following three lines are identical in effect:
643      * <pre>
644      * TimeOfDay added = dt.plusMinutes(6);
645      * TimeOfDay added = dt.plus(Period.minutes(6));
646      * TimeOfDay added = dt.withFieldAdded(DurationFieldType.minutes(), 6);
647      * </pre>
648      *
649      * @param minutes the amount of minutes to add, may be negative
650      * @return the new time plus the increased minutes
651      * @since 1.1
652      */

653     public TimeOfDay plusMinutes(int minutes) {
654         return withFieldAdded(DurationFieldType.minutes(), minutes);
655     }
656
657     /**
658      * Returns a copy of this time plus the specified number of seconds.
659      * <p>
660      * This time instance is immutable and unaffected by this method call.
661      * <p>
662      * The following three lines are identical in effect:
663      * <pre>
664      * TimeOfDay added = dt.plusSeconds(6);
665      * TimeOfDay added = dt.plus(Period.seconds(6));
666      * TimeOfDay added = dt.withFieldAdded(DurationFieldType.seconds(), 6);
667      * </pre>
668      *
669      * @param seconds the amount of seconds to add, may be negative
670      * @return the new time plus the increased seconds
671      * @since 1.1
672      */

673     public TimeOfDay plusSeconds(int seconds) {
674         return withFieldAdded(DurationFieldType.seconds(), seconds);
675     }
676
677     /**
678      * Returns a copy of this time plus the specified number of millis.
679      * <p>
680      * This time instance is immutable and unaffected by this method call.
681      * <p>
682      * The following three lines are identical in effect:
683      * <pre>
684      * TimeOfDay added = dt.plusMillis(6);
685      * TimeOfDay added = dt.plus(Period.millis(6));
686      * TimeOfDay added = dt.withFieldAdded(DurationFieldType.millis(), 6);
687      * </pre>
688      *
689      * @param millis the amount of millis to add, may be negative
690      * @return the new time plus the increased millis
691      * @since 1.1
692      */

693     public TimeOfDay plusMillis(int millis) {
694         return withFieldAdded(DurationFieldType.millis(), millis);
695     }
696
697     //-----------------------------------------------------------------------
698
/**
699      * Returns a copy of this time with the specified period taken away,
700      * wrapping to what would be a new day if required.
701      * <p>
702      * If the amount is zero or null, then <code>this</code> is returned.
703      * <p>
704      * This method is typically used to subtract complex period instances.
705      * Subtracting one field is best achieved using methods
706      * like {@link #minusHours(int)}.
707      *
708      * @param period the period to reduce this instant by
709      * @return a copy of this instance with the period taken away
710      * @throws ArithmeticException if the new time exceeds capacity
711      */

712     public TimeOfDay minus(ReadablePeriod period) {
713         return withPeriodAdded(period, -1);
714     }
715
716     //-----------------------------------------------------------------------
717
/**
718      * Returns a copy of this time minus the specified number of hours.
719      * <p>
720      * This time instance is immutable and unaffected by this method call.
721      * <p>
722      * The following three lines are identical in effect:
723      * <pre>
724      * TimeOfDay subtracted = dt.minusHours(6);
725      * TimeOfDay subtracted = dt.minus(Period.hours(6));
726      * TimeOfDay subtracted = dt.withFieldAdded(DurationFieldType.hours(), -6);
727      * </pre>
728      *
729      * @param hours the amount of hours to subtract, may be negative
730      * @return the new time minus the increased hours
731      * @since 1.1
732      */

733     public TimeOfDay minusHours(int hours) {
734         return withFieldAdded(DurationFieldType.hours(), FieldUtils.safeNegate(hours));
735     }
736
737     /**
738      * Returns a copy of this time minus the specified number of minutes.
739      * <p>
740      * This time instance is immutable and unaffected by this method call.
741      * <p>
742      * The following three lines are identical in effect:
743      * <pre>
744      * TimeOfDay subtracted = dt.minusMinutes(6);
745      * TimeOfDay subtracted = dt.minus(Period.minutes(6));
746      * TimeOfDay subtracted = dt.withFieldAdded(DurationFieldType.minutes(), -6);
747      * </pre>
748      *
749      * @param minutes the amount of minutes to subtract, may be negative
750      * @return the new time minus the increased minutes
751      * @since 1.1
752      */

753     public TimeOfDay minusMinutes(int minutes) {
754         return withFieldAdded(DurationFieldType.minutes(), FieldUtils.safeNegate(minutes));
755     }
756
757     /**
758      * Returns a copy of this time minus the specified number of seconds.
759      * <p>
760      * This time instance is immutable and unaffected by this method call.
761      * <p>
762      * The following three lines are identical in effect:
763      * <pre>
764      * TimeOfDay subtracted = dt.minusSeconds(6);
765      * TimeOfDay subtracted = dt.minus(Period.seconds(6));
766      * TimeOfDay subtracted = dt.withFieldAdded(DurationFieldType.seconds(), -6);
767      * </pre>
768      *
769      * @param seconds the amount of seconds to subtract, may be negative
770      * @return the new time minus the increased seconds
771      * @since 1.1
772      */

773     public TimeOfDay minusSeconds(int seconds) {
774         return withFieldAdded(DurationFieldType.seconds(), FieldUtils.safeNegate(seconds));
775     }
776
777     /**
778      * Returns a copy of this time minus the specified number of millis.
779      * <p>
780      * This time instance is immutable and unaffected by this method call.
781      * <p>
782      * The following three lines are identical in effect:
783      * <pre>
784      * TimeOfDay subtracted = dt.minusMillis(6);
785      * TimeOfDay subtracted = dt.minus(Period.millis(6));
786      * TimeOfDay subtracted = dt.withFieldAdded(DurationFieldType.millis(), -6);
787      * </pre>
788      *
789      * @param millis the amount of millis to subtract, may be negative
790      * @return the new time minus the increased millis
791      * @since 1.1
792      */

793     public TimeOfDay minusMillis(int millis) {
794         return withFieldAdded(DurationFieldType.millis(), FieldUtils.safeNegate(millis));
795     }
796
797     //-----------------------------------------------------------------------
798
/**
799      * Gets the property object for the specified type, which contains
800      * many useful methods.
801      *
802      * @param type the field type to get the property for
803      * @return the property object
804      * @throws IllegalArgumentException if the field is null or unsupported
805      */

806     public Property property(DateTimeFieldType type) {
807         return new Property(this, indexOfSupported(type));
808     }
809
810     //-----------------------------------------------------------------------
811
/**
812      * Converts this object to a LocalTime with the same time and chronology.
813      *
814      * @return a LocalTime with the same time and chronology
815      * @since 1.3
816      */

817     public LocalTime toLocalTime() {
818         return new LocalTime(getHourOfDay(), getMinuteOfHour(),
819                 getSecondOfMinute(), getMillisOfSecond(), getChronology());
820     }
821
822     //-----------------------------------------------------------------------
823
/**
824      * Converts this partial to a full datetime using the default time zone
825      * setting the time fields from this instance and the date fields from
826      * the current time.
827      *
828      * @return this date as a datetime with the time as the current time
829      */

830     public DateTime toDateTimeToday() {
831         return toDateTimeToday(null);
832     }
833
834     /**
835      * Converts this partial to a full datetime using the specified time zone
836      * setting the time fields from this instance and the date fields from
837      * the current time.
838      * <p>
839      * This method uses the chronology from this instance plus the time zone
840      * specified.
841      *
842      * @param zone the zone to use, null means default
843      * @return this date as a datetime with the time as the current time
844      */

845     public DateTime toDateTimeToday(DateTimeZone zone) {
846         Chronology chrono = getChronology().withZone(zone);
847         long instantMillis = DateTimeUtils.currentTimeMillis();
848         long resolved = chrono.set(this, instantMillis);
849         return new DateTime(resolved, chrono);
850     }
851
852     //-----------------------------------------------------------------------
853
/**
854      * Get the hour of day (0-23) field value.
855      *
856      * @return the hour of day
857      */

858     public int getHourOfDay() {
859         return getValue(HOUR_OF_DAY);
860     }
861
862     /**
863      * Get the minute of hour field value.
864      *
865      * @return the minute of hour
866      */

867     public int getMinuteOfHour() {
868         return getValue(MINUTE_OF_HOUR);
869     }
870
871     /**
872      * Get the second of minute field value.
873      *
874      * @return the second of minute
875      */

876     public int getSecondOfMinute() {
877         return getValue(SECOND_OF_MINUTE);
878     }
879
880     /**
881      * Get the millis of second field value.
882      *
883      * @return the millis of second
884      */

885     public int getMillisOfSecond() {
886         return getValue(MILLIS_OF_SECOND);
887     }
888
889     //-----------------------------------------------------------------------
890
/**
891      * Returns a copy of this time with the hour of day field updated.
892      * <p>
893      * TimeOfDay is immutable, so there are no set methods.
894      * Instead, this method returns a new instance with the value of
895      * hour of day changed.
896      *
897      * @param hour the hour of day to set
898      * @return a copy of this object with the field set
899      * @throws IllegalArgumentException if the value is invalid
900      * @since 1.3
901      */

902     public TimeOfDay withHourOfDay(int hour) {
903         int[] newValues = getValues();
904         newValues = getChronology().hourOfDay().set(this, HOUR_OF_DAY, newValues, hour);
905         return new TimeOfDay(this, newValues);
906     }
907
908     /**
909      * Returns a copy of this time with the minute of hour field updated.
910      * <p>
911      * TimeOfDay is immutable, so there are no set methods.
912      * Instead, this method returns a new instance with the value of
913      * minute of hour changed.
914      *
915      * @param minute the minute of hour to set
916      * @return a copy of this object with the field set
917      * @throws IllegalArgumentException if the value is invalid
918      * @since 1.3
919      */

920     public TimeOfDay withMinuteOfHour(int minute) {
921         int[] newValues = getValues();
922         newValues = getChronology().minuteOfHour().set(this, MINUTE_OF_HOUR, newValues, minute);
923         return new TimeOfDay(this, newValues);
924     }
925
926     /**
927      * Returns a copy of this time with the second of minute field updated.
928      * <p>
929      * TimeOfDay is immutable, so there are no set methods.
930      * Instead, this method returns a new instance with the value of
931      * second of minute changed.
932      *
933      * @param second the second of minute to set
934      * @return a copy of this object with the field set
935      * @throws IllegalArgumentException if the value is invalid
936      * @since 1.3
937      */

938     public TimeOfDay withSecondOfMinute(int second) {
939         int[] newValues = getValues();
940         newValues = getChronology().secondOfMinute().set(this, SECOND_OF_MINUTE, newValues, second);
941         return new TimeOfDay(this, newValues);
942     }
943
944     /**
945      * Returns a copy of this time with the millis of second field updated.
946      * <p>
947      * TimeOfDay is immutable, so there are no set methods.
948      * Instead, this method returns a new instance with the value of
949      * millis of second changed.
950      *
951      * @param millis the millis of second to set
952      * @return a copy of this object with the field set
953      * @throws IllegalArgumentException if the value is invalid
954      * @since 1.3
955      */

956     public TimeOfDay withMillisOfSecond(int millis) {
957         int[] newValues = getValues();
958         newValues = getChronology().millisOfSecond().set(this, MILLIS_OF_SECOND, newValues, millis);
959         return new TimeOfDay(this, newValues);
960     }
961
962     //-----------------------------------------------------------------------
963
/**
964      * Get the hour of day field property which provides access to advanced functionality.
965      *
966      * @return the hour of day property
967      */

968     public Property hourOfDay() {
969         return new Property(this, HOUR_OF_DAY);
970     }
971
972     /**
973      * Get the minute of hour field property which provides access to advanced functionality.
974      *
975      * @return the minute of hour property
976      */

977     public Property minuteOfHour() {
978         return new Property(this, MINUTE_OF_HOUR);
979     }
980
981     /**
982      * Get the second of minute field property which provides access to advanced functionality.
983      *
984      * @return the second of minute property
985      */

986     public Property secondOfMinute() {
987         return new Property(this, SECOND_OF_MINUTE);
988     }
989
990     /**
991      * Get the millis of second property which provides access to advanced functionality.
992      *
993      * @return the millis of second property
994      */

995     public Property millisOfSecond() {
996         return new Property(this, MILLIS_OF_SECOND);
997     }
998
999     //-----------------------------------------------------------------------
1000
/**
1001     * Output the time in the ISO8601 format THH:mm:ss.SSS.
1002     *
1003     * @return ISO8601 formatted string
1004     */

1005    public String JavaDoc toString() {
1006        return ISODateTimeFormat.tTime().print(this);
1007    }
1008
1009    //-----------------------------------------------------------------------
1010
/**
1011     * The property class for <code>TimeOfDay</code>.
1012     * <p>
1013     * This class binds a <code>TimeOfDay</code> to a <code>DateTimeField</code>.
1014     *
1015     * @author Stephen Colebourne
1016     * @since 1.0
1017     */

1018    public static class Property extends AbstractPartialFieldProperty implements Serializable JavaDoc {
1019
1020        /** Serialization version */
1021        private static final long serialVersionUID = 5598459141741063833L;
1022
1023        /** The partial */
1024        private final TimeOfDay iTimeOfDay;
1025        /** The field index */
1026        private final int iFieldIndex;
1027
1028        /**
1029         * Constructs a property.
1030         *
1031         * @param partial the partial instance
1032         * @param fieldIndex the index in the partial
1033         */

1034        Property(TimeOfDay partial, int fieldIndex) {
1035            super();
1036            iTimeOfDay = partial;
1037            iFieldIndex = fieldIndex;
1038        }
1039
1040        /**
1041         * Gets the field that this property uses.
1042         *
1043         * @return the field
1044         */

1045        public DateTimeField getField() {
1046            return iTimeOfDay.getField(iFieldIndex);
1047        }
1048
1049        /**
1050         * Gets the partial that this property belongs to.
1051         *
1052         * @return the partial
1053         */

1054        protected ReadablePartial getReadablePartial() {
1055            return iTimeOfDay;
1056        }
1057
1058        /**
1059         * Gets the partial that this property belongs to.
1060         *
1061         * @return the partial
1062         */

1063        public TimeOfDay getTimeOfDay() {
1064            return iTimeOfDay;
1065        }
1066
1067        /**
1068         * Gets the value of this field.
1069         *
1070         * @return the field value
1071         */

1072        public int get() {
1073            return iTimeOfDay.getValue(iFieldIndex);
1074        }
1075
1076        //-----------------------------------------------------------------------
1077
/**
1078         * Adds to the value of this field in a copy of this TimeOfDay,
1079         * wrapping to what would be the next day if necessary.
1080         * <p>
1081         * The value will be added to this field. If the value is too large to be
1082         * added solely to this field then it will affect larger fields.
1083         * Smaller fields are unaffected.
1084         * <p>
1085         * If the result would be too large, beyond 23:59:59:999, then the
1086         * calculation wraps to 00:00:00.000. For the alternate strict behaviour
1087         * with no wrapping see {@link #addNoWrapToCopy(int)}.
1088         * <p>
1089         * The TimeOfDay attached to this property is unchanged by this call.
1090         * Instead, a new instance is returned.
1091         *
1092         * @param valueToAdd the value to add to the field in the copy
1093         * @return a copy of the TimeOfDay with the field value changed
1094         * @throws IllegalArgumentException if the value isn't valid
1095         */

1096        public TimeOfDay addToCopy(int valueToAdd) {
1097            int[] newValues = iTimeOfDay.getValues();
1098            newValues = getField().addWrapPartial(iTimeOfDay, iFieldIndex, newValues, valueToAdd);
1099            return new TimeOfDay(iTimeOfDay, newValues);
1100        }
1101
1102        /**
1103         * Adds to the value of this field in a copy of this TimeOfDay,
1104         * throwing an Exception if the bounds are exceeded.
1105         * <p>
1106         * The value will be added to this field. If the value is too large to be
1107         * added solely to this field then it will affect larger fields.
1108         * Smaller fields are unaffected.
1109         * <p>
1110         * If the result would be too large (beyond 23:59:59:999) or too
1111         * small (less than 00:00:00.000) then an Execption is thrown.
1112         * For the alternate behaviour which wraps to the next 'day',
1113         * see {@link #addToCopy(int)}.
1114         * <p>
1115         * The TimeOfDay attached to this property is unchanged by this call.
1116         * Instead, a new instance is returned.
1117         *
1118         * @param valueToAdd the value to add to the field in the copy
1119         * @return a copy of the TimeOfDay with the field value changed
1120         * @throws IllegalArgumentException if the value isn't valid
1121         */

1122        public TimeOfDay addNoWrapToCopy(int valueToAdd) {
1123            int[] newValues = iTimeOfDay.getValues();
1124            newValues = getField().add(iTimeOfDay, iFieldIndex, newValues, valueToAdd);
1125            return new TimeOfDay(iTimeOfDay, newValues);
1126        }
1127
1128        /**
1129         * Adds to the value of this field in a copy of this TimeOfDay wrapping
1130         * within this field if the maximum value is reached.
1131         * <p>
1132         * The value will be added to this field. If the value is too large to be
1133         * added solely to this field then it wraps within this field.
1134         * Other fields are unaffected.
1135         * <p>
1136         * For example,
1137         * <code>12:59:37</code> addWrapField one minute returns <code>12:00:37</code>.
1138         * <p>
1139         * The TimeOfDay attached to this property is unchanged by this call.
1140         * Instead, a new instance is returned.
1141         *
1142         * @param valueToAdd the value to add to the field in the copy
1143         * @return a copy of the TimeOfDay with the field value changed
1144         * @throws IllegalArgumentException if the value isn't valid
1145         */

1146        public TimeOfDay addWrapFieldToCopy(int valueToAdd) {
1147            int[] newValues = iTimeOfDay.getValues();
1148            newValues = getField().addWrapField(iTimeOfDay, iFieldIndex, newValues, valueToAdd);
1149            return new TimeOfDay(iTimeOfDay, newValues);
1150        }
1151
1152        //-----------------------------------------------------------------------
1153
/**
1154         * Sets this field in a copy of the TimeOfDay.
1155         * <p>
1156         * The TimeOfDay attached to this property is unchanged by this call.
1157         * Instead, a new instance is returned.
1158         *
1159         * @param value the value to set the field in the copy to
1160         * @return a copy of the TimeOfDay with the field value changed
1161         * @throws IllegalArgumentException if the value isn't valid
1162         */

1163        public TimeOfDay setCopy(int value) {
1164            int[] newValues = iTimeOfDay.getValues();
1165            newValues = getField().set(iTimeOfDay, iFieldIndex, newValues, value);
1166            return new TimeOfDay(iTimeOfDay, newValues);
1167        }
1168
1169        /**
1170         * Sets this field in a copy of the TimeOfDay to a parsed text value.
1171         * <p>
1172         * The TimeOfDay attached to this property is unchanged by this call.
1173         * Instead, a new instance is returned.
1174         *
1175         * @param text the text value to set
1176         * @param locale optional locale to use for selecting a text symbol
1177         * @return a copy of the TimeOfDay with the field value changed
1178         * @throws IllegalArgumentException if the text value isn't valid
1179         */

1180        public TimeOfDay setCopy(String JavaDoc text, Locale JavaDoc locale) {
1181            int[] newValues = iTimeOfDay.getValues();
1182            newValues = getField().set(iTimeOfDay, iFieldIndex, newValues, text, locale);
1183            return new TimeOfDay(iTimeOfDay, newValues);
1184        }
1185
1186        /**
1187         * Sets this field in a copy of the TimeOfDay to a parsed text value.
1188         * <p>
1189         * The TimeOfDay attached to this property is unchanged by this call.
1190         * Instead, a new instance is returned.
1191         *
1192         * @param text the text value to set
1193         * @return a copy of the TimeOfDay with the field value changed
1194         * @throws IllegalArgumentException if the text value isn't valid
1195         */

1196        public TimeOfDay setCopy(String JavaDoc text) {
1197            return setCopy(text, null);
1198        }
1199
1200        //-----------------------------------------------------------------------
1201
/**
1202         * Returns a new TimeOfDay with this field set to the maximum value
1203         * for this field.
1204         * <p>
1205         * The TimeOfDay attached to this property is unchanged by this call.
1206         *
1207         * @return a copy of the TimeOfDay with this field set to its maximum
1208         * @since 1.2
1209         */

1210        public TimeOfDay withMaximumValue() {
1211            return setCopy(getMaximumValue());
1212        }
1213
1214        /**
1215         * Returns a new TimeOfDay with this field set to the minimum value
1216         * for this field.
1217         * <p>
1218         * The TimeOfDay attached to this property is unchanged by this call.
1219         *
1220         * @return a copy of the TimeOfDay with this field set to its minimum
1221         * @since 1.2
1222         */

1223        public TimeOfDay withMinimumValue() {
1224            return setCopy(getMinimumValue());
1225        }
1226    }
1227
1228}
1229
Popular Tags