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

COVERAGE SUMMARY FOR SOURCE FILE [DateTimeFormatter.java]

nameclass, %method, %block, %line, %
DateTimeFormatter.java100% (1/1)100% (35/35)96%  (696/722)96%  (156.6/163)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class DateTimeFormatter100% (1/1)100% (35/35)96%  (696/722)96%  (156.6/163)
printTo (StringBuffer, long, Chronology): void 100% (1/1)73%  (36/49)71%  (7.8/11)
printTo (Writer, long, Chronology): void 100% (1/1)73%  (36/49)71%  (7.8/11)
DateTimeFormatter (DateTimePrinter, DateTimeParser): void 100% (1/1)100% (24/24)100% (9/9)
DateTimeFormatter (DateTimePrinter, DateTimeParser, Locale, boolean, Chronolo... 100% (1/1)100% (24/24)100% (9/9)
getChronolgy (): Chronology 100% (1/1)100% (3/3)100% (1/1)
getLocale (): Locale 100% (1/1)100% (3/3)100% (1/1)
getParser (): DateTimeParser 100% (1/1)100% (3/3)100% (1/1)
getPivotYear (): Integer 100% (1/1)100% (3/3)100% (1/1)
getPrinter (): DateTimePrinter 100% (1/1)100% (3/3)100% (1/1)
getZone (): DateTimeZone 100% (1/1)100% (3/3)100% (1/1)
isOffsetParsed (): boolean 100% (1/1)100% (3/3)100% (1/1)
isParser (): boolean 100% (1/1)100% (7/7)100% (1/1)
isPrinter (): boolean 100% (1/1)100% (7/7)100% (1/1)
parseDateTime (String): DateTime 100% (1/1)100% (67/67)100% (14/14)
parseInto (ReadWritableInstant, String, int): int 100% (1/1)100% (71/71)100% (16/16)
parseMillis (String): long 100% (1/1)100% (46/46)100% (9/9)
parseMutableDateTime (String): MutableDateTime 100% (1/1)100% (67/67)100% (14/14)
print (ReadableInstant): String 100% (1/1)100% (14/14)100% (3/3)
print (ReadablePartial): String 100% (1/1)100% (14/14)100% (3/3)
print (long): String 100% (1/1)100% (14/14)100% (3/3)
printTo (StringBuffer, ReadableInstant): void 100% (1/1)100% (12/12)100% (4/4)
printTo (StringBuffer, ReadablePartial): void 100% (1/1)100% (17/17)100% (5/5)
printTo (StringBuffer, long): void 100% (1/1)100% (6/6)100% (2/2)
printTo (Writer, ReadableInstant): void 100% (1/1)100% (12/12)100% (4/4)
printTo (Writer, ReadablePartial): void 100% (1/1)100% (17/17)100% (5/5)
printTo (Writer, long): void 100% (1/1)100% (6/6)100% (2/2)
requireParser (): DateTimeParser 100% (1/1)100% (12/12)100% (4/4)
requirePrinter (): DateTimePrinter 100% (1/1)100% (12/12)100% (4/4)
selectChronology (Chronology): Chronology 100% (1/1)100% (19/19)100% (6/6)
withChronology (Chronology): DateTimeFormatter 100% (1/1)100% (23/23)100% (3/3)
withLocale (Locale): DateTimeFormatter 100% (1/1)100% (30/30)100% (3/3)
withOffsetParsed (): DateTimeFormatter 100% (1/1)100% (22/22)100% (3/3)
withPivotYear (Integer): DateTimeFormatter 100% (1/1)100% (31/31)100% (3/3)
withPivotYear (int): DateTimeFormatter 100% (1/1)100% (7/7)100% (1/1)
withZone (DateTimeZone): DateTimeFormatter 100% (1/1)100% (22/22)100% (3/3)

1/*
2 *  Copyright 2001-2005 Stephen Colebourne
3 *
4 *  Licensed under the Apache License, Version 2.0 (the "License");
5 *  you may not use this file except in compliance with the License.
6 *  You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 *  Unless required by applicable law or agreed to in writing, software
11 *  distributed under the License is distributed on an "AS IS" BASIS,
12 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 *  See the License for the specific language governing permissions and
14 *  limitations under the License.
15 */
16package org.joda.time.format;
17 
18import java.io.IOException;
19import java.io.Writer;
20import java.util.Locale;
21 
22import org.joda.time.Chronology;
23import org.joda.time.DateTime;
24import org.joda.time.DateTimeUtils;
25import org.joda.time.DateTimeZone;
26import org.joda.time.MutableDateTime;
27import org.joda.time.ReadWritableInstant;
28import org.joda.time.ReadableInstant;
29import org.joda.time.ReadablePartial;
30 
31/**
32 * Controls the printing and parsing of a datetime to and from a string.
33 * <p>
34 * This class is the main API for printing and parsing used by most applications.
35 * Instances of this class are created via one of three factory classes:
36 * <ul>
37 * <li>{@link DateTimeFormat} - formats by pattern and style</li>
38 * <li>{@link ISODateTimeFormat} - ISO8601 formats</li>
39 * <li>{@link DateTimeFormatterBuilder} - complex formats created via method calls</li>
40 * </ul>
41 * <p>
42 * An instance of this class holds a reference internally to one printer and
43 * one parser. It is possible that one of these may be null, in which case the
44 * formatter cannot print/parse. This can be checked via the {@link #isPrinter()}
45 * and {@link #isParser()} methods.
46 * <p>
47 * The underlying printer/parser can be altered to behave exactly as required
48 * by using one of the decorator modifiers:
49 * <ul>
50 * <li>{@link #withLocale(Locale)} - returns a new formatter that uses the specified locale</li>
51 * <li>{@link #withZone(DateTimeZone)} - returns a new formatter that uses the specified time zone</li>
52 * <li>{@link #withChronology(Chronology)} - returns a new formatter that uses the specified chronology</li>
53 * <li>{@link #withOffsetParsed()} - returns a new formatter that returns the parsed time zone offset</li>
54 * </ul>
55 * Each of these returns a new formatter (instances of this class are immutable).
56 * <p>
57 * The main methods of the class are the <code>printXxx</code> and
58 * <code>parseXxx</code> methods. These are used as follows:
59 * <pre>
60 * // print using the defaults (default locale, chronology/zone of the datetime)
61 * String dateStr = formatter.print(dt);
62 * // print using the French locale
63 * String dateStr = formatter.withLocale(Locale.FRENCH).print(dt);
64 * // print using the UTC zone
65 * String dateStr = formatter.withZone(DateTimeZone.UTC).print(dt);
66 * 
67 * // parse using the Paris zone
68 * DateTime date = formatter.withZone(DateTimeZone.forID("Europe/Paris")).parseDateTime(str);
69 * </pre>
70 * 
71 * @author Brian S O'Neill
72 * @author Stephen Colebourne
73 * @author Fredrik Borgh
74 * @since 1.0
75 */
76public class DateTimeFormatter {
77 
78    /** The internal printer used to output the datetime. */
79    private final DateTimePrinter iPrinter;
80    /** The internal parser used to output the datetime. */
81    private final DateTimeParser iParser;
82    /** The locale to use for printing and parsing. */
83    private final Locale iLocale;
84    /** Whether the offset is parsed. */
85    private final boolean iOffsetParsed;
86    /** The chronology to use as an override. */
87    private final Chronology iChrono;
88    /** The zone to use as an override. */
89    private final DateTimeZone iZone;
90    /* The pivot year to use for two-digit year parsing. */
91    private final Integer iPivotYear;
92 
93    /**
94     * Creates a new formatter, however you will normally use the factory
95     * or the builder.
96     * 
97     * @param printer  the internal printer, null if cannot print
98     * @param parser  the internal parser, null if cannot parse
99     */
100    public DateTimeFormatter(
101            DateTimePrinter printer, DateTimeParser parser) {
102        super();
103        iPrinter = printer;
104        iParser = parser;
105        iLocale = null;
106        iOffsetParsed = false;
107        iChrono = null;
108        iZone = null;
109        iPivotYear = null;
110    }
111 
112    /**
113     * Constructor.
114     */
115    private DateTimeFormatter(
116            DateTimePrinter printer, DateTimeParser parser,
117            Locale locale, boolean offsetParsed,
118            Chronology chrono, DateTimeZone zone,
119            Integer pivotYear) {
120        super();
121        iPrinter = printer;
122        iParser = parser;
123        iLocale = locale;
124        iOffsetParsed = offsetParsed;
125        iChrono = chrono;
126        iZone = zone;
127        iPivotYear = pivotYear;
128    }
129 
130    //-----------------------------------------------------------------------
131    /**
132     * Is this formatter capable of printing.
133     * 
134     * @return true if this is a printer
135     */
136    public boolean isPrinter() {
137        return (iPrinter != null);
138    }
139 
140    /**
141     * Gets the internal printer object that performs the real printing work.
142     * 
143     * @return the internal printer; is null if printing not supported
144     */
145    public DateTimePrinter getPrinter() {
146        return iPrinter;
147    }
148 
149    /**
150     * Is this formatter capable of parsing.
151     * 
152     * @return true if this is a parser
153     */
154    public boolean isParser() {
155        return (iParser != null);
156    }
157 
158    /**
159     * Gets the internal parser object that performs the real parsing work.
160     * 
161     * @return the internal parser; is null if parsing not supported
162     */
163    public DateTimeParser getParser() {
164        return iParser;
165    }
166 
167    //-----------------------------------------------------------------------
168    /**
169     * Returns a new formatter with a different locale that will be used
170     * for printing and parsing.
171     * <p>
172     * A DateTimeFormatter is immutable, so a new instance is returned,
173     * and the original is unaltered and still usable.
174     * 
175     * @param locale the locale to use; if null, formatter uses default locale
176     * at invocation time
177     * @return the new formatter
178     */
179    public DateTimeFormatter withLocale(Locale locale) {
180        if (locale == getLocale() || (locale != null && locale.equals(getLocale()))) {
181            return this;
182        }
183        return new DateTimeFormatter(iPrinter, iParser, locale,
184                iOffsetParsed, iChrono, iZone, iPivotYear);
185    }
186 
187    /**
188     * Gets the locale that will be used for printing and parsing.
189     * 
190     * @return the locale to use; if null, formatter uses default locale at
191     * invocation time
192     */
193    public Locale getLocale() {
194        return iLocale;
195    }
196 
197    //-----------------------------------------------------------------------
198    /**
199     * Returns a new formatter that will create a datetime with a time zone
200     * equal to that of the offset of the parsed string.
201     * <p>
202     * After calling this method, a string '2004-06-09T10:20:30-08:00' will
203     * create a datetime with a zone of -08:00 (a fixed zone, with no daylight
204     * savings rules). If the parsed string represents a local time (no zone
205     * offset) the parsed datetime will be in the default zone.
206     * <p>
207     * Calling this method sets the override zone to null.
208     * Calling the override zone method sets this flag off.
209     * 
210     * @return the new formatter
211     */
212    public DateTimeFormatter withOffsetParsed() {
213        if (iOffsetParsed == true) {
214            return this;
215        }
216        return new DateTimeFormatter(iPrinter, iParser, iLocale,
217                true, iChrono, null, iPivotYear);
218    }
219 
220    /**
221     * Checks whether the offset from the string is used as the zone of
222     * the parsed datetime.
223     * 
224     * @return true if the offset from the string is used as the zone
225     */
226    public boolean isOffsetParsed() {
227        return iOffsetParsed;
228    }
229 
230    //-----------------------------------------------------------------------
231    /**
232     * Returns a new formatter that will use the specified chronology in
233     * preference to that of the printed object, or ISO on a parse.
234     * <p>
235     * When printing, this chronolgy will be used in preference to the chronology
236     * from the datetime that would otherwise be used.
237     * <p>
238     * When parsing, this chronology will be set on the parsed datetime.
239     * <p>
240     * A null chronology means no-override.
241     * If both an override chronology and an override zone are set, the
242     * override zone will take precedence over the zone in the chronology.
243     * 
244     * @param chrono  the chronology to use as an override
245     * @return the new formatter
246     */
247    public DateTimeFormatter withChronology(Chronology chrono) {
248        if (iChrono == chrono) {
249            return this;
250        }
251        return new DateTimeFormatter(iPrinter, iParser, iLocale,
252                iOffsetParsed, chrono, iZone, iPivotYear);
253    }
254 
255    /**
256     * Gets the chronology to use as an override.
257     * 
258     * @return the chronology to use as an override
259     */
260    public Chronology getChronolgy() {
261        return iChrono;
262    }
263 
264    //-----------------------------------------------------------------------
265    /**
266     * Returns a new formatter that will use the specified zone in preference
267     * to the zone of the printed object, or default zone on a parse.
268     * <p>
269     * When printing, this zone will be used in preference to the zone
270     * from the datetime that would otherwise be used.
271     * <p>
272     * When parsing, this zone will be set on the parsed datetime.
273     * <p>
274     * A null zone means of no-override.
275     * If both an override chronology and an override zone are set, the
276     * override zone will take precedence over the zone in the chronology.
277     * 
278     * @param zone  the zone to use as an override
279     * @return the new formatter
280     */
281    public DateTimeFormatter withZone(DateTimeZone zone) {
282        if (iZone == zone) {
283            return this;
284        }
285        return new DateTimeFormatter(iPrinter, iParser, iLocale,
286                false, iChrono, zone, iPivotYear);
287    }
288 
289    /**
290     * Gets the zone to use as an override.
291     * 
292     * @return the zone to use as an override
293     */
294    public DateTimeZone getZone() {
295        return iZone;
296    }
297 
298    //-----------------------------------------------------------------------
299    /**
300     * Returns a new formatter that will use the specified pivot year for two
301     * digit year parsing in preference to that stored in the parser.
302     * <p>
303     * This setting is useful for changing the pivot year of formats built
304     * using a pattern - {@link DateTimeFormat#forPattern(String)}.
305     * <p>
306     * When parsing, this pivot year is used. Null means no-override.
307     * There is no effect when printing.
308     * <p>
309     * The pivot year enables a two digit year to be converted to a four
310     * digit year. The pivot represents the year in the middle of the
311     * supported range of years. Thus the full range of years that will
312     * be built is <code>(pivot - 50) .. (pivot + 49)</code>.
313     *
314     * <pre>
315     * pivot   supported range   00 is   20 is   40 is   60 is   80 is
316     * ---------------------------------------------------------------
317     * 1950      1900..1999      1900    1920    1940    1960    1980
318     * 1975      1925..2024      2000    2020    1940    1960    1980
319     * 2000      1950..2049      2000    2020    2040    1960    1980
320     * 2025      1975..2074      2000    2020    2040    2060    1980
321     * 2050      2000..2099      2000    2020    2040    2060    2080
322     * </pre>
323     *
324     * @param pivotYear  the pivot year to use as an override when parsing
325     * @return the new formatter
326     * @since 1.1
327     */
328    public DateTimeFormatter withPivotYear(Integer pivotYear) {
329        if (iPivotYear == pivotYear || (iPivotYear != null && iPivotYear.equals(pivotYear))) {
330            return this;
331        }
332        return new DateTimeFormatter(iPrinter, iParser, iLocale,
333                iOffsetParsed, iChrono, iZone, pivotYear);
334    }
335 
336    /**
337     * Returns a new formatter that will use the specified pivot year for two
338     * digit year parsing in preference to that stored in the parser.
339     * <p>
340     * This setting is useful for changing the pivot year of formats built
341     * using a pattern - {@link DateTimeFormat#forPattern(String)}.
342     * <p>
343     * When parsing, this pivot year is used.
344     * There is no effect when printing.
345     * <p>
346     * The pivot year enables a two digit year to be converted to a four
347     * digit year. The pivot represents the year in the middle of the
348     * supported range of years. Thus the full range of years that will
349     * be built is <code>(pivot - 50) .. (pivot + 49)</code>.
350     *
351     * <pre>
352     * pivot   supported range   00 is   20 is   40 is   60 is   80 is
353     * ---------------------------------------------------------------
354     * 1950      1900..1999      1900    1920    1940    1960    1980
355     * 1975      1925..2024      2000    2020    1940    1960    1980
356     * 2000      1950..2049      2000    2020    2040    1960    1980
357     * 2025      1975..2074      2000    2020    2040    2060    1980
358     * 2050      2000..2099      2000    2020    2040    2060    2080
359     * </pre>
360     *
361     * @param pivotYear  the pivot year to use as an override when parsing
362     * @return the new formatter
363     * @since 1.1
364     */
365    public DateTimeFormatter withPivotYear(int pivotYear) {
366        return withPivotYear(new Integer(pivotYear));
367    }
368 
369    /**
370     * Gets the pivot year to use as an override.
371     *
372     * @return the pivot year to use as an override
373     * @since 1.1
374     */
375    public Integer getPivotYear() {
376      return iPivotYear;
377    }
378 
379    //-----------------------------------------------------------------------
380    /**
381     * Prints a ReadableInstant, using the chronology supplied by the instant.
382     *
383     * @param buf  formatted instant is appended to this buffer
384     * @param instant  instant to format, null means now
385     */
386    public void printTo(StringBuffer buf, ReadableInstant instant) {
387        long millis = DateTimeUtils.getInstantMillis(instant);
388        Chronology chrono = DateTimeUtils.getInstantChronology(instant);
389        printTo(buf, millis, chrono);
390    }
391 
392    /**
393     * Prints a ReadableInstant, using the chronology supplied by the instant.
394     *
395     * @param out  formatted instant is written out
396     * @param instant  instant to format, null means now
397     */
398    public void printTo(Writer out, ReadableInstant instant) throws IOException {
399        long millis = DateTimeUtils.getInstantMillis(instant);
400        Chronology chrono = DateTimeUtils.getInstantChronology(instant);
401        printTo(out, millis, chrono);
402    }
403 
404    //-----------------------------------------------------------------------
405    /**
406     * Prints an instant from milliseconds since 1970-01-01T00:00:00Z,
407     * using ISO chronology in the default DateTimeZone.
408     *
409     * @param buf  formatted instant is appended to this buffer
410     * @param instant  millis since 1970-01-01T00:00:00Z
411     */
412    public void printTo(StringBuffer buf, long instant) {
413        printTo(buf, instant, null);
414    }
415 
416    /**
417     * Prints an instant from milliseconds since 1970-01-01T00:00:00Z,
418     * using ISO chronology in the default DateTimeZone.
419     *
420     * @param out  formatted instant is written out
421     * @param instant  millis since 1970-01-01T00:00:00Z
422     */
423    public void printTo(Writer out, long instant) throws IOException {
424        printTo(out, instant, null);
425    }
426 
427    //-----------------------------------------------------------------------
428    /**
429     * Prints a ReadablePartial.
430     * <p>
431     * Neither the override chronology nor the override zone are used
432     * by this method.
433     *
434     * @param buf  formatted partial is appended to this buffer
435     * @param partial  partial to format
436     */
437    public void printTo(StringBuffer buf, ReadablePartial partial) {
438        DateTimePrinter printer = requirePrinter();
439        if (partial == null) {
440            throw new IllegalArgumentException("The partial must not be null");
441        }
442        printer.printTo(buf, partial, iLocale);
443    }
444 
445    /**
446     * Prints a ReadablePartial.
447     * <p>
448     * Neither the override chronology nor the override zone are used
449     * by this method.
450     *
451     * @param out  formatted partial is written out
452     * @param partial  partial to format
453     */
454    public void printTo(Writer out, ReadablePartial partial) throws IOException {
455        DateTimePrinter printer = requirePrinter();
456        if (partial == null) {
457            throw new IllegalArgumentException("The partial must not be null");
458        }
459        printer.printTo(out, partial, iLocale);
460    }
461 
462    //-----------------------------------------------------------------------
463    /**
464     * Prints a ReadableInstant to a String.
465     * <p>
466     * This method will use the override zone and the override chronololgy if
467     * they are set. Otherwise it will use the chronology and zone of the instant.
468     *
469     * @param instant  instant to format, null means now
470     * @return the printed result
471     */
472    public String print(ReadableInstant instant) {
473        StringBuffer buf = new StringBuffer(requirePrinter().estimatePrintedLength());
474        printTo(buf, instant);
475        return buf.toString();
476    }
477 
478    /**
479     * Prints a millisecond instant to a String.
480     * <p>
481     * This method will use the override zone and the override chronololgy if
482     * they are set. Otherwise it will use the ISO chronology and default zone.
483     *
484     * @param instant  millis since 1970-01-01T00:00:00Z
485     * @return the printed result
486     */
487    public String print(long instant) {
488        StringBuffer buf = new StringBuffer(requirePrinter().estimatePrintedLength());
489        printTo(buf, instant);
490        return buf.toString();
491    }
492 
493    /**
494     * Prints a ReadablePartial to a new String.
495     * <p>
496     * Neither the override chronology nor the override zone are used
497     * by this method.
498     *
499     * @param partial  partial to format
500     * @return the printed result
501     */
502    public String print(ReadablePartial partial) {
503        StringBuffer buf = new StringBuffer(requirePrinter().estimatePrintedLength());
504        printTo(buf, partial);
505        return buf.toString();
506    }
507 
508    private void printTo(StringBuffer buf, long instant, Chronology chrono) {
509        DateTimePrinter printer = requirePrinter();
510        chrono = selectChronology(chrono);
511        // Shift instant into local time (UTC) to avoid excessive offset
512        // calculations when printing multiple fields in a composite printer.
513        DateTimeZone zone = chrono.getZone();
514        int offset = zone.getOffset(instant);
515        long adjustedInstant = instant + offset;
516        if ((instant ^ adjustedInstant) < 0 && (instant ^ offset) >= 0) {
517            // Time zone offset overflow, so revert to UTC.
518            zone = DateTimeZone.UTC;
519            offset = 0;
520            adjustedInstant = instant;
521        }
522        printer.printTo(buf, adjustedInstant, chrono.withUTC(), offset, zone, iLocale);
523    }
524 
525    private void printTo(Writer buf, long instant, Chronology chrono) throws IOException {
526        DateTimePrinter printer = requirePrinter();
527        chrono = selectChronology(chrono);
528        // Shift instant into local time (UTC) to avoid excessive offset
529        // calculations when printing multiple fields in a composite printer.
530        DateTimeZone zone = chrono.getZone();
531        int offset = zone.getOffset(instant);
532        long adjustedInstant = instant + offset;
533        if ((instant ^ adjustedInstant) < 0 && (instant ^ offset) >= 0) {
534            // Time zone offset overflow, so revert to UTC.
535            zone = DateTimeZone.UTC;
536            offset = 0;
537            adjustedInstant = instant;
538        }
539        printer.printTo(buf, adjustedInstant, chrono.withUTC(), offset, zone, iLocale);
540    }
541 
542    /**
543     * Checks whether printing is supported.
544     * 
545     * @throws UnsupportedOperationException if printing is not supported
546     */
547    private DateTimePrinter requirePrinter() {
548        DateTimePrinter printer = iPrinter;
549        if (printer == null) {
550            throw new UnsupportedOperationException("Printing not supported");
551        }
552        return printer;
553    }
554 
555    //-----------------------------------------------------------------------
556    /**
557     * Parses a datetime from the given text, at the given position, saving the
558     * result into the fields of the given ReadWritableInstant. If the parse
559     * succeeds, the return value is the new text position. Note that the parse
560     * may succeed without fully reading the text and in this case those fields
561     * that were read will be set.
562     * <p>
563     * Only those fields present in the string will be changed in the specified
564     * instant. All other fields will remain unaltered. Thus if the string only
565     * contains a year and a month, then the day and time will be retained from
566     * the input instant. If this is not the behaviour you want, then reset the
567     * fields before calling this method, or use {@link #parseDateTime(String)}
568     * or {@link #parseMutableDateTime(String)}.
569     * <p>
570     * If it fails, the return value is negative, but the instant may still be
571     * modified. To determine the position where the parse failed, apply the
572     * one's complement operator (~) on the return value.
573     * <p>
574     * The parse will use the chronology of the instant.
575     *
576     * @param instant  an instant that will be modified, not null
577     * @param text  the text to parse
578     * @param position  position to start parsing from
579     * @return new position, negative value means parse failed -
580     *  apply complement operator (~) to get position of failure
581     * @throws UnsupportedOperationException if parsing is not supported
582     * @throws IllegalArgumentException if the instant is null
583     * @throws IllegalArgumentException if any field is out of range
584     */
585    public int parseInto(ReadWritableInstant instant, String text, int position) {
586        DateTimeParser parser = requireParser();
587        if (instant == null) {
588            throw new IllegalArgumentException("Instant must not be null");
589        }
590        
591        long instantMillis = instant.getMillis();
592        Chronology chrono = instant.getChronology();
593        long instantLocal = instantMillis + chrono.getZone().getOffset(instantMillis);
594        chrono = selectChronology(chrono);
595        
596        DateTimeParserBucket bucket = new DateTimeParserBucket
597            (instantLocal, chrono, iLocale, iPivotYear);
598        int newPos = parser.parseInto(bucket, text, position);
599        instant.setMillis(bucket.computeMillis(false, text));
600        if (iOffsetParsed && bucket.getZone() == null) {
601            int parsedOffset = bucket.getOffset();
602            DateTimeZone parsedZone = DateTimeZone.forOffsetMillis(parsedOffset);
603            chrono = chrono.withZone(parsedZone);
604        }
605        instant.setChronology(chrono);
606        return newPos;
607    }
608 
609    /**
610     * Parses a datetime from the given text, returning the number of
611     * milliseconds since the epoch, 1970-01-01T00:00:00Z.
612     * <p>
613     * The parse will use the ISO chronology, and the default time zone.
614     * If the text contains a time zone string then that will be taken into account.
615     *
616     * @param text  text to parse
617     * @return parsed value expressed in milliseconds since the epoch
618     * @throws UnsupportedOperationException if parsing is not supported
619     * @throws IllegalArgumentException if the text to parse is invalid
620     */
621    public long parseMillis(String text) {
622        DateTimeParser parser = requireParser();
623        
624        Chronology chrono = selectChronology(iChrono);
625        DateTimeParserBucket bucket = new DateTimeParserBucket(0, chrono, iLocale, iPivotYear);
626        int newPos = parser.parseInto(bucket, text, 0);
627        if (newPos >= 0) {
628            if (newPos >= text.length()) {
629                return bucket.computeMillis(true, text);
630            }
631        } else {
632            newPos = ~newPos;
633        }
634        throw new IllegalArgumentException(FormatUtils.createErrorMessage(text, newPos));
635    }
636 
637    /**
638     * Parses a datetime from the given text, returning a new DateTime.
639     * <p>
640     * The parse will use the zone and chronology specified on this formatter.
641     * <p>
642     * If the text contains a time zone string then that will be taken into
643     * account in adjusting the time of day as follows.
644     * If the {@link #withOffsetParsed()} has been called, then the resulting
645     * DateTime will have a fixed offset based on the parsed time zone.
646     * Otherwise the resulting DateTime will have the zone of this formatter,
647     * but the parsed zone may have caused the time to be adjusted.
648     *
649     * @param text  the text to parse
650     * @return parsed value in a DateTime object
651     * @throws UnsupportedOperationException if parsing is not supported
652     * @throws IllegalArgumentException if the text to parse is invalid
653     */
654    public DateTime parseDateTime(String text) {
655        DateTimeParser parser = requireParser();
656        
657        Chronology chrono = selectChronology(null);
658        DateTimeParserBucket bucket = new DateTimeParserBucket(0, chrono, iLocale, iPivotYear);
659        int newPos = parser.parseInto(bucket, text, 0);
660        if (newPos >= 0) {
661            if (newPos >= text.length()) {
662                long millis = bucket.computeMillis(true, text);
663                if (iOffsetParsed && bucket.getZone() == null) {
664                    int parsedOffset = bucket.getOffset();
665                    DateTimeZone parsedZone = DateTimeZone.forOffsetMillis(parsedOffset);
666                    chrono = chrono.withZone(parsedZone);
667                }
668                return new DateTime(millis, chrono);
669            }
670        } else {
671            newPos = ~newPos;
672        }
673        throw new IllegalArgumentException(FormatUtils.createErrorMessage(text, newPos));
674    }
675 
676    /**
677     * Parses a datetime from the given text, returning a new MutableDateTime.
678     * <p>
679     * The parse will use the zone and chronology specified on this formatter.
680     * <p>
681     * If the text contains a time zone string then that will be taken into
682     * account in adjusting the time of day as follows.
683     * If the {@link #withOffsetParsed()} has been called, then the resulting
684     * DateTime will have a fixed offset based on the parsed time zone.
685     * Otherwise the resulting DateTime will have the zone of this formatter,
686     * but the parsed zone may have caused the time to be adjusted.
687     *
688     * @param text  the text to parse
689     * @return parsed value in a MutableDateTime object
690     * @throws UnsupportedOperationException if parsing is not supported
691     * @throws IllegalArgumentException if the text to parse is invalid
692     */
693    public MutableDateTime parseMutableDateTime(String text) {
694        DateTimeParser parser = requireParser();
695        
696        Chronology chrono = selectChronology(null);
697        DateTimeParserBucket bucket = new DateTimeParserBucket(0, chrono, iLocale, iPivotYear);
698        int newPos = parser.parseInto(bucket, text, 0);
699        if (newPos >= 0) {
700            if (newPos >= text.length()) {
701                long millis = bucket.computeMillis(true, text);
702                if (iOffsetParsed && bucket.getZone() == null) {
703                    int parsedOffset = bucket.getOffset();
704                    DateTimeZone parsedZone = DateTimeZone.forOffsetMillis(parsedOffset);
705                    chrono = chrono.withZone(parsedZone);
706                }
707                return new MutableDateTime(millis, chrono);
708            }
709        } else {
710            newPos = ~newPos;
711        }
712        throw new IllegalArgumentException(FormatUtils.createErrorMessage(text, newPos));
713    }
714 
715    /**
716     * Checks whether parsing is supported.
717     * 
718     * @throws UnsupportedOperationException if parsing is not supported
719     */
720    private DateTimeParser requireParser() {
721        DateTimeParser parser = iParser;
722        if (parser == null) {
723            throw new UnsupportedOperationException("Parsing not supported");
724        }
725        return parser;
726    }
727 
728    //-----------------------------------------------------------------------
729    /**
730     * Determines the correct chronology to use.
731     *
732     * @param chrono  the proposed chronology
733     * @return the actual chronology
734     */
735    private Chronology selectChronology(Chronology chrono) {
736        chrono = DateTimeUtils.getChronology(chrono);
737        if (iChrono != null) {
738            chrono = iChrono;
739        }
740        if (iZone != null) {
741            chrono = chrono.withZone(iZone);
742        }
743        return chrono;
744    }
745 
746}

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