EMMA Coverage Report (generated Tue Oct 28 00:01:11 GMT 2008)
[all classes][org.joda.time]

COVERAGE SUMMARY FOR SOURCE FILE [LocalTime.java]

nameclass, %method, %block, %line, %
LocalTime.java100% (2/2)95%  (81/85)96%  (1128/1180)95%  (218.9/230)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class LocalTime$Property100% (1/1)86%  (18/21)81%  (163/201)76%  (25/33)
addCopy (long): LocalTime 0%   (0/1)0%   (0/11)0%   (0/1)
readObject (ObjectInputStream): void 0%   (0/1)0%   (0/17)0%   (0/4)
writeObject (ObjectOutputStream): void 0%   (0/1)0%   (0/10)0%   (0/3)
LocalTime$Property (LocalTime, DateTimeField): void 100% (1/1)100% (9/9)100% (4/4)
addCopy (int): LocalTime 100% (1/1)100% (11/11)100% (1/1)
addNoWrapToCopy (int): LocalTime 100% (1/1)100% (30/30)100% (5/5)
addWrapFieldToCopy (int): LocalTime 100% (1/1)100% (11/11)100% (1/1)
getChronology (): Chronology 100% (1/1)100% (4/4)100% (1/1)
getField (): DateTimeField 100% (1/1)100% (3/3)100% (1/1)
getLocalTime (): LocalTime 100% (1/1)100% (3/3)100% (1/1)
getMillis (): long 100% (1/1)100% (4/4)100% (1/1)
roundCeilingCopy (): LocalTime 100% (1/1)100% (10/10)100% (1/1)
roundFloorCopy (): LocalTime 100% (1/1)100% (10/10)100% (1/1)
roundHalfCeilingCopy (): LocalTime 100% (1/1)100% (10/10)100% (1/1)
roundHalfEvenCopy (): LocalTime 100% (1/1)100% (10/10)100% (1/1)
roundHalfFloorCopy (): LocalTime 100% (1/1)100% (10/10)100% (1/1)
setCopy (String): LocalTime 100% (1/1)100% (5/5)100% (1/1)
setCopy (String, Locale): LocalTime 100% (1/1)100% (12/12)100% (1/1)
setCopy (int): LocalTime 100% (1/1)100% (11/11)100% (1/1)
withMaximumValue (): LocalTime 100% (1/1)100% (5/5)100% (1/1)
withMinimumValue (): LocalTime 100% (1/1)100% (5/5)100% (1/1)
     
class LocalTime100% (1/1)98%  (63/64)99%  (965/979)98%  (193.9/197)
withFields (ReadablePartial): LocalTime 0%   (0/1)0%   (0/13)0%   (0/3)
equals (Object): boolean 100% (1/1)97%  (30/31)99%  (6.9/7)
<static initializer> 100% (1/1)100% (29/29)100% (7/7)
LocalTime (): void 100% (1/1)100% (5/5)100% (2/2)
LocalTime (Chronology): void 100% (1/1)100% (5/5)100% (2/2)
LocalTime (DateTimeZone): void 100% (1/1)100% (6/6)100% (2/2)
LocalTime (Object): void 100% (1/1)100% (6/6)100% (2/2)
LocalTime (Object, Chronology): void 100% (1/1)100% (44/44)100% (8/8)
LocalTime (Object, DateTimeZone): void 100% (1/1)100% (44/44)100% (8/8)
LocalTime (int, int): void 100% (1/1)100% (8/8)100% (2/2)
LocalTime (int, int, int): void 100% (1/1)100% (8/8)100% (2/2)
LocalTime (int, int, int, int): void 100% (1/1)100% (8/8)100% (2/2)
LocalTime (int, int, int, int, Chronology): void 100% (1/1)100% (21/21)100% (6/6)
LocalTime (long): void 100% (1/1)100% (5/5)100% (2/2)
LocalTime (long, Chronology): void 100% (1/1)100% (25/25)100% (7/7)
LocalTime (long, DateTimeZone): void 100% (1/1)100% (6/6)100% (2/2)
compareTo (Object): int 100% (1/1)100% (39/39)100% (7/7)
fromCalendarFields (Calendar): LocalTime 100% (1/1)100% (23/23)100% (3/3)
fromDateFields (Date): LocalTime 100% (1/1)100% (22/22)100% (3/3)
fromMillisOfDay (long): LocalTime 100% (1/1)100% (4/4)100% (1/1)
fromMillisOfDay (long, Chronology): LocalTime 100% (1/1)100% (10/10)100% (2/2)
get (DateTimeFieldType): int 100% (1/1)100% (33/33)100% (5/5)
getChronology (): Chronology 100% (1/1)100% (3/3)100% (1/1)
getField (int, Chronology): DateTimeField 100% (1/1)100% (26/26)100% (6/6)
getHourOfDay (): int 100% (1/1)100% (7/7)100% (1/1)
getLocalMillis (): long 100% (1/1)100% (3/3)100% (1/1)
getMillisOfDay (): int 100% (1/1)100% (7/7)100% (1/1)
getMillisOfSecond (): int 100% (1/1)100% (7/7)100% (1/1)
getMinuteOfHour (): int 100% (1/1)100% (7/7)100% (1/1)
getSecondOfMinute (): int 100% (1/1)100% (7/7)100% (1/1)
getValue (int): int 100% (1/1)100% (42/42)100% (6/6)
hourOfDay (): LocalTime$Property 100% (1/1)100% (8/8)100% (1/1)
isSupported (DateTimeFieldType): boolean 100% (1/1)100% (25/25)100% (6/6)
isSupported (DurationFieldType): boolean 100% (1/1)100% (26/26)100% (6/6)
millisOfDay (): LocalTime$Property 100% (1/1)100% (8/8)100% (1/1)
millisOfSecond (): LocalTime$Property 100% (1/1)100% (8/8)100% (1/1)
minus (ReadablePeriod): LocalTime 100% (1/1)100% (5/5)100% (1/1)
minusHours (int): LocalTime 100% (1/1)100% (16/16)100% (4/4)
minusMillis (int): LocalTime 100% (1/1)100% (16/16)100% (4/4)
minusMinutes (int): LocalTime 100% (1/1)100% (16/16)100% (4/4)
minusSeconds (int): LocalTime 100% (1/1)100% (16/16)100% (4/4)
minuteOfHour (): LocalTime$Property 100% (1/1)100% (8/8)100% (1/1)
plus (ReadablePeriod): LocalTime 100% (1/1)100% (5/5)100% (1/1)
plusHours (int): LocalTime 100% (1/1)100% (16/16)100% (4/4)
plusMillis (int): LocalTime 100% (1/1)100% (16/16)100% (4/4)
plusMinutes (int): LocalTime 100% (1/1)100% (16/16)100% (4/4)
plusSeconds (int): LocalTime 100% (1/1)100% (16/16)100% (4/4)
property (DateTimeFieldType): LocalTime$Property 100% (1/1)100% (34/34)100% (5/5)
secondOfMinute (): LocalTime$Property 100% (1/1)100% (8/8)100% (1/1)
size (): int 100% (1/1)100% (2/2)100% (1/1)
toDateTimeToday (): DateTime 100% (1/1)100% (4/4)100% (1/1)
toDateTimeToday (DateTimeZone): DateTime 100% (1/1)100% (18/18)100% (4/4)
toString (): String 100% (1/1)100% (4/4)100% (1/1)
toString (String): String 100% (1/1)100% (10/10)100% (3/3)
toString (String, Locale): String 100% (1/1)100% (12/12)100% (3/3)
withField (DateTimeFieldType, int): LocalTime 100% (1/1)100% (38/38)100% (6/6)
withFieldAdded (DurationFieldType, int): LocalTime 100% (1/1)100% (42/42)100% (8/8)
withHourOfDay (int): LocalTime 100% (1/1)100% (10/10)100% (1/1)
withLocalMillis (long): LocalTime 100% (1/1)100% (14/14)100% (1/1)
withMillisOfDay (int): LocalTime 100% (1/1)100% (10/10)100% (1/1)
withMillisOfSecond (int): LocalTime 100% (1/1)100% (10/10)100% (1/1)
withMinuteOfHour (int): LocalTime 100% (1/1)100% (10/10)100% (1/1)
withPeriodAdded (ReadablePeriod, int): LocalTime 100% (1/1)100% (18/18)100% (4/4)
withSecondOfMinute (int): LocalTime 100% (1/1)100% (10/10)100% (1/1)

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

[all classes][org.joda.time]
EMMA 2.0.5312 (C) Vladimir Roubtsov