001 /*
002 * Copyright 2001-2007 Stephen Colebourne
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.joda.time;
017
018 import java.io.IOException;
019 import java.io.ObjectInputStream;
020 import java.io.ObjectOutputStream;
021 import java.io.Serializable;
022 import java.util.Calendar;
023 import java.util.Date;
024 import java.util.HashSet;
025 import java.util.Locale;
026 import java.util.Set;
027
028 import org.joda.time.base.BaseLocal;
029 import org.joda.time.chrono.ISOChronology;
030 import org.joda.time.convert.ConverterManager;
031 import org.joda.time.convert.PartialConverter;
032 import org.joda.time.field.AbstractReadableInstantFieldProperty;
033 import org.joda.time.format.DateTimeFormat;
034 import org.joda.time.format.ISODateTimeFormat;
035
036 /**
037 * LocalTime is an immutable time class representing a time
038 * without a time zone.
039 * <p>
040 * LocalTime implements the {@link ReadablePartial} interface.
041 * To do this, the interface methods focus on the key fields -
042 * HourOfDay, MinuteOfHour, SecondOfMinute and MillisOfSecond.
043 * However, <b>all</b> time fields may in fact be queried.
044 * <p>
045 * Calculations on LocalTime are performed using a {@link Chronology}.
046 * This chronology will be set internally to be in the UTC time zone
047 * for all calculations.
048 *
049 * <p>Each individual field can be queried in two ways:
050 * <ul>
051 * <li><code>getHourOfDay()</code>
052 * <li><code>hourOfDay().get()</code>
053 * </ul>
054 * The second technique also provides access to other useful methods on the
055 * field:
056 * <ul>
057 * <li>numeric value
058 * <li>text value
059 * <li>short text value
060 * <li>maximum/minimum values
061 * <li>add/subtract
062 * <li>set
063 * <li>rounding
064 * </ul>
065 *
066 * <p>
067 * LocalTime is thread-safe and immutable, provided that the Chronology is as well.
068 * All standard Chronology classes supplied are thread-safe and immutable.
069 *
070 * @author Stephen Colebourne
071 * @since 1.3
072 */
073 public final class LocalTime
074 extends BaseLocal
075 implements ReadablePartial, Serializable {
076
077 /** Serialization lock */
078 private static final long serialVersionUID = -12873158713873L;
079
080 /** Constant for midnight. */
081 public static final LocalTime MIDNIGHT = new LocalTime(0, 0, 0, 0);
082
083 /** The index of the hourOfDay field in the field array */
084 private static final int HOUR_OF_DAY = 0;
085 /** The index of the minuteOfHour field in the field array */
086 private static final int MINUTE_OF_HOUR = 1;
087 /** The index of the secondOfMinute field in the field array */
088 private static final int SECOND_OF_MINUTE = 2;
089 /** The index of the millisOfSecond field in the field array */
090 private static final int MILLIS_OF_SECOND = 3;
091 /** Set of known duration types. */
092 private static final Set TIME_DURATION_TYPES = new HashSet();
093 static {
094 TIME_DURATION_TYPES.add(DurationFieldType.millis());
095 TIME_DURATION_TYPES.add(DurationFieldType.seconds());
096 TIME_DURATION_TYPES.add(DurationFieldType.minutes());
097 TIME_DURATION_TYPES.add(DurationFieldType.hours());
098 }
099
100 /** The local millis from 1970-01-01T00:00:00 */
101 private long iLocalMillis;
102 /** The chronology to use, in UTC */
103 private Chronology iChronology;
104
105 //-----------------------------------------------------------------------
106 /**
107 * Constructs a LocalTime from the specified millis of day using the
108 * ISO chronology.
109 * <p>
110 * The millisOfDay value may exceed the number of millis in one day,
111 * but additional days will be ignored.
112 * This method uses the UTC time zone internally.
113 *
114 * @param millisOfDay the number of milliseconds into a day to convert
115 */
116 public static LocalTime fromMillisOfDay(long millisOfDay) {
117 return fromMillisOfDay(millisOfDay, null);
118 }
119
120 /**
121 * Constructs a LocalTime from the specified millis of day using the
122 * specified chronology.
123 * <p>
124 * The millisOfDay value may exceed the number of millis in one day,
125 * but additional days will be ignored.
126 * This method uses the UTC time zone internally.
127 *
128 * @param millisOfDay the number of milliseconds into a day to convert
129 * @param chrono the chronology, null means ISO chronology
130 */
131 public static LocalTime fromMillisOfDay(long millisOfDay, Chronology chrono) {
132 chrono = DateTimeUtils.getChronology(chrono).withUTC();
133 return new LocalTime(millisOfDay, chrono);
134 }
135
136 //-----------------------------------------------------------------------
137 /**
138 * Constructs a LocalTime from a <code>java.util.Calendar</code>
139 * using exactly the same field values.
140 * <p>
141 * Each field is queried from the Calendar and assigned to the LocalTime.
142 * This is useful if you have been using the Calendar as a local time,
143 * ignoring the zone.
144 * <p>
145 * One advantage of this method is that this method is unaffected if the
146 * version of the time zone data differs between the JDK and Joda-Time.
147 * That is because the local field values are transferred, calculated using
148 * the JDK time zone data and without using the Joda-Time time zone data.
149 * <p>
150 * This factory method ignores the type of the calendar and always
151 * creates a LocalTime with ISO chronology. It is expected that you
152 * will only pass in instances of <code>GregorianCalendar</code> however
153 * this is not validated.
154 *
155 * @param calendar the Calendar to extract fields from
156 * @return the created LocalTime
157 * @throws IllegalArgumentException if the calendar is null
158 * @throws IllegalArgumentException if the date is invalid for the ISO chronology
159 */
160 public static LocalTime fromCalendarFields(Calendar calendar) {
161 if (calendar == null) {
162 throw new IllegalArgumentException("The calendar must not be null");
163 }
164 return new LocalTime(
165 calendar.get(Calendar.HOUR_OF_DAY),
166 calendar.get(Calendar.MINUTE),
167 calendar.get(Calendar.SECOND),
168 calendar.get(Calendar.MILLISECOND)
169 );
170 }
171
172 /**
173 * Constructs a LocalTime from a <code>java.util.Date</code>
174 * using exactly the same field values.
175 * <p>
176 * Each field is queried from the Date and assigned to the LocalTime.
177 * This is useful if you have been using the Date as a local time,
178 * ignoring the zone.
179 * <p>
180 * One advantage of this method is that this method is unaffected if the
181 * version of the time zone data differs between the JDK and Joda-Time.
182 * That is because the local field values are transferred, calculated using
183 * the JDK time zone data and without using the Joda-Time time zone data.
184 * <p>
185 * This factory method always creates a LocalTime with ISO chronology.
186 *
187 * @param date the Date to extract fields from
188 * @return the created LocalTime
189 * @throws IllegalArgumentException if the calendar is null
190 * @throws IllegalArgumentException if the date is invalid for the ISO chronology
191 */
192 public static LocalTime fromDateFields(Date date) {
193 if (date == null) {
194 throw new IllegalArgumentException("The date must not be null");
195 }
196 return new LocalTime(
197 date.getHours(),
198 date.getMinutes(),
199 date.getSeconds(),
200 (((int) (date.getTime() % 1000)) + 1000) % 1000
201 );
202 }
203
204 //-----------------------------------------------------------------------
205 /**
206 * Constructs an instance set to the current local time evaluated using
207 * ISO chronology in the default zone.
208 * <p>
209 * Once the constructor is completed, the zone is no longer used.
210 */
211 public LocalTime() {
212 this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance());
213 }
214
215 /**
216 * Constructs an instance set to the current local time evaluated using
217 * ISO chronology in the specified zone.
218 * <p>
219 * If the specified time zone is null, the default zone is used.
220 * Once the constructor is completed, the zone is no longer used.
221 *
222 * @param zone the time zone, null means default zone
223 */
224 public LocalTime(DateTimeZone zone) {
225 this(DateTimeUtils.currentTimeMillis(), ISOChronology.getInstance(zone));
226 }
227
228 /**
229 * Constructs an instance set to the current local time evaluated using
230 * specified chronology and zone.
231 * <p>
232 * If the chronology is null, ISO chronology in the default time zone is used.
233 * Once the constructor is completed, the zone is no longer used.
234 *
235 * @param chronology the chronology, null means ISOChronology in default zone
236 */
237 public LocalTime(Chronology chronology) {
238 this(DateTimeUtils.currentTimeMillis(), chronology);
239 }
240
241 //-----------------------------------------------------------------------
242 /**
243 * Constructs an instance set to the local time defined by the specified
244 * instant evaluated using ISO chronology in the default zone.
245 * <p>
246 * Once the constructor is completed, the zone is no longer used.
247 *
248 * @param instant the milliseconds from 1970-01-01T00:00:00Z
249 */
250 public LocalTime(long instant) {
251 this(instant, ISOChronology.getInstance());
252 }
253
254 /**
255 * Constructs an instance set to the local time defined by the specified
256 * instant evaluated using ISO chronology in the specified zone.
257 * <p>
258 * If the specified time zone is null, the default zone is used.
259 * Once the constructor is completed, the zone is no longer used.
260 *
261 * @param instant the milliseconds from 1970-01-01T00:00:00Z
262 * @param zone the time zone, null means default zone
263 */
264 public LocalTime(long instant, DateTimeZone zone) {
265 this(instant, ISOChronology.getInstance(zone));
266 }
267
268 /**
269 * Constructs an instance set to the local time defined by the specified
270 * instant evaluated using the specified chronology.
271 * <p>
272 * If the chronology is null, ISO chronology in the default zone is used.
273 * Once the constructor is completed, the zone is no longer used.
274 *
275 * @param instant the milliseconds from 1970-01-01T00:00:00Z
276 * @param chronology the chronology, null means ISOChronology in default zone
277 */
278 public LocalTime(long instant, Chronology chronology) {
279 chronology = DateTimeUtils.getChronology(chronology);
280
281 long localMillis = chronology.getZone().getMillisKeepLocal(DateTimeZone.UTC, instant);
282 chronology = chronology.withUTC();
283 iLocalMillis = chronology.millisOfDay().get(localMillis);
284 iChronology = chronology;
285 }
286
287 //-----------------------------------------------------------------------
288 /**
289 * Constructs an instance from an Object that represents a datetime.
290 * <p>
291 * If the object contains no chronology, <code>ISOChronology</code> is used.
292 * If the object contains no time zone, the default zone is used.
293 * Once the constructor is completed, the zone is no longer used.
294 * <p>
295 * The recognised object types are defined in
296 * {@link org.joda.time.convert.ConverterManager ConverterManager} and
297 * include ReadablePartial, ReadableInstant, String, Calendar and Date.
298 * The String formats are described by {@link ISODateTimeFormat#localTimeParser()}.
299 * The default String converter ignores the zone and only parses the field values.
300 *
301 * @param instant the datetime object
302 * @throws IllegalArgumentException if the instant is invalid
303 */
304 public LocalTime(Object instant) {
305 this(instant, (Chronology) null);
306 }
307
308 /**
309 * Constructs an instance from an Object that represents a datetime,
310 * forcing the time zone to that specified.
311 * <p>
312 * If the object contains no chronology, <code>ISOChronology</code> is used.
313 * If the specified time zone is null, the default zone is used.
314 * Once the constructor is completed, the zone is no longer used.
315 * <p>
316 * The recognised object types are defined in
317 * {@link org.joda.time.convert.ConverterManager ConverterManager} and
318 * include ReadablePartial, ReadableInstant, String, Calendar and Date.
319 * The String formats are described by {@link ISODateTimeFormat#localTimeParser()}.
320 * The default String converter ignores the zone and only parses the field values.
321 *
322 * @param instant the datetime object
323 * @param zone the time zone
324 * @throws IllegalArgumentException if the instant is invalid
325 */
326 public LocalTime(Object instant, DateTimeZone zone) {
327 PartialConverter converter = ConverterManager.getInstance().getPartialConverter(instant);
328 Chronology chronology = converter.getChronology(instant, zone);
329 chronology = DateTimeUtils.getChronology(chronology);
330 iChronology = chronology.withUTC();
331 int[] values = converter.getPartialValues(this, instant, chronology, ISODateTimeFormat.localTimeParser());
332 iLocalMillis = iChronology.getDateTimeMillis(0L, values[0], values[1], values[2], values[3]);
333 }
334
335 /**
336 * Constructs an instance from an Object that represents a datetime,
337 * using the specified chronology.
338 * <p>
339 * If the chronology is null, ISO in the default time zone is used.
340 * Once the constructor is completed, the zone is no longer used.
341 * <p>
342 * The recognised object types are defined in
343 * {@link org.joda.time.convert.ConverterManager ConverterManager} and
344 * include ReadablePartial, ReadableInstant, String, Calendar and Date.
345 * The String formats are described by {@link ISODateTimeFormat#localTimeParser()}.
346 * The default String converter ignores the zone and only parses the field values.
347 *
348 * @param instant the datetime object
349 * @param chronology the chronology
350 * @throws IllegalArgumentException if the instant is invalid
351 */
352 public LocalTime(Object instant, Chronology chronology) {
353 PartialConverter converter = ConverterManager.getInstance().getPartialConverter(instant);
354 chronology = converter.getChronology(instant, chronology);
355 chronology = DateTimeUtils.getChronology(chronology);
356 iChronology = chronology.withUTC();
357 int[] values = converter.getPartialValues(this, instant, chronology, ISODateTimeFormat.localTimeParser());
358 iLocalMillis = iChronology.getDateTimeMillis(0L, values[0], values[1], values[2], values[3]);
359 }
360
361 //-----------------------------------------------------------------------
362 /**
363 * Constructs an instance set to the specified time
364 * using <code>ISOChronology</code>.
365 *
366 * @param hourOfDay the hour of the day
367 * @param minuteOfHour the minute of the hour
368 */
369 public LocalTime(
370 int hourOfDay,
371 int minuteOfHour) {
372 this(hourOfDay, minuteOfHour, 0, 0, ISOChronology.getInstanceUTC());
373 }
374
375 /**
376 * Constructs an instance set to the specified time
377 * using <code>ISOChronology</code>.
378 *
379 * @param hourOfDay the hour of the day
380 * @param minuteOfHour the minute of the hour
381 * @param secondOfMinute the second of the minute
382 */
383 public LocalTime(
384 int hourOfDay,
385 int minuteOfHour,
386 int secondOfMinute) {
387 this(hourOfDay, minuteOfHour, secondOfMinute, 0, ISOChronology.getInstanceUTC());
388 }
389
390 /**
391 * Constructs an instance set to the specified time
392 * using <code>ISOChronology</code>.
393 *
394 * @param hourOfDay the hour of the day
395 * @param minuteOfHour the minute of the hour
396 * @param secondOfMinute the second of the minute
397 * @param millisOfSecond the millisecond of the second
398 */
399 public LocalTime(
400 int hourOfDay,
401 int minuteOfHour,
402 int secondOfMinute,
403 int millisOfSecond) {
404 this(hourOfDay, minuteOfHour, secondOfMinute,
405 millisOfSecond, ISOChronology.getInstanceUTC());
406 }
407
408 /**
409 * Constructs an instance set to the specified time
410 * using the specified chronology, whose zone is ignored.
411 * <p>
412 * If the chronology is null, <code>ISOChronology</code> is used.
413 *
414 * @param hourOfDay the hour of the day
415 * @param minuteOfHour the minute of the hour
416 * @param secondOfMinute the second of the minute
417 * @param millisOfSecond the millisecond of the second
418 * @param chronology the chronology, null means ISOChronology in default zone
419 */
420 public LocalTime(
421 int hourOfDay,
422 int minuteOfHour,
423 int secondOfMinute,
424 int millisOfSecond,
425 Chronology chronology) {
426 super();
427 chronology = DateTimeUtils.getChronology(chronology).withUTC();
428 long instant = chronology.getDateTimeMillis(
429 0L, hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond);
430 iChronology = chronology;
431 iLocalMillis = instant;
432 }
433
434 //-----------------------------------------------------------------------
435 /**
436 * Gets the number of fields in this partial, which is four.
437 * The supported fields are HourOfDay, MinuteOfHour, SecondOfMinute
438 * and MillisOfSecond.
439 *
440 * @return the field count, four
441 */
442 public int size() {
443 return 4;
444 }
445
446 /**
447 * Gets the field for a specific index in the chronology specified.
448 * <p>
449 * This method must not use any instance variables.
450 *
451 * @param index the index to retrieve
452 * @param chrono the chronology to use
453 * @return the field
454 */
455 protected DateTimeField getField(int index, Chronology chrono) {
456 switch (index) {
457 case HOUR_OF_DAY:
458 return chrono.hourOfDay();
459 case MINUTE_OF_HOUR:
460 return chrono.minuteOfHour();
461 case SECOND_OF_MINUTE:
462 return chrono.secondOfMinute();
463 case MILLIS_OF_SECOND:
464 return chrono.millisOfSecond();
465 default:
466 throw new IndexOutOfBoundsException("Invalid index: " + index);
467 }
468 }
469
470 /**
471 * Gets the value of the field at the specifed index.
472 * <p>
473 * This method is required to support the <code>ReadablePartial</code>
474 * interface. The supported fields are HourOfDay, MinuteOfHour,
475 * SecondOfMinute and MillisOfSecond.
476 *
477 * @param index the index, zero to three
478 * @return the value
479 * @throws IndexOutOfBoundsException if the index is invalid
480 */
481 public int getValue(int index) {
482 switch (index) {
483 case HOUR_OF_DAY:
484 return getChronology().hourOfDay().get(getLocalMillis());
485 case MINUTE_OF_HOUR:
486 return getChronology().minuteOfHour().get(getLocalMillis());
487 case SECOND_OF_MINUTE:
488 return getChronology().secondOfMinute().get(getLocalMillis());
489 case MILLIS_OF_SECOND:
490 return getChronology().millisOfSecond().get(getLocalMillis());
491 default:
492 throw new IndexOutOfBoundsException("Invalid index: " + index);
493 }
494 }
495
496 //-----------------------------------------------------------------------
497 /**
498 * Get the value of one of the fields of time.
499 * <p>
500 * This method gets the value of the specified field.
501 * For example:
502 * <pre>
503 * DateTime dt = new DateTime();
504 * int hourOfDay = dt.get(DateTimeFieldType.hourOfDay());
505 * </pre>
506 *
507 * @param fieldType a field type, usually obtained from DateTimeFieldType, not null
508 * @return the value of that field
509 * @throws IllegalArgumentException if the field type is null
510 */
511 public int get(DateTimeFieldType fieldType) {
512 if (fieldType == null) {
513 throw new IllegalArgumentException("The DateTimeFieldType must not be null");
514 }
515 if (isSupported(fieldType) == false) {
516 throw new IllegalArgumentException("Field '" + fieldType + "' is not supported");
517 }
518 return fieldType.getField(getChronology()).get(getLocalMillis());
519 }
520
521 /**
522 * Checks if the field type specified is supported by this
523 * local time and chronology.
524 * This can be used to avoid exceptions in {@link #get(DateTimeFieldType)}.
525 *
526 * @param type a field type, usually obtained from DateTimeFieldType
527 * @return true if the field type is supported
528 */
529 public boolean isSupported(DateTimeFieldType type) {
530 if (type == null) {
531 return false;
532 }
533 if (isSupported(type.getDurationType()) == false) {
534 return false;
535 }
536 DurationFieldType range = type.getRangeDurationType();
537 return (isSupported(range) || range == DurationFieldType.days());
538 }
539
540 /**
541 * Checks if the duration type specified is supported by this
542 * local time and chronology.
543 *
544 * @param type a duration type, usually obtained from DurationFieldType
545 * @return true if the field type is supported
546 */
547 public boolean isSupported(DurationFieldType type) {
548 if (type == null) {
549 return false;
550 }
551 DurationField field = type.getField(getChronology());
552 if (TIME_DURATION_TYPES.contains(type) ||
553 field.getUnitMillis() < getChronology().days().getUnitMillis()) {
554 return field.isSupported();
555 }
556 return false;
557 }
558
559 //-----------------------------------------------------------------------
560 /**
561 * Gets the local milliseconds from the Java epoch
562 * of 1970-01-01T00:00:00 (not fixed to any specific time zone).
563 *
564 * @return the number of milliseconds since 1970-01-01T00:00:00
565 * @since 1.5 (previously private)
566 */
567 protected long getLocalMillis() {
568 return iLocalMillis;
569 }
570
571 /**
572 * Gets the chronology of the time.
573 *
574 * @return the Chronology that the time is using
575 */
576 public Chronology getChronology() {
577 return iChronology;
578 }
579
580 //-----------------------------------------------------------------------
581 /**
582 * Compares this ReadablePartial with another returning true if the chronology,
583 * field types and values are equal.
584 *
585 * @param partial an object to check against
586 * @return true if fields and values are equal
587 */
588 public boolean equals(Object partial) {
589 // override to perform faster
590 if (this == partial) {
591 return true;
592 }
593 if (partial instanceof LocalTime) {
594 LocalTime other = (LocalTime) partial;
595 if (iChronology.equals(other.iChronology)) {
596 return iLocalMillis == other.iLocalMillis;
597 }
598 }
599 return super.equals(partial);
600 }
601
602 /**
603 * Compares this partial with another returning an integer
604 * indicating the order.
605 * <p>
606 * The fields are compared in order, from largest to smallest.
607 * The first field that is non-equal is used to determine the result.
608 * <p>
609 * The specified object must be a partial instance whose field types
610 * match those of this partial.
611 * <p>
612 * NOTE: This implementation violates the Comparable contract.
613 * This method will accept any instance of ReadablePartial as input.
614 * However, it is possible that some implementations of ReadablePartial
615 * exist that do not extend AbstractPartial, and thus will throw a
616 * ClassCastException if compared in the opposite direction.
617 * The cause of this problem is that ReadablePartial doesn't define
618 * the compareTo() method, however we can't change that until v2.0.
619 *
620 * @param partial an object to check against
621 * @return negative if this is less, zero if equal, positive if greater
622 * @throws ClassCastException if the partial is the wrong class
623 * or if it has field types that don't match
624 * @throws NullPointerException if the partial is null
625 */
626 public int compareTo(Object partial) {
627 // override to perform faster
628 if (this == partial) {
629 return 0;
630 }
631 if (partial instanceof LocalTime) {
632 LocalTime other = (LocalTime) partial;
633 if (iChronology.equals(other.iChronology)) {
634 return (iLocalMillis < other.iLocalMillis ? -1 :
635 (iLocalMillis == other.iLocalMillis ? 0 : 1));
636
637 }
638 }
639 return super.compareTo(partial);
640 }
641
642 //-----------------------------------------------------------------------
643 /**
644 * Returns a copy of this time with different local millis.
645 * <p>
646 * The returned object will be a new instance of the same type.
647 * Only the millis will change, the chronology is kept.
648 * The returned object will be either be a new instance or <code>this</code>.
649 *
650 * @param newMillis the new millis, from 1970-01-01T00:00:00
651 * @return a copy of this time with different millis
652 */
653 LocalTime withLocalMillis(long newMillis) {
654 return (newMillis == getLocalMillis() ? this : new LocalTime(newMillis, getChronology()));
655 }
656
657 //-----------------------------------------------------------------------
658 /**
659 * Returns a copy of this time with the partial set of fields replacing
660 * those from this instance.
661 * <p>
662 * For example, if the partial contains an hour and minute then those two
663 * fields will be changed in the returned instance.
664 * Unsupported fields are ignored.
665 * If the partial is null, then <code>this</code> is returned.
666 *
667 * @param partial the partial set of fields to apply to this time, null ignored
668 * @return a copy of this time with a different set of fields
669 * @throws IllegalArgumentException if any value is invalid
670 */
671 public LocalTime withFields(ReadablePartial partial) {
672 if (partial == null) {
673 return this;
674 }
675 return withLocalMillis(getChronology().set(partial, getLocalMillis()));
676 }
677
678 /**
679 * Returns a copy of this time with the specified field set
680 * to a new value.
681 * <p>
682 * For example, if the field type is <code>hourOfDay</code> then the hour of day
683 * field would be changed in the returned instance.
684 * If the field type is null, then <code>this</code> is returned.
685 * <p>
686 * These lines are equivalent:
687 * <pre>
688 * LocalTime updated = dt.withHourOfDay(6);
689 * LocalTime updated = dt.withField(DateTimeFieldType.hourOfDay(), 6);
690 * </pre>
691 *
692 * @param fieldType the field type to set, not null
693 * @param value the value to set
694 * @return a copy of this time with the field set
695 * @throws IllegalArgumentException if the value is null or invalid
696 */
697 public LocalTime withField(DateTimeFieldType fieldType, int value) {
698 if (fieldType == null) {
699 throw new IllegalArgumentException("Field must not be null");
700 }
701 if (isSupported(fieldType) == false) {
702 throw new IllegalArgumentException("Field '" + fieldType + "' is not supported");
703 }
704 long instant = fieldType.getField(getChronology()).set(getLocalMillis(), value);
705 return withLocalMillis(instant);
706 }
707
708 /**
709 * Returns a copy of this time with the value of the specified
710 * field increased.
711 * <p>
712 * If the addition is zero or the field is null, then <code>this</code>
713 * is returned.
714 * <p>
715 * If the addition causes the maximum value of the field to be exceeded,
716 * then the value will wrap. Thus 23:59 plus two minutes yields 00:01.
717 * <p>
718 * These lines are equivalent:
719 * <pre>
720 * LocalTime added = dt.plusHours(6);
721 * LocalTime added = dt.withFieldAdded(DurationFieldType.hours(), 6);
722 * </pre>
723 *
724 * @param fieldType the field type to add to, not null
725 * @param amount the amount to add
726 * @return a copy of this time with the field updated
727 * @throws IllegalArgumentException if the value is null or invalid
728 * @throws ArithmeticException if the result exceeds the internal capacity
729 */
730 public LocalTime withFieldAdded(DurationFieldType fieldType, int amount) {
731 if (fieldType == null) {
732 throw new IllegalArgumentException("Field must not be null");
733 }
734 if (isSupported(fieldType) == false) {
735 throw new IllegalArgumentException("Field '" + fieldType + "' is not supported");
736 }
737 if (amount == 0) {
738 return this;
739 }
740 long instant = fieldType.getField(getChronology()).add(getLocalMillis(), amount);
741 return withLocalMillis(instant);
742 }
743
744 //-----------------------------------------------------------------------
745 /**
746 * Returns a copy of this time with the specified period added.
747 * <p>
748 * If the addition is zero, then <code>this</code> is returned.
749 * <p>
750 * This method is typically used to add multiple copies of complex
751 * period instances. Adding one field is best achieved using methods
752 * like {@link #withFieldAdded(DurationFieldType, int)}
753 * or {@link #plusHours(int)}.
754 *
755 * @param period the period to add to this one, null means zero
756 * @param scalar the amount of times to add, such as -1 to subtract once
757 * @return a copy of this time with the period added
758 * @throws ArithmeticException if the result exceeds the internal capacity
759 */
760 public LocalTime withPeriodAdded(ReadablePeriod period, int scalar) {
761 if (period == null || scalar == 0) {
762 return this;
763 }
764 long instant = getChronology().add(period, getLocalMillis(), scalar);
765 return withLocalMillis(instant);
766 }
767
768 //-----------------------------------------------------------------------
769 /**
770 * Returns a copy of this time with the specified period added.
771 * <p>
772 * If the amount is zero or null, then <code>this</code> is returned.
773 * <p>
774 * This method is typically used to add complex period instances.
775 * Adding one field is best achieved using methods
776 * like {@link #plusHours(int)}.
777 *
778 * @param period the period to add to this one, null means zero
779 * @return a copy of this time with the period added
780 * @throws ArithmeticException if the result exceeds the internal capacity
781 */
782 public LocalTime plus(ReadablePeriod period) {
783 return withPeriodAdded(period, 1);
784 }
785
786 //-----------------------------------------------------------------------
787 /**
788 * Returns a copy of this time plus the specified number of hours.
789 * <p>
790 * This LocalTime instance is immutable and unaffected by this method call.
791 * <p>
792 * The following three lines are identical in effect:
793 * <pre>
794 * LocalTime added = dt.plusHours(6);
795 * LocalTime added = dt.plus(Period.hours(6));
796 * LocalTime added = dt.withFieldAdded(DurationFieldType.hours(), 6);
797 * </pre>
798 *
799 * @param hours the amount of hours to add, may be negative
800 * @return the new LocalTime plus the increased hours
801 */
802 public LocalTime plusHours(int hours) {
803 if (hours == 0) {
804 return this;
805 }
806 long instant = getChronology().hours().add(getLocalMillis(), hours);
807 return withLocalMillis(instant);
808 }
809
810 /**
811 * Returns a copy of this time plus the specified number of minutes.
812 * <p>
813 * This LocalTime instance is immutable and unaffected by this method call.
814 * <p>
815 * The following three lines are identical in effect:
816 * <pre>
817 * LocalTime added = dt.plusMinutes(6);
818 * LocalTime added = dt.plus(Period.minutes(6));
819 * LocalTime added = dt.withFieldAdded(DurationFieldType.minutes(), 6);
820 * </pre>
821 *
822 * @param minutes the amount of minutes to add, may be negative
823 * @return the new LocalTime plus the increased minutes
824 */
825 public LocalTime plusMinutes(int minutes) {
826 if (minutes == 0) {
827 return this;
828 }
829 long instant = getChronology().minutes().add(getLocalMillis(), minutes);
830 return withLocalMillis(instant);
831 }
832
833 /**
834 * Returns a copy of this time plus the specified number of seconds.
835 * <p>
836 * This LocalTime instance is immutable and unaffected by this method call.
837 * <p>
838 * The following three lines are identical in effect:
839 * <pre>
840 * LocalTime added = dt.plusSeconds(6);
841 * LocalTime added = dt.plus(Period.seconds(6));
842 * LocalTime added = dt.withFieldAdded(DurationFieldType.seconds(), 6);
843 * </pre>
844 *
845 * @param seconds the amount of seconds to add, may be negative
846 * @return the new LocalTime plus the increased seconds
847 */
848 public LocalTime plusSeconds(int seconds) {
849 if (seconds == 0) {
850 return this;
851 }
852 long instant = getChronology().seconds().add(getLocalMillis(), seconds);
853 return withLocalMillis(instant);
854 }
855
856 /**
857 * Returns a copy of this time plus the specified number of millis.
858 * <p>
859 * This LocalTime instance is immutable and unaffected by this method call.
860 * <p>
861 * The following three lines are identical in effect:
862 * <pre>
863 * LocalTime added = dt.plusMillis(6);
864 * LocalTime added = dt.plus(Period.millis(6));
865 * LocalTime added = dt.withFieldAdded(DurationFieldType.millis(), 6);
866 * </pre>
867 *
868 * @param millis the amount of millis to add, may be negative
869 * @return the new LocalTime plus the increased millis
870 */
871 public LocalTime plusMillis(int millis) {
872 if (millis == 0) {
873 return this;
874 }
875 long instant = getChronology().millis().add(getLocalMillis(), millis);
876 return withLocalMillis(instant);
877 }
878
879 //-----------------------------------------------------------------------
880 /**
881 * Returns a copy of this time with the specified period taken away.
882 * <p>
883 * If the amount is zero or null, then <code>this</code> is returned.
884 * <p>
885 * This method is typically used to subtract complex period instances.
886 * Subtracting one field is best achieved using methods
887 * like {@link #minusHours(int)}.
888 *
889 * @param period the period to reduce this instant by
890 * @return a copy of this time with the period taken away
891 * @throws ArithmeticException if the result exceeds the internal capacity
892 */
893 public LocalTime minus(ReadablePeriod period) {
894 return withPeriodAdded(period, -1);
895 }
896
897 //-----------------------------------------------------------------------
898 /**
899 * Returns a copy of this time minus the specified number of hours.
900 * <p>
901 * This LocalTime instance is immutable and unaffected by this method call.
902 * <p>
903 * The following three lines are identical in effect:
904 * <pre>
905 * LocalTime subtracted = dt.minusHours(6);
906 * LocalTime subtracted = dt.minus(Period.hours(6));
907 * LocalTime subtracted = dt.withFieldAdded(DurationFieldType.hours(), -6);
908 * </pre>
909 *
910 * @param hours the amount of hours to subtract, may be negative
911 * @return the new LocalTime minus the increased hours
912 */
913 public LocalTime minusHours(int hours) {
914 if (hours == 0) {
915 return this;
916 }
917 long instant = getChronology().hours().subtract(getLocalMillis(), hours);
918 return withLocalMillis(instant);
919 }
920
921 /**
922 * Returns a copy of this time minus the specified number of minutes.
923 * <p>
924 * This LocalTime instance is immutable and unaffected by this method call.
925 * <p>
926 * The following three lines are identical in effect:
927 * <pre>
928 * LocalTime subtracted = dt.minusMinutes(6);
929 * LocalTime subtracted = dt.minus(Period.minutes(6));
930 * LocalTime subtracted = dt.withFieldAdded(DurationFieldType.minutes(), -6);
931 * </pre>
932 *
933 * @param minutes the amount of minutes to subtract, may be negative
934 * @return the new LocalTime minus the increased minutes
935 */
936 public LocalTime minusMinutes(int minutes) {
937 if (minutes == 0) {
938 return this;
939 }
940 long instant = getChronology().minutes().subtract(getLocalMillis(), minutes);
941 return withLocalMillis(instant);
942 }
943
944 /**
945 * Returns a copy of this time minus the specified number of seconds.
946 * <p>
947 * This LocalTime instance is immutable and unaffected by this method call.
948 * <p>
949 * The following three lines are identical in effect:
950 * <pre>
951 * LocalTime subtracted = dt.minusSeconds(6);
952 * LocalTime subtracted = dt.minus(Period.seconds(6));
953 * LocalTime subtracted = dt.withFieldAdded(DurationFieldType.seconds(), -6);
954 * </pre>
955 *
956 * @param seconds the amount of seconds to subtract, may be negative
957 * @return the new LocalTime minus the increased seconds
958 */
959 public LocalTime minusSeconds(int seconds) {
960 if (seconds == 0) {
961 return this;
962 }
963 long instant = getChronology().seconds().subtract(getLocalMillis(), seconds);
964 return withLocalMillis(instant);
965 }
966
967 /**
968 * Returns a copy of this time minus the specified number of millis.
969 * <p>
970 * This LocalTime instance is immutable and unaffected by this method call.
971 * <p>
972 * The following three lines are identical in effect:
973 * <pre>
974 * LocalTime subtracted = dt.minusMillis(6);
975 * LocalTime subtracted = dt.minus(Period.millis(6));
976 * LocalTime subtracted = dt.withFieldAdded(DurationFieldType.millis(), -6);
977 * </pre>
978 *
979 * @param millis the amount of millis to subtract, may be negative
980 * @return the new LocalTime minus the increased millis
981 */
982 public LocalTime minusMillis(int millis) {
983 if (millis == 0) {
984 return this;
985 }
986 long instant = getChronology().millis().subtract(getLocalMillis(), millis);
987 return withLocalMillis(instant);
988 }
989
990 //-----------------------------------------------------------------------
991 /**
992 * Gets the property object for the specified type, which contains
993 * many useful methods.
994 *
995 * @param fieldType the field type to get the chronology for
996 * @return the property object
997 * @throws IllegalArgumentException if the field is null or unsupported
998 */
999 public Property property(DateTimeFieldType fieldType) {
1000 if (fieldType == null) {
1001 throw new IllegalArgumentException("The DateTimeFieldType must not be null");
1002 }
1003 if (isSupported(fieldType) == false) {
1004 throw new IllegalArgumentException("Field '" + fieldType + "' is not supported");
1005 }
1006 return new Property(this, fieldType.getField(getChronology()));
1007 }
1008
1009 //-----------------------------------------------------------------------
1010 /**
1011 * Get the hour of day field value.
1012 *
1013 * @return the hour of day
1014 */
1015 public int getHourOfDay() {
1016 return getChronology().hourOfDay().get(getLocalMillis());
1017 }
1018
1019 /**
1020 * Get the minute of hour field value.
1021 *
1022 * @return the minute of hour
1023 */
1024 public int getMinuteOfHour() {
1025 return getChronology().minuteOfHour().get(getLocalMillis());
1026 }
1027
1028 /**
1029 * Get the second of minute field value.
1030 *
1031 * @return the second of minute
1032 */
1033 public int getSecondOfMinute() {
1034 return getChronology().secondOfMinute().get(getLocalMillis());
1035 }
1036
1037 /**
1038 * Get the millis of second field value.
1039 *
1040 * @return the millis of second
1041 */
1042 public int getMillisOfSecond() {
1043 return getChronology().millisOfSecond().get(getLocalMillis());
1044 }
1045
1046 /**
1047 * Get the millis of day field value.
1048 *
1049 * @return the millis of day
1050 */
1051 public int getMillisOfDay() {
1052 return getChronology().millisOfDay().get(getLocalMillis());
1053 }
1054
1055 //-----------------------------------------------------------------------
1056 /**
1057 * Returns a copy of this time with the hour of day field updated.
1058 * <p>
1059 * LocalTime is immutable, so there are no set methods.
1060 * Instead, this method returns a new instance with the value of
1061 * hour of day changed.
1062 *
1063 * @param hour the hour of day to set
1064 * @return a copy of this object with the field set
1065 * @throws IllegalArgumentException if the value is invalid
1066 */
1067 public LocalTime withHourOfDay(int hour) {
1068 return withLocalMillis(getChronology().hourOfDay().set(getLocalMillis(), hour));
1069 }
1070
1071 /**
1072 * Returns a copy of this time with the minute of hour field updated.
1073 * <p>
1074 * LocalTime is immutable, so there are no set methods.
1075 * Instead, this method returns a new instance with the value of
1076 * minute of hour changed.
1077 *
1078 * @param minute the minute of hour to set
1079 * @return a copy of this object with the field set
1080 * @throws IllegalArgumentException if the value is invalid
1081 */
1082 public LocalTime withMinuteOfHour(int minute) {
1083 return withLocalMillis(getChronology().minuteOfHour().set(getLocalMillis(), minute));
1084 }
1085
1086 /**
1087 * Returns a copy of this time with the second of minute field updated.
1088 * <p>
1089 * LocalTime is immutable, so there are no set methods.
1090 * Instead, this method returns a new instance with the value of
1091 * second of minute changed.
1092 *
1093 * @param second the second of minute to set
1094 * @return a copy of this object with the field set
1095 * @throws IllegalArgumentException if the value is invalid
1096 */
1097 public LocalTime withSecondOfMinute(int second) {
1098 return withLocalMillis(getChronology().secondOfMinute().set(getLocalMillis(), second));
1099 }
1100
1101 /**
1102 * Returns a copy of this time with the millis of second field updated.
1103 * <p>
1104 * LocalTime is immutable, so there are no set methods.
1105 * Instead, this method returns a new instance with the value of
1106 * millis of second changed.
1107 *
1108 * @param millis the millis of second to set
1109 * @return a copy of this object with the field set
1110 * @throws IllegalArgumentException if the value is invalid
1111 */
1112 public LocalTime withMillisOfSecond(int millis) {
1113 return withLocalMillis(getChronology().millisOfSecond().set(getLocalMillis(), millis));
1114 }
1115
1116 /**
1117 * Returns a copy of this time with the millis of day field updated.
1118 * <p>
1119 * LocalTime is immutable, so there are no set methods.
1120 * Instead, this method returns a new instance with the value of
1121 * millis of day changed.
1122 *
1123 * @param millis the millis of day to set
1124 * @return a copy of this object with the field set
1125 * @throws IllegalArgumentException if the value is invalid
1126 */
1127 public LocalTime withMillisOfDay(int millis) {
1128 return withLocalMillis(getChronology().millisOfDay().set(getLocalMillis(), millis));
1129 }
1130
1131 //-----------------------------------------------------------------------
1132 /**
1133 * Get the hour of day field property which provides access to advanced functionality.
1134 *
1135 * @return the hour of day property
1136 */
1137 public Property hourOfDay() {
1138 return new Property(this, getChronology().hourOfDay());
1139 }
1140
1141 /**
1142 * Get the minute of hour field property which provides access to advanced functionality.
1143 *
1144 * @return the minute of hour property
1145 */
1146 public Property minuteOfHour() {
1147 return new Property(this, getChronology().minuteOfHour());
1148 }
1149
1150 /**
1151 * Get the second of minute field property which provides access to advanced functionality.
1152 *
1153 * @return the second of minute property
1154 */
1155 public Property secondOfMinute() {
1156 return new Property(this, getChronology().secondOfMinute());
1157 }
1158
1159 /**
1160 * Get the millis of second property which provides access to advanced functionality.
1161 *
1162 * @return the millis of second property
1163 */
1164 public Property millisOfSecond() {
1165 return new Property(this, getChronology().millisOfSecond());
1166 }
1167
1168 /**
1169 * Get the millis of day property which provides access to advanced functionality.
1170 *
1171 * @return the millis of day property
1172 */
1173 public Property millisOfDay() {
1174 return new Property(this, getChronology().millisOfDay());
1175 }
1176
1177 //-----------------------------------------------------------------------
1178 /**
1179 * Converts this LocalTime to a full datetime using the default time zone
1180 * setting the time fields from this instance and the date fields from
1181 * the current date.
1182 *
1183 * @return this time as a datetime using todays date
1184 */
1185 public DateTime toDateTimeToday() {
1186 return toDateTimeToday(null);
1187 }
1188
1189 /**
1190 * Converts this LocalTime to a full datetime using the specified time zone
1191 * setting the time fields from this instance and the date fields from
1192 * the current time.
1193 * <p>
1194 * This method uses the chronology from this instance plus the time zone
1195 * specified.
1196 *
1197 * @param zone the zone to use, null means default
1198 * @return this time as a datetime using todays date
1199 */
1200 public DateTime toDateTimeToday(DateTimeZone zone) {
1201 Chronology chrono = getChronology().withZone(zone);
1202 long instantMillis = DateTimeUtils.currentTimeMillis();
1203 long resolved = chrono.set(this, instantMillis);
1204 return new DateTime(resolved, chrono);
1205 }
1206
1207 //-----------------------------------------------------------------------
1208 /**
1209 * Output the time in ISO8601 format (HH:mm:ss.SSSZZ).
1210 *
1211 * @return ISO8601 time formatted string.
1212 */
1213 public String toString() {
1214 return ISODateTimeFormat.time().print(this);
1215 }
1216
1217 /**
1218 * Output the time using the specified format pattern.
1219 *
1220 * @param pattern the pattern specification, null means use <code>toString</code>
1221 * @see org.joda.time.format.DateTimeFormat
1222 */
1223 public String toString(String pattern) {
1224 if (pattern == null) {
1225 return toString();
1226 }
1227 return DateTimeFormat.forPattern(pattern).print(this);
1228 }
1229
1230 /**
1231 * Output the time using the specified format pattern.
1232 *
1233 * @param pattern the pattern specification, null means use <code>toString</code>
1234 * @param locale Locale to use, null means default
1235 * @see org.joda.time.format.DateTimeFormat
1236 */
1237 public String toString(String pattern, Locale locale) throws IllegalArgumentException {
1238 if (pattern == null) {
1239 return toString();
1240 }
1241 return DateTimeFormat.forPattern(pattern).withLocale(locale).print(this);
1242 }
1243
1244 //-----------------------------------------------------------------------
1245 /**
1246 * LocalTime.Property binds a LocalTime to a DateTimeField allowing
1247 * powerful datetime functionality to be easily accessed.
1248 * <p>
1249 * The simplest use of this class is as an alternative get method, here used to
1250 * get the minute '30'.
1251 * <pre>
1252 * LocalTime dt = new LocalTime(12, 30);
1253 * int year = dt.minuteOfHour().get();
1254 * </pre>
1255 * <p>
1256 * Methods are also provided that allow time modification. These return
1257 * new instances of LocalTime - they do not modify the original. The example
1258 * below yields two independent immutable date objects 2 hours apart.
1259 * <pre>
1260 * LocalTime dt1230 = new LocalTime(12, 30);
1261 * LocalTime dt1430 = dt1230.hourOfDay().setCopy(14);
1262 * </pre>
1263 * <p>
1264 * LocalTime.Property itself is thread-safe and immutable, as well as the
1265 * LocalTime being operated on.
1266 *
1267 * @author Stephen Colebourne
1268 * @author Brian S O'Neill
1269 * @since 1.3
1270 */
1271 public static final class Property extends AbstractReadableInstantFieldProperty {
1272
1273 /** Serialization version */
1274 private static final long serialVersionUID = -325842547277223L;
1275
1276 /** The instant this property is working against */
1277 private transient LocalTime iInstant;
1278 /** The field this property is working against */
1279 private transient DateTimeField iField;
1280
1281 /**
1282 * Constructor.
1283 *
1284 * @param instant the instant to set
1285 * @param field the field to use
1286 */
1287 Property(LocalTime instant, DateTimeField field) {
1288 super();
1289 iInstant = instant;
1290 iField = field;
1291 }
1292
1293 /**
1294 * Writes the property in a safe serialization format.
1295 */
1296 private void writeObject(ObjectOutputStream oos) throws IOException {
1297 oos.writeObject(iInstant);
1298 oos.writeObject(iField.getType());
1299 }
1300
1301 /**
1302 * Reads the property from a safe serialization format.
1303 */
1304 private void readObject(ObjectInputStream oos) throws IOException, ClassNotFoundException {
1305 iInstant = (LocalTime) oos.readObject();
1306 DateTimeFieldType type = (DateTimeFieldType) oos.readObject();
1307 iField = type.getField(iInstant.getChronology());
1308 }
1309
1310 //-----------------------------------------------------------------------
1311 /**
1312 * Gets the field being used.
1313 *
1314 * @return the field
1315 */
1316 public DateTimeField getField() {
1317 return iField;
1318 }
1319
1320 /**
1321 * Gets the milliseconds of the time that this property is linked to.
1322 *
1323 * @return the milliseconds
1324 */
1325 protected long getMillis() {
1326 return iInstant.getLocalMillis();
1327 }
1328
1329 /**
1330 * Gets the chronology of the datetime that this property is linked to.
1331 *
1332 * @return the chronology
1333 * @since 1.4
1334 */
1335 protected Chronology getChronology() {
1336 return iInstant.getChronology();
1337 }
1338
1339 /**
1340 * Gets the LocalTime object linked to this property.
1341 *
1342 * @return the linked LocalTime
1343 */
1344 public LocalTime getLocalTime() {
1345 return iInstant;
1346 }
1347
1348 //-----------------------------------------------------------------------
1349 /**
1350 * Adds to this field in a copy of this LocalTime.
1351 * <p>
1352 * The LocalTime attached to this property is unchanged by this call.
1353 *
1354 * @param value the value to add to the field in the copy
1355 * @return a copy of the LocalTime with the field value changed
1356 */
1357 public LocalTime addCopy(int value) {
1358 return iInstant.withLocalMillis(iField.add(iInstant.getLocalMillis(), value));
1359 }
1360
1361 /**
1362 * Adds to this field in a copy of this LocalTime.
1363 * If the addition exceeds the maximum value (eg. 23:59) it will
1364 * wrap to the minimum value (eg. 00:00).
1365 * <p>
1366 * The LocalTime attached to this property is unchanged by this call.
1367 *
1368 * @param value the value to add to the field in the copy
1369 * @return a copy of the LocalTime with the field value changed
1370 */
1371 public LocalTime addCopy(long value) {
1372 return iInstant.withLocalMillis(iField.add(iInstant.getLocalMillis(), value));
1373 }
1374
1375 /**
1376 * Adds to this field in a copy of this LocalTime.
1377 * If the addition exceeds the maximum value (eg. 23:59) then
1378 * an exception will be thrown.
1379 * Contrast this behaviour to {@link #addCopy(int)}.
1380 * <p>
1381 * The LocalTime attached to this property is unchanged by this call.
1382 *
1383 * @param value the value to add to the field in the copy
1384 * @return a copy of the LocalTime with the field value changed
1385 * @throws IllegalArgumentException if the result is invalid
1386 */
1387 public LocalTime addNoWrapToCopy(int value) {
1388 long millis = iField.add(iInstant.getLocalMillis(), value);
1389 long rounded = iInstant.getChronology().millisOfDay().get(millis);
1390 if (rounded != millis) {
1391 throw new IllegalArgumentException("The addition exceeded the boundaries of LocalTime");
1392 }
1393 return iInstant.withLocalMillis(millis);
1394 }
1395
1396 /**
1397 * Adds to this field, possibly wrapped, in a copy of this LocalTime.
1398 * A field wrapped operation only changes this field.
1399 * Thus 10:59 plusWrapField one minute goes to 10:00.
1400 * <p>
1401 * The LocalTime attached to this property is unchanged by this call.
1402 *
1403 * @param value the value to add to the field in the copy
1404 * @return a copy of the LocalTime with the field value changed
1405 * @throws IllegalArgumentException if the value isn't valid
1406 */
1407 public LocalTime addWrapFieldToCopy(int value) {
1408 return iInstant.withLocalMillis(iField.addWrapField(iInstant.getLocalMillis(), value));
1409 }
1410
1411 //-----------------------------------------------------------------------
1412 /**
1413 * Sets this field in a copy of the LocalTime.
1414 * <p>
1415 * The LocalTime attached to this property is unchanged by this call.
1416 *
1417 * @param value the value to set the field in the copy to
1418 * @return a copy of the LocalTime with the field value changed
1419 * @throws IllegalArgumentException if the value isn't valid
1420 */
1421 public LocalTime setCopy(int value) {
1422 return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), value));
1423 }
1424
1425 /**
1426 * Sets this field in a copy of the LocalTime to a parsed text value.
1427 * <p>
1428 * The LocalTime attached to this property is unchanged by this call.
1429 *
1430 * @param text the text value to set
1431 * @param locale optional locale to use for selecting a text symbol
1432 * @return a copy of the LocalTime with the field value changed
1433 * @throws IllegalArgumentException if the text value isn't valid
1434 */
1435 public LocalTime setCopy(String text, Locale locale) {
1436 return iInstant.withLocalMillis(iField.set(iInstant.getLocalMillis(), text, locale));
1437 }
1438
1439 /**
1440 * Sets this field in a copy of the LocalTime to a parsed text value.
1441 * <p>
1442 * The LocalTime attached to this property is unchanged by this call.
1443 *
1444 * @param text the text value to set
1445 * @return a copy of the LocalTime with the field value changed
1446 * @throws IllegalArgumentException if the text value isn't valid
1447 */
1448 public LocalTime setCopy(String text) {
1449 return setCopy(text, null);
1450 }
1451
1452 //-----------------------------------------------------------------------
1453 /**
1454 * Returns a new LocalTime with this field set to the maximum value
1455 * for this field.
1456 * <p>
1457 * The LocalTime attached to this property is unchanged by this call.
1458 *
1459 * @return a copy of the LocalTime with this field set to its maximum
1460 */
1461 public LocalTime withMaximumValue() {
1462 return setCopy(getMaximumValue());
1463 }
1464
1465 /**
1466 * Returns a new LocalTime with this field set to the minimum value
1467 * for this field.
1468 * <p>
1469 * The LocalTime attached to this property is unchanged by this call.
1470 *
1471 * @return a copy of the LocalTime with this field set to its minimum
1472 */
1473 public LocalTime withMinimumValue() {
1474 return setCopy(getMinimumValue());
1475 }
1476
1477 //-----------------------------------------------------------------------
1478 /**
1479 * Rounds to the lowest whole unit of this field on a copy of this
1480 * LocalTime.
1481 * <p>
1482 * For example, rounding floor on the hourOfDay field of a LocalTime
1483 * where the time is 10:30 would result in new LocalTime with the
1484 * time of 10:00.
1485 *
1486 * @return a copy of the LocalTime with the field value changed
1487 */
1488 public LocalTime roundFloorCopy() {
1489 return iInstant.withLocalMillis(iField.roundFloor(iInstant.getLocalMillis()));
1490 }
1491
1492 /**
1493 * Rounds to the highest whole unit of this field on a copy of this
1494 * LocalTime.
1495 * <p>
1496 * For example, rounding floor on the hourOfDay field of a LocalTime
1497 * where the time is 10:30 would result in new LocalTime with the
1498 * time of 11:00.
1499 *
1500 * @return a copy of the LocalTime with the field value changed
1501 */
1502 public LocalTime roundCeilingCopy() {
1503 return iInstant.withLocalMillis(iField.roundCeiling(iInstant.getLocalMillis()));
1504 }
1505
1506 /**
1507 * Rounds to the nearest whole unit of this field on a copy of this
1508 * LocalTime, favoring the floor if halfway.
1509 *
1510 * @return a copy of the LocalTime with the field value changed
1511 */
1512 public LocalTime roundHalfFloorCopy() {
1513 return iInstant.withLocalMillis(iField.roundHalfFloor(iInstant.getLocalMillis()));
1514 }
1515
1516 /**
1517 * Rounds to the nearest whole unit of this field on a copy of this
1518 * LocalTime, favoring the ceiling if halfway.
1519 *
1520 * @return a copy of the LocalTime with the field value changed
1521 */
1522 public LocalTime roundHalfCeilingCopy() {
1523 return iInstant.withLocalMillis(iField.roundHalfCeiling(iInstant.getLocalMillis()));
1524 }
1525
1526 /**
1527 * Rounds to the nearest whole unit of this field on a copy of this
1528 * LocalTime. If halfway, the ceiling is favored over the floor
1529 * only if it makes this field's value even.
1530 *
1531 * @return a copy of the LocalTime with the field value changed
1532 */
1533 public LocalTime roundHalfEvenCopy() {
1534 return iInstant.withLocalMillis(iField.roundHalfEven(iInstant.getLocalMillis()));
1535 }
1536 }
1537
1538 }