/*
 *  Copyright 2001-2014 Stephen Colebourne
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.joda.time.format;

import java.io.IOException;
import java.io.Writer;
import java.util.Locale;

import org.joda.time.Chronology;
import org.joda.time.DateTime;
import org.joda.time.DateTimeUtils;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.joda.time.LocalTime;
import org.joda.time.MutableDateTime;
import org.joda.time.ReadWritableInstant;
import org.joda.time.ReadableInstant;
import org.joda.time.ReadablePartial;

Controls the printing and parsing of a datetime to and from a string.

This class is the main API for printing and parsing used by most applications. Instances of this class are created via one of three factory classes:

An instance of this class holds a reference internally to one printer and one parser. It is possible that one of these may be null, in which case the formatter cannot print/parse. This can be checked via the isPrinter() and isParser() methods.

The underlying printer/parser can be altered to behave exactly as required by using one of the decorator modifiers:

Each of these returns a new formatter (instances of this class are immutable).

The main methods of the class are the printXxx and parseXxx methods. These are used as follows:

// print using the defaults (default locale, chronology/zone of the datetime)
String dateStr = formatter.print(dt);
// print using the French locale
String dateStr = formatter.withLocale(Locale.FRENCH).print(dt);
// print using the UTC zone
String dateStr = formatter.withZone(DateTimeZone.UTC).print(dt);
// parse using the Paris zone
DateTime date = formatter.withZone(DateTimeZone.forID("Europe/Paris")).parseDateTime(str);

Parsing builds up the resultant instant by 'setting' the value of each parsed field from largest to smallest onto an initial instant, typically 1970-01-01T00:00Z. This design means that day-of-month is set before day-of-week. As such, if both the day-of-month and day-of-week are parsed, and the day-of-week is incorrect, then the day-of-week overrides the day-of-month. This has a side effect if the input is not consistent.

Author:Brian S O'Neill, Stephen Colebourne, Fredrik Borgh
Since:1.0
/** * Controls the printing and parsing of a datetime to and from a string. * <p> * This class is the main API for printing and parsing used by most applications. * Instances of this class are created via one of three factory classes: * <ul> * <li>{@link DateTimeFormat} - formats by pattern and style</li> * <li>{@link ISODateTimeFormat} - ISO8601 formats</li> * <li>{@link DateTimeFormatterBuilder} - complex formats created via method calls</li> * </ul> * <p> * An instance of this class holds a reference internally to one printer and * one parser. It is possible that one of these may be null, in which case the * formatter cannot print/parse. This can be checked via the {@link #isPrinter()} * and {@link #isParser()} methods. * <p> * The underlying printer/parser can be altered to behave exactly as required * by using one of the decorator modifiers: * <ul> * <li>{@link #withLocale(Locale)} - returns a new formatter that uses the specified locale</li> * <li>{@link #withZone(DateTimeZone)} - returns a new formatter that uses the specified time zone</li> * <li>{@link #withChronology(Chronology)} - returns a new formatter that uses the specified chronology</li> * <li>{@link #withOffsetParsed()} - returns a new formatter that returns the parsed time zone offset</li> * <li>{@link #withPivotYear(int)} - returns a new formatter with the specified pivot year</li> * <li>{@link #withDefaultYear(int)} - returns a new formatter with the specified default year</li> * </ul> * Each of these returns a new formatter (instances of this class are immutable). * <p> * The main methods of the class are the <code>printXxx</code> and * <code>parseXxx</code> methods. These are used as follows: * <pre> * // print using the defaults (default locale, chronology/zone of the datetime) * String dateStr = formatter.print(dt); * // print using the French locale * String dateStr = formatter.withLocale(Locale.FRENCH).print(dt); * // print using the UTC zone * String dateStr = formatter.withZone(DateTimeZone.UTC).print(dt); * * // parse using the Paris zone * DateTime date = formatter.withZone(DateTimeZone.forID("Europe/Paris")).parseDateTime(str); * </pre> * <p> * Parsing builds up the resultant instant by 'setting' the value of each parsed field * from largest to smallest onto an initial instant, typically 1970-01-01T00:00Z. * This design means that day-of-month is set before day-of-week. * As such, if both the day-of-month and day-of-week are parsed, and the day-of-week * is incorrect, then the day-of-week overrides the day-of-month. * * This has a side effect if the input is not consistent. * * * @author Brian S O'Neill * @author Stephen Colebourne * @author Fredrik Borgh * @since 1.0 */
public class DateTimeFormatter {
The internal printer used to output the datetime.
/** The internal printer used to output the datetime. */
private final InternalPrinter iPrinter;
The internal parser used to output the datetime.
/** The internal parser used to output the datetime. */
private final InternalParser iParser;
The locale to use for printing and parsing.
/** The locale to use for printing and parsing. */
private final Locale iLocale;
Whether the offset is parsed.
/** Whether the offset is parsed. */
private final boolean iOffsetParsed;
The chronology to use as an override.
/** The chronology to use as an override. */
private final Chronology iChrono;
The zone to use as an override.
/** The zone to use as an override. */
private final DateTimeZone iZone;
The pivot year to use for two-digit year parsing.
/** The pivot year to use for two-digit year parsing. */
private final Integer iPivotYear;
The default year for parsing month/day without year.
/** The default year for parsing month/day without year. */
private final int iDefaultYear;
Creates a new formatter, however you will normally use the factory or the builder.
Params:
  • printer – the internal printer, null if cannot print
  • parser – the internal parser, null if cannot parse
/** * Creates a new formatter, however you will normally use the factory * or the builder. * * @param printer the internal printer, null if cannot print * @param parser the internal parser, null if cannot parse */
public DateTimeFormatter( DateTimePrinter printer, DateTimeParser parser) { this(DateTimePrinterInternalPrinter.of(printer), DateTimeParserInternalParser.of(parser)); }
Creates a new formatter, however you will normally use the factory or the builder.
Params:
  • printer – the internal printer, null if cannot print
  • parser – the internal parser, null if cannot parse
/** * Creates a new formatter, however you will normally use the factory * or the builder. * * @param printer the internal printer, null if cannot print * @param parser the internal parser, null if cannot parse */
DateTimeFormatter( InternalPrinter printer, InternalParser parser) { super(); iPrinter = printer; iParser = parser; iLocale = null; iOffsetParsed = false; iChrono = null; iZone = null; iPivotYear = null; iDefaultYear = 2000; }
Constructor.
/** * Constructor. */
private DateTimeFormatter( InternalPrinter printer, InternalParser parser, Locale locale, boolean offsetParsed, Chronology chrono, DateTimeZone zone, Integer pivotYear, int defaultYear) { super(); iPrinter = printer; iParser = parser; iLocale = locale; iOffsetParsed = offsetParsed; iChrono = chrono; iZone = zone; iPivotYear = pivotYear; iDefaultYear = defaultYear; } //-----------------------------------------------------------------------
Is this formatter capable of printing.
Returns:true if this is a printer
/** * Is this formatter capable of printing. * * @return true if this is a printer */
public boolean isPrinter() { return (iPrinter != null); }
Gets the internal printer object that performs the real printing work.
Returns:the internal printer; is null if printing not supported
/** * Gets the internal printer object that performs the real printing work. * * @return the internal printer; is null if printing not supported */
public DateTimePrinter getPrinter() { return InternalPrinterDateTimePrinter.of(iPrinter); }
Gets the internal printer object that performs the real printing work.
Returns:the internal printer; is null if printing not supported
/** * Gets the internal printer object that performs the real printing work. * * @return the internal printer; is null if printing not supported */
InternalPrinter getPrinter0() { return iPrinter; }
Is this formatter capable of parsing.
Returns:true if this is a parser
/** * Is this formatter capable of parsing. * * @return true if this is a parser */
public boolean isParser() { return (iParser != null); }
Gets the internal parser object that performs the real parsing work.
Returns:the internal parser; is null if parsing not supported
/** * Gets the internal parser object that performs the real parsing work. * * @return the internal parser; is null if parsing not supported */
public DateTimeParser getParser() { return InternalParserDateTimeParser.of(iParser); } InternalParser getParser0() { return iParser; } //-----------------------------------------------------------------------
Returns a new formatter with a different locale that will be used for printing and parsing.

A DateTimeFormatter is immutable, so a new instance is returned, and the original is unaltered and still usable.

Params:
  • locale – the locale to use; if null, formatter uses default locale at invocation time
Returns:the new formatter
/** * Returns a new formatter with a different locale that will be used * for printing and parsing. * <p> * A DateTimeFormatter is immutable, so a new instance is returned, * and the original is unaltered and still usable. * * @param locale the locale to use; if null, formatter uses default locale * at invocation time * @return the new formatter */
public DateTimeFormatter withLocale(Locale locale) { if (locale == getLocale() || (locale != null && locale.equals(getLocale()))) { return this; } return new DateTimeFormatter(iPrinter, iParser, locale, iOffsetParsed, iChrono, iZone, iPivotYear, iDefaultYear); }
Gets the locale that will be used for printing and parsing.
Returns:the locale to use; if null, formatter uses default locale at invocation time
/** * Gets the locale that will be used for printing and parsing. * * @return the locale to use; if null, formatter uses default locale at * invocation time */
public Locale getLocale() { return iLocale; } //-----------------------------------------------------------------------
Returns a new formatter that will create a datetime with a time zone equal to that of the offset of the parsed string.

After calling this method, a string '2004-06-09T10:20:30-08:00' will create a datetime with a zone of -08:00 (a fixed zone, with no daylight savings rules). If the parsed string represents a local time (no zone offset) the parsed datetime will be in the default zone.

Calling this method sets the override zone to null. Calling the override zone method sets this flag off.

Returns:the new formatter
/** * Returns a new formatter that will create a datetime with a time zone * equal to that of the offset of the parsed string. * <p> * After calling this method, a string '2004-06-09T10:20:30-08:00' will * create a datetime with a zone of -08:00 (a fixed zone, with no daylight * savings rules). If the parsed string represents a local time (no zone * offset) the parsed datetime will be in the default zone. * <p> * Calling this method sets the override zone to null. * Calling the override zone method sets this flag off. * * @return the new formatter */
public DateTimeFormatter withOffsetParsed() { if (iOffsetParsed == true) { return this; } return new DateTimeFormatter(iPrinter, iParser, iLocale, true, iChrono, null, iPivotYear, iDefaultYear); }
Checks whether the offset from the string is used as the zone of the parsed datetime.
Returns:true if the offset from the string is used as the zone
/** * Checks whether the offset from the string is used as the zone of * the parsed datetime. * * @return true if the offset from the string is used as the zone */
public boolean isOffsetParsed() { return iOffsetParsed; } //-----------------------------------------------------------------------
Returns a new formatter that will use the specified chronology in preference to that of the printed object, or ISO on a parse.

When printing, this chronology will be used in preference to the chronology from the datetime that would otherwise be used.

When parsing, this chronology will be set on the parsed datetime.

A null chronology means no-override. If both an override chronology and an override zone are set, the override zone will take precedence over the zone in the chronology.

Params:
  • chrono – the chronology to use as an override
Returns:the new formatter
/** * Returns a new formatter that will use the specified chronology in * preference to that of the printed object, or ISO on a parse. * <p> * When printing, this chronology will be used in preference to the chronology * from the datetime that would otherwise be used. * <p> * When parsing, this chronology will be set on the parsed datetime. * <p> * A null chronology means no-override. * If both an override chronology and an override zone are set, the * override zone will take precedence over the zone in the chronology. * * @param chrono the chronology to use as an override * @return the new formatter */
public DateTimeFormatter withChronology(Chronology chrono) { if (iChrono == chrono) { return this; } return new DateTimeFormatter(iPrinter, iParser, iLocale, iOffsetParsed, chrono, iZone, iPivotYear, iDefaultYear); }
Gets the chronology to use as an override.
Returns:the chronology to use as an override
/** * Gets the chronology to use as an override. * * @return the chronology to use as an override */
public Chronology getChronology() { return iChrono; }
Gets the chronology to use as an override.
Returns:the chronology to use as an override
Deprecated:Use the method with the correct spelling
/** * Gets the chronology to use as an override. * * @return the chronology to use as an override * @deprecated Use the method with the correct spelling */
@Deprecated public Chronology getChronolgy() { return iChrono; } //-----------------------------------------------------------------------
Returns a new formatter that will use the UTC zone in preference to the zone of the printed object, or default zone on a parse.

When printing, UTC will be used in preference to the zone from the datetime that would otherwise be used.

When parsing, UTC will be set on the parsed datetime.

If both an override chronology and an override zone are set, the override zone will take precedence over the zone in the chronology.

Returns:the new formatter, never null
Since:2.0
/** * Returns a new formatter that will use the UTC zone in preference * to the zone of the printed object, or default zone on a parse. * <p> * When printing, UTC will be used in preference to the zone * from the datetime that would otherwise be used. * <p> * When parsing, UTC will be set on the parsed datetime. * <p> * If both an override chronology and an override zone are set, the * override zone will take precedence over the zone in the chronology. * * @return the new formatter, never null * @since 2.0 */
public DateTimeFormatter withZoneUTC() { return withZone(DateTimeZone.UTC); }
Returns a new formatter that will use the specified zone in preference to the zone of the printed object, or default zone on a parse.

When printing, this zone will be used in preference to the zone from the datetime that would otherwise be used.

When parsing, this zone will be set on the parsed datetime.

A null zone means of no-override. If both an override chronology and an override zone are set, the override zone will take precedence over the zone in the chronology.

Params:
  • zone – the zone to use as an override
Returns:the new formatter
/** * Returns a new formatter that will use the specified zone in preference * to the zone of the printed object, or default zone on a parse. * <p> * When printing, this zone will be used in preference to the zone * from the datetime that would otherwise be used. * <p> * When parsing, this zone will be set on the parsed datetime. * <p> * A null zone means of no-override. * If both an override chronology and an override zone are set, the * override zone will take precedence over the zone in the chronology. * * @param zone the zone to use as an override * @return the new formatter */
public DateTimeFormatter withZone(DateTimeZone zone) { if (iZone == zone) { return this; } return new DateTimeFormatter(iPrinter, iParser, iLocale, false, iChrono, zone, iPivotYear, iDefaultYear); }
Gets the zone to use as an override.
Returns:the zone to use as an override
/** * Gets the zone to use as an override. * * @return the zone to use as an override */
public DateTimeZone getZone() { return iZone; } //-----------------------------------------------------------------------
Returns a new formatter that will use the specified pivot year for two digit year parsing in preference to that stored in the parser.

This setting is useful for changing the pivot year of formats built using a pattern - DateTimeFormat.forPattern(String).

When parsing, this pivot year is used. Null means no-override. There is no effect when printing.

The pivot year enables a two digit year to be converted to a four digit year. The pivot represents the year in the middle of the supported range of years. Thus the full range of years that will be built is (pivot - 50) .. (pivot + 49).

pivot   supported range   00 is   20 is   40 is   60 is   80 is
---------------------------------------------------------------
1950      1900..1999      1900    1920    1940    1960    1980
1975      1925..2024      2000    2020    1940    1960    1980
2000      1950..2049      2000    2020    2040    1960    1980
2025      1975..2074      2000    2020    2040    2060    1980
2050      2000..2099      2000    2020    2040    2060    2080
Params:
  • pivotYear – the pivot year to use as an override when parsing
Returns:the new formatter
Since:1.1
/** * Returns a new formatter that will use the specified pivot year for two * digit year parsing in preference to that stored in the parser. * <p> * This setting is useful for changing the pivot year of formats built * using a pattern - {@link DateTimeFormat#forPattern(String)}. * <p> * When parsing, this pivot year is used. Null means no-override. * There is no effect when printing. * <p> * The pivot year enables a two digit year to be converted to a four * digit year. The pivot represents the year in the middle of the * supported range of years. Thus the full range of years that will * be built is <code>(pivot - 50) .. (pivot + 49)</code>. * * <pre> * pivot supported range 00 is 20 is 40 is 60 is 80 is * --------------------------------------------------------------- * 1950 1900..1999 1900 1920 1940 1960 1980 * 1975 1925..2024 2000 2020 1940 1960 1980 * 2000 1950..2049 2000 2020 2040 1960 1980 * 2025 1975..2074 2000 2020 2040 2060 1980 * 2050 2000..2099 2000 2020 2040 2060 2080 * </pre> * * @param pivotYear the pivot year to use as an override when parsing * @return the new formatter * @since 1.1 */
public DateTimeFormatter withPivotYear(Integer pivotYear) { if (iPivotYear == pivotYear || (iPivotYear != null && iPivotYear.equals(pivotYear))) { return this; } return new DateTimeFormatter(iPrinter, iParser, iLocale, iOffsetParsed, iChrono, iZone, pivotYear, iDefaultYear); }
Returns a new formatter that will use the specified pivot year for two digit year parsing in preference to that stored in the parser.

This setting is useful for changing the pivot year of formats built using a pattern - DateTimeFormat.forPattern(String).

When parsing, this pivot year is used. There is no effect when printing.

The pivot year enables a two digit year to be converted to a four digit year. The pivot represents the year in the middle of the supported range of years. Thus the full range of years that will be built is (pivot - 50) .. (pivot + 49).

pivot   supported range   00 is   20 is   40 is   60 is   80 is
---------------------------------------------------------------
1950      1900..1999      1900    1920    1940    1960    1980
1975      1925..2024      2000    2020    1940    1960    1980
2000      1950..2049      2000    2020    2040    1960    1980
2025      1975..2074      2000    2020    2040    2060    1980
2050      2000..2099      2000    2020    2040    2060    2080
Params:
  • pivotYear – the pivot year to use as an override when parsing
Returns:the new formatter
Since:1.1
/** * Returns a new formatter that will use the specified pivot year for two * digit year parsing in preference to that stored in the parser. * <p> * This setting is useful for changing the pivot year of formats built * using a pattern - {@link DateTimeFormat#forPattern(String)}. * <p> * When parsing, this pivot year is used. * There is no effect when printing. * <p> * The pivot year enables a two digit year to be converted to a four * digit year. The pivot represents the year in the middle of the * supported range of years. Thus the full range of years that will * be built is <code>(pivot - 50) .. (pivot + 49)</code>. * * <pre> * pivot supported range 00 is 20 is 40 is 60 is 80 is * --------------------------------------------------------------- * 1950 1900..1999 1900 1920 1940 1960 1980 * 1975 1925..2024 2000 2020 1940 1960 1980 * 2000 1950..2049 2000 2020 2040 1960 1980 * 2025 1975..2074 2000 2020 2040 2060 1980 * 2050 2000..2099 2000 2020 2040 2060 2080 * </pre> * * @param pivotYear the pivot year to use as an override when parsing * @return the new formatter * @since 1.1 */
public DateTimeFormatter withPivotYear(int pivotYear) { return withPivotYear(Integer.valueOf(pivotYear)); }
Gets the pivot year to use as an override.
Returns:the pivot year to use as an override
Since:1.1
/** * Gets the pivot year to use as an override. * * @return the pivot year to use as an override * @since 1.1 */
public Integer getPivotYear() { return iPivotYear; } //-----------------------------------------------------------------------
Returns a new formatter that will use the specified default year.

The default year is used when parsing in the case where there is a month or a day but not a year. Specifically, it is used if there is a field parsed with a duration between the length of a month and the length of a day inclusive.

This value is typically used to move the year from 1970 to a leap year to enable February 29th to be parsed. Unless customised, the year 2000 is used.

This setting has no effect when printing.

Params:
  • defaultYear – the default year to use
Returns:the new formatter, not null
Since:2.0
/** * Returns a new formatter that will use the specified default year. * <p> * The default year is used when parsing in the case where there is a * month or a day but not a year. Specifically, it is used if there is * a field parsed with a duration between the length of a month and the * length of a day inclusive. * <p> * This value is typically used to move the year from 1970 to a leap year * to enable February 29th to be parsed. * Unless customised, the year 2000 is used. * <p> * This setting has no effect when printing. * * @param defaultYear the default year to use * @return the new formatter, not null * @since 2.0 */
public DateTimeFormatter withDefaultYear(int defaultYear) { return new DateTimeFormatter(iPrinter, iParser, iLocale, iOffsetParsed, iChrono, iZone, iPivotYear, defaultYear); }
Gets the default year for parsing months and days.
Returns:the default year for parsing months and days
Since:2.0
/** * Gets the default year for parsing months and days. * * @return the default year for parsing months and days * @since 2.0 */
public int getDefaultYear() { return iDefaultYear; } //-----------------------------------------------------------------------
Prints a ReadableInstant, using the chronology supplied by the instant.
Params:
  • buf – the destination to format to, not null
  • instant – instant to format, null means now
/** * Prints a ReadableInstant, using the chronology supplied by the instant. * * @param buf the destination to format to, not null * @param instant instant to format, null means now */
public void printTo(StringBuffer buf, ReadableInstant instant) { try { printTo((Appendable) buf, instant); } catch (IOException ex) { // StringBuffer does not throw IOException } }
Prints a ReadableInstant, using the chronology supplied by the instant.
Params:
  • buf – the destination to format to, not null
  • instant – instant to format, null means now
/** * Prints a ReadableInstant, using the chronology supplied by the instant. * * @param buf the destination to format to, not null * @param instant instant to format, null means now */
public void printTo(StringBuilder buf, ReadableInstant instant) { try { printTo((Appendable) buf, instant); } catch (IOException ex) { // StringBuilder does not throw IOException } }
Prints a ReadableInstant, using the chronology supplied by the instant.
Params:
  • out – the destination to format to, not null
  • instant – instant to format, null means now
/** * Prints a ReadableInstant, using the chronology supplied by the instant. * * @param out the destination to format to, not null * @param instant instant to format, null means now */
public void printTo(Writer out, ReadableInstant instant) throws IOException { printTo((Appendable) out, instant); }
Prints a ReadableInstant, using the chronology supplied by the instant.
Params:
  • appendable – the destination to format to, not null
  • instant – instant to format, null means now
Since:2.0
/** * Prints a ReadableInstant, using the chronology supplied by the instant. * * @param appendable the destination to format to, not null * @param instant instant to format, null means now * @since 2.0 */
public void printTo(Appendable appendable, ReadableInstant instant) throws IOException { long millis = DateTimeUtils.getInstantMillis(instant); Chronology chrono = DateTimeUtils.getInstantChronology(instant); printTo(appendable, millis, chrono); } //-----------------------------------------------------------------------
Prints an instant from milliseconds since 1970-01-01T00:00:00Z, using ISO chronology in the default DateTimeZone.
Params:
  • buf – the destination to format to, not null
  • instant – millis since 1970-01-01T00:00:00Z
/** * Prints an instant from milliseconds since 1970-01-01T00:00:00Z, * using ISO chronology in the default DateTimeZone. * * @param buf the destination to format to, not null * @param instant millis since 1970-01-01T00:00:00Z */
public void printTo(StringBuffer buf, long instant) { try { printTo((Appendable) buf, instant); } catch (IOException ex) { // StringBuffer does not throw IOException } }
Prints an instant from milliseconds since 1970-01-01T00:00:00Z, using ISO chronology in the default DateTimeZone.
Params:
  • buf – the destination to format to, not null
  • instant – millis since 1970-01-01T00:00:00Z
/** * Prints an instant from milliseconds since 1970-01-01T00:00:00Z, * using ISO chronology in the default DateTimeZone. * * @param buf the destination to format to, not null * @param instant millis since 1970-01-01T00:00:00Z */
public void printTo(StringBuilder buf, long instant) { try { printTo((Appendable) buf, instant); } catch (IOException ex) { // StringBuilder does not throw IOException } }
Prints an instant from milliseconds since 1970-01-01T00:00:00Z, using ISO chronology in the default DateTimeZone.
Params:
  • out – the destination to format to, not null
  • instant – millis since 1970-01-01T00:00:00Z
/** * Prints an instant from milliseconds since 1970-01-01T00:00:00Z, * using ISO chronology in the default DateTimeZone. * * @param out the destination to format to, not null * @param instant millis since 1970-01-01T00:00:00Z */
public void printTo(Writer out, long instant) throws IOException { printTo((Appendable) out, instant); }
Prints an instant from milliseconds since 1970-01-01T00:00:00Z, using ISO chronology in the default DateTimeZone.
Params:
  • appendable – the destination to format to, not null
  • instant – millis since 1970-01-01T00:00:00Z
Since:2.0
/** * Prints an instant from milliseconds since 1970-01-01T00:00:00Z, * using ISO chronology in the default DateTimeZone. * * @param appendable the destination to format to, not null * @param instant millis since 1970-01-01T00:00:00Z * @since 2.0 */
public void printTo(Appendable appendable, long instant) throws IOException { printTo(appendable, instant, null); } //-----------------------------------------------------------------------
Prints a ReadablePartial.

Neither the override chronology nor the override zone are used by this method.

Params:
  • buf – the destination to format to, not null
  • partial – partial to format
/** * Prints a ReadablePartial. * <p> * Neither the override chronology nor the override zone are used * by this method. * * @param buf the destination to format to, not null * @param partial partial to format */
public void printTo(StringBuffer buf, ReadablePartial partial) { try { printTo((Appendable) buf, partial); } catch (IOException ex) { // StringBuffer does not throw IOException } }
Prints a ReadablePartial.

Neither the override chronology nor the override zone are used by this method.

Params:
  • buf – the destination to format to, not null
  • partial – partial to format
/** * Prints a ReadablePartial. * <p> * Neither the override chronology nor the override zone are used * by this method. * * @param buf the destination to format to, not null * @param partial partial to format */
public void printTo(StringBuilder buf, ReadablePartial partial) { try { printTo((Appendable) buf, partial); } catch (IOException ex) { // StringBuilder does not throw IOException } }
Prints a ReadablePartial.

Neither the override chronology nor the override zone are used by this method.

Params:
  • out – the destination to format to, not null
  • partial – partial to format
/** * Prints a ReadablePartial. * <p> * Neither the override chronology nor the override zone are used * by this method. * * @param out the destination to format to, not null * @param partial partial to format */
public void printTo(Writer out, ReadablePartial partial) throws IOException { printTo((Appendable) out, partial); }
Prints a ReadablePartial.

Neither the override chronology nor the override zone are used by this method.

Params:
  • appendable – the destination to format to, not null
  • partial – partial to format
Since:2.0
/** * Prints a ReadablePartial. * <p> * Neither the override chronology nor the override zone are used * by this method. * * @param appendable the destination to format to, not null * @param partial partial to format * @since 2.0 */
public void printTo(Appendable appendable, ReadablePartial partial) throws IOException { InternalPrinter printer = requirePrinter(); if (partial == null) { throw new IllegalArgumentException("The partial must not be null"); } printer.printTo(appendable, partial, iLocale); } //-----------------------------------------------------------------------
Prints a ReadableInstant to a String.

This method will use the override zone and the override chronology if they are set. Otherwise it will use the chronology and zone of the instant.

Params:
  • instant – instant to format, null means now
Returns:the printed result
/** * Prints a ReadableInstant to a String. * <p> * This method will use the override zone and the override chronology if * they are set. Otherwise it will use the chronology and zone of the instant. * * @param instant instant to format, null means now * @return the printed result */
public String print(ReadableInstant instant) { StringBuilder buf = new StringBuilder(requirePrinter().estimatePrintedLength()); try { printTo((Appendable) buf, instant); } catch (IOException ex) { // StringBuilder does not throw IOException } return buf.toString(); }
Prints a millisecond instant to a String.

This method will use the override zone and the override chronology if they are set. Otherwise it will use the ISO chronology and default zone.

Params:
  • instant – millis since 1970-01-01T00:00:00Z
Returns:the printed result
/** * Prints a millisecond instant to a String. * <p> * This method will use the override zone and the override chronology if * they are set. Otherwise it will use the ISO chronology and default zone. * * @param instant millis since 1970-01-01T00:00:00Z * @return the printed result */
public String print(long instant) { StringBuilder buf = new StringBuilder(requirePrinter().estimatePrintedLength()); try { printTo((Appendable) buf, instant); } catch (IOException ex) { // StringBuilder does not throw IOException } return buf.toString(); }
Prints a ReadablePartial to a new String.

Neither the override chronology nor the override zone are used by this method.

Params:
  • partial – partial to format
Returns:the printed result
/** * Prints a ReadablePartial to a new String. * <p> * Neither the override chronology nor the override zone are used * by this method. * * @param partial partial to format * @return the printed result */
public String print(ReadablePartial partial) { StringBuilder buf = new StringBuilder(requirePrinter().estimatePrintedLength()); try { printTo((Appendable) buf, partial); } catch (IOException ex) { // StringBuilder does not throw IOException } return buf.toString(); } private void printTo(Appendable appendable, long instant, Chronology chrono) throws IOException { InternalPrinter printer = requirePrinter(); chrono = selectChronology(chrono); // Shift instant into local time (UTC) to avoid excessive offset // calculations when printing multiple fields in a composite printer. DateTimeZone zone = chrono.getZone(); int offset = zone.getOffset(instant); long adjustedInstant = instant + offset; if ((instant ^ adjustedInstant) < 0 && (instant ^ offset) >= 0) { // Time zone offset overflow, so revert to UTC. zone = DateTimeZone.UTC; offset = 0; adjustedInstant = instant; } printer.printTo(appendable, adjustedInstant, chrono.withUTC(), offset, zone, iLocale); }
Checks whether printing is supported.
Throws:
  • UnsupportedOperationException – if printing is not supported
/** * Checks whether printing is supported. * * @throws UnsupportedOperationException if printing is not supported */
private InternalPrinter requirePrinter() { InternalPrinter printer = iPrinter; if (printer == null) { throw new UnsupportedOperationException("Printing not supported"); } return printer; } //-----------------------------------------------------------------------
Parses a datetime from the given text, at the given position, saving the result into the fields of the given ReadWritableInstant. If the parse succeeds, the return value is the new text position. Note that the parse may succeed without fully reading the text and in this case those fields that were read will be set.

Only those fields present in the string will be changed in the specified instant. All other fields will remain unaltered. Thus if the string only contains a year and a month, then the day and time will be retained from the input instant. If this is not the behaviour you want, then reset the fields before calling this method, or use parseDateTime(String) or parseMutableDateTime(String).

If it fails, the return value is negative, but the instant may still be modified. To determine the position where the parse failed, apply the one's complement operator (~) on the return value.

This parse method ignores the default year and parses using the year from the supplied instant based on the chronology and time-zone of the supplied instant.

The parse will use the chronology of the instant.

Params:
  • instant – an instant that will be modified, not null
  • text – the text to parse
  • position – position to start parsing from
Throws:
Returns:new position, negative value means parse failed - apply complement operator (~) to get position of failure
/** * Parses a datetime from the given text, at the given position, saving the * result into the fields of the given ReadWritableInstant. If the parse * succeeds, the return value is the new text position. Note that the parse * may succeed without fully reading the text and in this case those fields * that were read will be set. * <p> * Only those fields present in the string will be changed in the specified * instant. All other fields will remain unaltered. Thus if the string only * contains a year and a month, then the day and time will be retained from * the input instant. If this is not the behaviour you want, then reset the * fields before calling this method, or use {@link #parseDateTime(String)} * or {@link #parseMutableDateTime(String)}. * <p> * If it fails, the return value is negative, but the instant may still be * modified. To determine the position where the parse failed, apply the * one's complement operator (~) on the return value. * <p> * This parse method ignores the {@link #getDefaultYear() default year} and * parses using the year from the supplied instant based on the chronology * and time-zone of the supplied instant. * <p> * The parse will use the chronology of the instant. * * @param instant an instant that will be modified, not null * @param text the text to parse * @param position position to start parsing from * @return new position, negative value means parse failed - * apply complement operator (~) to get position of failure * @throws UnsupportedOperationException if parsing is not supported * @throws IllegalArgumentException if the instant is null * @throws IllegalArgumentException if any field is out of range */
public int parseInto(ReadWritableInstant instant, String text, int position) { InternalParser parser = requireParser(); if (instant == null) { throw new IllegalArgumentException("Instant must not be null"); } long instantMillis = instant.getMillis(); Chronology chrono = instant.getChronology(); int defaultYear = DateTimeUtils.getChronology(chrono).year().get(instantMillis); long instantLocal = instantMillis + chrono.getZone().getOffset(instantMillis); chrono = selectChronology(chrono); DateTimeParserBucket bucket = new DateTimeParserBucket( instantLocal, chrono, iLocale, iPivotYear, defaultYear); int newPos = parser.parseInto(bucket, text, position); instant.setMillis(bucket.computeMillis(false, text)); if (iOffsetParsed && bucket.getOffsetInteger() != null) { int parsedOffset = bucket.getOffsetInteger(); DateTimeZone parsedZone = DateTimeZone.forOffsetMillis(parsedOffset); chrono = chrono.withZone(parsedZone); } else if (bucket.getZone() != null) { chrono = chrono.withZone(bucket.getZone()); } instant.setChronology(chrono); if (iZone != null) { instant.setZone(iZone); } return newPos; }
Parses a datetime from the given text, returning the number of milliseconds since the epoch, 1970-01-01T00:00:00Z.

The parse will use the ISO chronology, and the default time zone. If the text contains a time zone string then that will be taken into account.

Params:
  • text – the text to parse, not null
Throws:
Returns:parsed value expressed in milliseconds since the epoch
/** * Parses a datetime from the given text, returning the number of * milliseconds since the epoch, 1970-01-01T00:00:00Z. * <p> * The parse will use the ISO chronology, and the default time zone. * If the text contains a time zone string then that will be taken into account. * * @param text the text to parse, not null * @return parsed value expressed in milliseconds since the epoch * @throws UnsupportedOperationException if parsing is not supported * @throws IllegalArgumentException if the text to parse is invalid */
public long parseMillis(String text) { InternalParser parser = requireParser(); Chronology chrono = selectChronology(iChrono); DateTimeParserBucket bucket = new DateTimeParserBucket(0, chrono, iLocale, iPivotYear, iDefaultYear); return bucket.doParseMillis(parser, text); }
Parses only the local date from the given text, returning a new LocalDate.

This will parse the text fully according to the formatter, using the UTC zone. Once parsed, only the local date will be used. This means that any parsed time, time-zone or offset field is completely ignored. It also means that the zone and offset-parsed settings are ignored.

Params:
  • text – the text to parse, not null
Throws:
Returns:the parsed date, never null
Since:2.0
/** * Parses only the local date from the given text, returning a new LocalDate. * <p> * This will parse the text fully according to the formatter, using the UTC zone. * Once parsed, only the local date will be used. * This means that any parsed time, time-zone or offset field is completely ignored. * It also means that the zone and offset-parsed settings are ignored. * * @param text the text to parse, not null * @return the parsed date, never null * @throws UnsupportedOperationException if parsing is not supported * @throws IllegalArgumentException if the text to parse is invalid * @since 2.0 */
public LocalDate parseLocalDate(String text) { return parseLocalDateTime(text).toLocalDate(); }
Parses only the local time from the given text, returning a new LocalTime.

This will parse the text fully according to the formatter, using the UTC zone. Once parsed, only the local time will be used. This means that any parsed date, time-zone or offset field is completely ignored. It also means that the zone and offset-parsed settings are ignored.

Params:
  • text – the text to parse, not null
Throws:
Returns:the parsed time, never null
Since:2.0
/** * Parses only the local time from the given text, returning a new LocalTime. * <p> * This will parse the text fully according to the formatter, using the UTC zone. * Once parsed, only the local time will be used. * This means that any parsed date, time-zone or offset field is completely ignored. * It also means that the zone and offset-parsed settings are ignored. * * @param text the text to parse, not null * @return the parsed time, never null * @throws UnsupportedOperationException if parsing is not supported * @throws IllegalArgumentException if the text to parse is invalid * @since 2.0 */
public LocalTime parseLocalTime(String text) { return parseLocalDateTime(text).toLocalTime(); }
Parses only the local date-time from the given text, returning a new LocalDateTime.

This will parse the text fully according to the formatter, using the UTC zone. Once parsed, only the local date-time will be used. This means that any parsed time-zone or offset field is completely ignored. It also means that the zone and offset-parsed settings are ignored.

Params:
  • text – the text to parse, not null
Throws:
Returns:the parsed date-time, never null
Since:2.0
/** * Parses only the local date-time from the given text, returning a new LocalDateTime. * <p> * This will parse the text fully according to the formatter, using the UTC zone. * Once parsed, only the local date-time will be used. * This means that any parsed time-zone or offset field is completely ignored. * It also means that the zone and offset-parsed settings are ignored. * * @param text the text to parse, not null * @return the parsed date-time, never null * @throws UnsupportedOperationException if parsing is not supported * @throws IllegalArgumentException if the text to parse is invalid * @since 2.0 */
public LocalDateTime parseLocalDateTime(String text) { InternalParser parser = requireParser(); Chronology chrono = selectChronology(null).withUTC(); // always use UTC, avoiding DST gaps DateTimeParserBucket bucket = new DateTimeParserBucket(0, chrono, iLocale, iPivotYear, iDefaultYear); int newPos = parser.parseInto(bucket, text, 0); if (newPos >= 0) { if (newPos >= text.length()) { long millis = bucket.computeMillis(true, text); if (bucket.getOffsetInteger() != null) { // treat withOffsetParsed() as being true int parsedOffset = bucket.getOffsetInteger(); DateTimeZone parsedZone = DateTimeZone.forOffsetMillis(parsedOffset); chrono = chrono.withZone(parsedZone); } else if (bucket.getZone() != null) { chrono = chrono.withZone(bucket.getZone()); } return new LocalDateTime(millis, chrono); } } else { newPos = ~newPos; } throw new IllegalArgumentException(FormatUtils.createErrorMessage(text, newPos)); }
Parses a date-time from the given text, returning a new DateTime.

The parse will use the zone and chronology specified on this formatter.

If the text contains a time zone string then that will be taken into account in adjusting the time of day as follows. If the withOffsetParsed() has been called, then the resulting DateTime will have a fixed offset based on the parsed time zone. Otherwise the resulting DateTime will have the zone of this formatter, but the parsed zone may have caused the time to be adjusted.

Params:
  • text – the text to parse, not null
Throws:
Returns:the parsed date-time, never null
/** * Parses a date-time from the given text, returning a new DateTime. * <p> * The parse will use the zone and chronology specified on this formatter. * <p> * If the text contains a time zone string then that will be taken into * account in adjusting the time of day as follows. * If the {@link #withOffsetParsed()} has been called, then the resulting * DateTime will have a fixed offset based on the parsed time zone. * Otherwise the resulting DateTime will have the zone of this formatter, * but the parsed zone may have caused the time to be adjusted. * * @param text the text to parse, not null * @return the parsed date-time, never null * @throws UnsupportedOperationException if parsing is not supported * @throws IllegalArgumentException if the text to parse is invalid */
public DateTime parseDateTime(String text) { InternalParser parser = requireParser(); Chronology chrono = selectChronology(null); DateTimeParserBucket bucket = new DateTimeParserBucket(0, chrono, iLocale, iPivotYear, iDefaultYear); int newPos = parser.parseInto(bucket, text, 0); if (newPos >= 0) { if (newPos >= text.length()) { long millis = bucket.computeMillis(true, text); if (iOffsetParsed && bucket.getOffsetInteger() != null) { int parsedOffset = bucket.getOffsetInteger(); DateTimeZone parsedZone = DateTimeZone.forOffsetMillis(parsedOffset); chrono = chrono.withZone(parsedZone); } else if (bucket.getZone() != null) { chrono = chrono.withZone(bucket.getZone()); } DateTime dt = new DateTime(millis, chrono); if (iZone != null) { dt = dt.withZone(iZone); } return dt; } } else { newPos = ~newPos; } throw new IllegalArgumentException(FormatUtils.createErrorMessage(text, newPos)); }
Parses a date-time from the given text, returning a new MutableDateTime.

The parse will use the zone and chronology specified on this formatter.

If the text contains a time zone string then that will be taken into account in adjusting the time of day as follows. If the withOffsetParsed() has been called, then the resulting DateTime will have a fixed offset based on the parsed time zone. Otherwise the resulting DateTime will have the zone of this formatter, but the parsed zone may have caused the time to be adjusted.

Params:
  • text – the text to parse, not null
Throws:
Returns:the parsed date-time, never null
/** * Parses a date-time from the given text, returning a new MutableDateTime. * <p> * The parse will use the zone and chronology specified on this formatter. * <p> * If the text contains a time zone string then that will be taken into * account in adjusting the time of day as follows. * If the {@link #withOffsetParsed()} has been called, then the resulting * DateTime will have a fixed offset based on the parsed time zone. * Otherwise the resulting DateTime will have the zone of this formatter, * but the parsed zone may have caused the time to be adjusted. * * @param text the text to parse, not null * @return the parsed date-time, never null * @throws UnsupportedOperationException if parsing is not supported * @throws IllegalArgumentException if the text to parse is invalid */
public MutableDateTime parseMutableDateTime(String text) { InternalParser parser = requireParser(); Chronology chrono = selectChronology(null); DateTimeParserBucket bucket = new DateTimeParserBucket(0, chrono, iLocale, iPivotYear, iDefaultYear); int newPos = parser.parseInto(bucket, text, 0); if (newPos >= 0) { if (newPos >= text.length()) { long millis = bucket.computeMillis(true, text); if (iOffsetParsed && bucket.getOffsetInteger() != null) { int parsedOffset = bucket.getOffsetInteger(); DateTimeZone parsedZone = DateTimeZone.forOffsetMillis(parsedOffset); chrono = chrono.withZone(parsedZone); } else if (bucket.getZone() != null) { chrono = chrono.withZone(bucket.getZone()); } MutableDateTime dt = new MutableDateTime(millis, chrono); if (iZone != null) { dt.setZone(iZone); } return dt; } } else { newPos = ~newPos; } throw new IllegalArgumentException(FormatUtils.createErrorMessage(text, newPos)); }
Checks whether parsing is supported.
Throws:
  • UnsupportedOperationException – if parsing is not supported
/** * Checks whether parsing is supported. * * @throws UnsupportedOperationException if parsing is not supported */
private InternalParser requireParser() { InternalParser parser = iParser; if (parser == null) { throw new UnsupportedOperationException("Parsing not supported"); } return parser; } //-----------------------------------------------------------------------
Determines the correct chronology to use.
Params:
  • chrono – the proposed chronology
Returns:the actual chronology
/** * Determines the correct chronology to use. * * @param chrono the proposed chronology * @return the actual chronology */
private Chronology selectChronology(Chronology chrono) { chrono = DateTimeUtils.getChronology(chrono); if (iChrono != null) { chrono = iChrono; } if (iZone != null) { chrono = chrono.withZone(iZone); } return chrono; } }