java.util.Formatter Maven / Gradle / Ivy
Show all versions of dragome-js-jre Show documentation
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.util;
import java.io.Closeable;
import java.io.Flushable;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigAny;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
import java.text.DecimalFormatSymbols;
import java.time.temporal.TemporalAccessor;
import java.util.regex.Pattern;
/**
* An interpreter for printf-style format strings. This class provides support
* for layout justification and alignment, common formats for numeric, string,
* and date/time data, and locale-specific output. Common Java types such as
* {@code byte}, {@link java.math.BigAny BigDecimal}, and {@link Calendar}
* are supported. Limited formatting customization for arbitrary user types is
* provided through the {@link Formattable} interface.
*
* Formatters are not necessarily safe for multithreaded access. Thread
* safety is optional and is the responsibility of users of methods in this
* class.
*
*
Formatted printing for the Java language is heavily inspired by C's
* {@code printf}. Although the format strings are similar to C, some
* customizations have been made to accommodate the Java language and exploit
* some of its features. Also, Java formatting is more strict than C's; for
* example, if a conversion is incompatible with a flag, an exception will be
* thrown. In C inapplicable flags are silently ignored. The format strings
* are thus intended to be recognizable to C programmers but not necessarily
* completely compatible with those in C.
*
*
Examples of expected usage:
*
*
* StringBuilder sb = new StringBuilder();
* // Send all output to the Appendable object sb
* Formatter formatter = new Formatter(sb, Locale.US);
*
* // Explicit argument indices may be used to re-order output.
* formatter.format("%4$2s %3$2s %2$2s %1$2s", "a", "b", "c", "d")
* // -> " d c b a"
*
* // Optional locale as the first argument can be used to get
* // locale-specific formatting of numbers. The precision and width can be
* // given to round and align the value.
* formatter.format(Locale.FRANCE, "e = %+10.4f", Math.E);
* // -> "e = +2,7183"
*
* // The '(' numeric flag may be used to format negative numbers with
* // parentheses rather than a minus sign. Group separators are
* // automatically inserted.
* formatter.format("Amount gained or lost since last statement: $ %(,.2f",
* balanceDelta);
* // -> "Amount gained or lost since last statement: $ (6,217.58)"
*
*
* Convenience methods for common formatting requests exist as illustrated
* by the following invocations:
*
*
* // Writes a formatted string to System.out.
* System.out.format("Local time: %tT", Calendar.getInstance());
* // -> "Local time: 13:34:18"
*
* // Writes formatted output to System.err.
* System.err.printf("Unable to open file '%1$s': %2$s",
* fileName, exception.getMessage());
* // -> "Unable to open file 'food': No such file or directory"
*
*
* Like C's {@code sprintf(3)}, Strings may be formatted using the static
* method {@link String#format(String,Object...) String.format}:
*
*
* // Format a string containing a date.
* import java.util.Calendar;
* import java.util.GregorianCalendar;
* import static java.util.Calendar.*;
*
* Calendar c = new GregorianCalendar(1995, MAY, 23);
* String s = String.format("Duke's Birthday: %1$tb %1$te, %1$tY", c);
* // -> s == "Duke's Birthday: May 23, 1995"
*
*
* Organization
*
* This specification is divided into two sections. The first section, Summary, covers the basic formatting concepts. This
* section is intended for users who want to get started quickly and are
* familiar with formatted printing in other programming languages. The second
* section, Details, covers the specific implementation
* details. It is intended for users who want more precise specification of
* formatting behavior.
*
*
Summary
*
* This section is intended to provide a brief overview of formatting
* concepts. For precise behavioral details, refer to the Details section.
*
*
Format String Syntax
*
* Every method which produces formatted output requires a format
* string and an argument list. The format string is a {@link
* String} which may contain fixed text and one or more embedded format
* specifiers. Consider the following example:
*
*
* Calendar c = ...;
* String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
*
*
* This format string is the first argument to the {@code format} method. It
* contains three format specifiers "{@code %1$tm}", "{@code %1$te}", and
* "{@code %1$tY}" which indicate how the arguments should be processed and
* where they should be inserted in the text. The remaining portions of the
* format string are fixed text including {@code "Dukes Birthday: "} and any
* other spaces or punctuation.
*
* The argument list consists of all arguments passed to the method after the
* format string. In the above example, the argument list is of size one and
* consists of the {@link java.util.Calendar Calendar} object {@code c}.
*
*
*
* - The format specifiers for general, character, and numeric types have
* the following syntax:
*
*
* %[argument_index$][flags][width][.precision]conversion
*
*
* The optional argument_index is a decimal integer indicating the
* position of the argument in the argument list. The first argument is
* referenced by "{@code 1$}", the second by "{@code 2$}", etc.
*
*
The optional flags is a set of characters that modify the output
* format. The set of valid flags depends on the conversion.
*
*
The optional width is a positive decimal integer indicating
* the minimum number of characters to be written to the output.
*
*
The optional precision is a non-negative decimal integer usually
* used to restrict the number of characters. The specific behavior depends on
* the conversion.
*
*
The required conversion is a character indicating how the
* argument should be formatted. The set of valid conversions for a given
* argument depends on the argument's data type.
*
*
- The format specifiers for types which are used to represents dates and
* times have the following syntax:
*
*
* %[argument_index$][flags][width]conversion
*
*
* The optional argument_index, flags and width are
* defined as above.
*
*
The required conversion is a two character sequence. The first
* character is {@code 't'} or {@code 'T'}. The second character indicates
* the format to be used. These characters are similar to but not completely
* identical to those defined by GNU {@code date} and POSIX
* {@code strftime(3c)}.
*
*
- The format specifiers which do not correspond to arguments have the
* following syntax:
*
*
* %[flags][width]conversion
*
*
* The optional flags and width is defined as above.
*
*
The required conversion is a character indicating content to be
* inserted in the output.
*
*
*
* Conversions
*
* Conversions are divided into the following categories:
*
*
*
* - General - may be applied to any argument
* type
*
*
- Character - may be applied to basic types which represent
* Unicode characters: {@code char}, {@link Character}, {@code byte}, {@link
* Byte}, {@code short}, and {@link Short}. This conversion may also be
* applied to the types {@code int} and {@link Integer} when {@link
* Character#isValidCodePoint} returns {@code true}
*
*
- Numeric
*
*
*
* - Integral - may be applied to Java integral types: {@code byte},
* {@link Byte}, {@code short}, {@link Short}, {@code int} and {@link
* Integer}, {@code long}, {@link Long}, and {@link java.math.BigInteger
* BigInteger} (but not {@code char} or {@link Character})
*
*
- Floating Point - may be applied to Java floating-point types:
* {@code float}, {@link Float}, {@code double}, {@link Double}, and {@link
* java.math.BigAny BigDecimal}
*
*
*
* - Date/Time - may be applied to Java types which are capable of
* encoding a date or time: {@code long}, {@link Long}, {@link Calendar},
* {@link Date} and {@link TemporalAccessor TemporalAccessor}
*
*
- Percent - produces a literal {@code '%'}
* ('\u0025')
*
*
- Line Separator - produces the platform-specific line separator
*
*
*
* The following table summarizes the supported conversions. Conversions
* denoted by an upper-case character (i.e. {@code 'B'}, {@code 'H'},
* {@code 'S'}, {@code 'C'}, {@code 'X'}, {@code 'E'}, {@code 'G'},
* {@code 'A'}, and {@code 'T'}) are the same as those for the corresponding
* lower-case conversion characters except that the result is converted to
* upper case according to the rules of the prevailing {@link java.util.Locale
* Locale}. The result is equivalent to the following invocation of {@link
* String#toUpperCase()}
*
*
* out.toUpperCase()
*
*
*
* Conversion
* Argument Category
* Description
*
* {@code 'b'}, {@code 'B'}
* general
* If the argument arg is {@code null}, then the result is
* "{@code false}". If arg is a {@code boolean} or {@link
* Boolean}, then the result is the string returned by {@link
* String#valueOf(boolean) String.valueOf(arg)}. Otherwise, the result is
* "true".
*
* {@code 'h'}, {@code 'H'}
* general
* If the argument arg is {@code null}, then the result is
* "{@code null}". Otherwise, the result is obtained by invoking
* {@code Integer.toHexString(arg.hashCode())}.
*
* {@code 's'}, {@code 'S'}
* general
* If the argument arg is {@code null}, then the result is
* "{@code null}". If arg implements {@link Formattable}, then
* {@link Formattable#formatTo arg.formatTo} is invoked. Otherwise, the
* result is obtained by invoking {@code arg.toString()}.
*
* {@code 'c'}, {@code 'C'}
* character
* The result is a Unicode character
*
* {@code 'd'}
* integral
* The result is formatted as a decimal integer
*
* {@code 'o'}
* integral
* The result is formatted as an octal integer
*
* {@code 'x'}, {@code 'X'}
* integral
* The result is formatted as a hexadecimal integer
*
* {@code 'e'}, {@code 'E'}
* floating point
* The result is formatted as a decimal number in computerized
* scientific notation
*
* {@code 'f'}
* floating point
* The result is formatted as a decimal number
*
* {@code 'g'}, {@code 'G'}
* floating point
* The result is formatted using computerized scientific notation or
* decimal format, depending on the precision and the value after rounding.
*
* {@code 'a'}, {@code 'A'}
* floating point
* The result is formatted as a hexadecimal floating-point number with
* a significand and an exponent. This conversion is not supported
* for the {@code BigDecimal} type despite the latter's being in the
* floating point argument category.
*
* {@code 't'}, {@code 'T'}
* date/time
* Prefix for date and time conversion characters. See Date/Time Conversions.
*
* {@code '%'}
* percent
* The result is a literal {@code '%'} ('\u0025')
*
* {@code 'n'}
* line separator
* The result is the platform-specific line separator
*
*
*
* Any characters not explicitly defined as conversions are illegal and are
* reserved for future extensions.
*
*
Date/Time Conversions
*
* The following date and time conversion suffix characters are defined for
* the {@code 't'} and {@code 'T'} conversions. The types are similar to but
* not completely identical to those defined by GNU {@code date} and POSIX
* {@code strftime(3c)}. Additional conversion types are provided to access
* Java-specific functionality (e.g. {@code 'L'} for milliseconds within the
* second).
*
*
The following conversion characters are used for formatting times:
*
*
*
* {@code 'H'}
* Hour of the day for the 24-hour clock, formatted as two digits with
* a leading zero as necessary i.e. {@code 00 - 23}.
*
* {@code 'I'}
* Hour for the 12-hour clock, formatted as two digits with a leading
* zero as necessary, i.e. {@code 01 - 12}.
*
* {@code 'k'}
* Hour of the day for the 24-hour clock, i.e. {@code 0 - 23}.
*
* {@code 'l'}
* Hour for the 12-hour clock, i.e. {@code 1 - 12}.
*
* {@code 'M'}
* Minute within the hour formatted as two digits with a leading zero
* as necessary, i.e. {@code 00 - 59}.
*
* {@code 'S'}
* Seconds within the minute, formatted as two digits with a leading
* zero as necessary, i.e. {@code 00 - 60} ("{@code 60}" is a special
* value required to support leap seconds).
*
* {@code 'L'}
* Millisecond within the second formatted as three digits with
* leading zeros as necessary, i.e. {@code 000 - 999}.
*
* {@code 'N'}
* Nanosecond within the second, formatted as nine digits with leading
* zeros as necessary, i.e. {@code 000000000 - 999999999}.
*
* {@code 'p'}
* Locale-specific {@linkplain
* java.text.DateFormatSymbols#getAmPmStrings morning or afternoon} marker
* in lower case, e.g."{@code am}" or "{@code pm}". Use of the conversion
* prefix {@code 'T'} forces this output to upper case.
*
* {@code 'z'}
* RFC 822
* style numeric time zone offset from GMT, e.g. {@code -0800}. This
* value will be adjusted as necessary for Daylight Saving Time. For
* {@code long}, {@link Long}, and {@link Date} the time zone used is
* the {@linkplain TimeZone#getDefault() default time zone} for this
* instance of the Java virtual machine.
*
* {@code 'Z'}
* A string representing the abbreviation for the time zone. This
* value will be adjusted as necessary for Daylight Saving Time. For
* {@code long}, {@link Long}, and {@link Date} the time zone used is
* the {@linkplain TimeZone#getDefault() default time zone} for this
* instance of the Java virtual machine. The Formatter's locale will
* supersede the locale of the argument (if any).
*
* {@code 's'}
* Seconds since the beginning of the epoch starting at 1 January 1970
* {@code 00:00:00} UTC, i.e. {@code Long.MIN_VALUE/1000} to
* {@code Long.MAX_VALUE/1000}.
*
* {@code 'Q'}
* Milliseconds since the beginning of the epoch starting at 1 January
* 1970 {@code 00:00:00} UTC, i.e. {@code Long.MIN_VALUE} to
* {@code Long.MAX_VALUE}.
*
*
*
* The following conversion characters are used for formatting dates:
*
*
*
* {@code 'B'}
* Locale-specific {@linkplain java.text.DateFormatSymbols#getMonths
* full month name}, e.g. {@code "January"}, {@code "February"}.
*
* {@code 'b'}
* Locale-specific {@linkplain
* java.text.DateFormatSymbols#getShortMonths abbreviated month name},
* e.g. {@code "Jan"}, {@code "Feb"}.
*
* {@code 'h'}
* Same as {@code 'b'}.
*
* {@code 'A'}
* Locale-specific full name of the {@linkplain
* java.text.DateFormatSymbols#getWeekdays day of the week},
* e.g. {@code "Sunday"}, {@code "Monday"}
*
* {@code 'a'}
* Locale-specific short name of the {@linkplain
* java.text.DateFormatSymbols#getShortWeekdays day of the week},
* e.g. {@code "Sun"}, {@code "Mon"}
*
* {@code 'C'}
* Four-digit year divided by {@code 100}, formatted as two digits
* with leading zero as necessary, i.e. {@code 00 - 99}
*
* {@code 'Y'}
* Year, formatted as at least four digits with leading zeros as
* necessary, e.g. {@code 0092} equals {@code 92} CE for the Gregorian
* calendar.
*
* {@code 'y'}
* Last two digits of the year, formatted with leading zeros as
* necessary, i.e. {@code 00 - 99}.
*
* {@code 'j'}
* Day of year, formatted as three digits with leading zeros as
* necessary, e.g. {@code 001 - 366} for the Gregorian calendar.
*
* {@code 'm'}
* Month, formatted as two digits with leading zeros as necessary,
* i.e. {@code 01 - 13}.
*
* {@code 'd'}
* Day of month, formatted as two digits with leading zeros as
* necessary, i.e. {@code 01 - 31}
*
* {@code 'e'}
* Day of month, formatted as two digits, i.e. {@code 1 - 31}.
*
*
*
* The following conversion characters are used for formatting common
* date/time compositions.
*
*
*
* {@code 'R'}
* Time formatted for the 24-hour clock as {@code "%tH:%tM"}
*
* {@code 'T'}
* Time formatted for the 24-hour clock as {@code "%tH:%tM:%tS"}.
*
* {@code 'r'}
* Time formatted for the 12-hour clock as {@code "%tI:%tM:%tS %Tp"}.
* The location of the morning or afternoon marker ({@code '%Tp'}) may be
* locale-dependent.
*
* {@code 'D'}
* Date formatted as {@code "%tm/%td/%ty"}.
*
* {@code 'F'}
* ISO 8601
* complete date formatted as {@code "%tY-%tm-%td"}.
*
* {@code 'c'}
* Date and time formatted as {@code "%ta %tb %td %tT %tZ %tY"},
* e.g. {@code "Sun Jul 20 16:17:00 EDT 1969"}.
*
*
*
* Any characters not explicitly defined as date/time conversion suffixes
* are illegal and are reserved for future extensions.
*
*
Flags
*
* The following table summarizes the supported flags. y means the
* flag is supported for the indicated argument types.
*
*
*
* Flag General
* Character Integral
* Floating Point
* Date/Time
* Description
*
* '-' y
* y
* y
* y
* y
* The result will be left-justified.
*
* '#' y1
* -
* y3
* y
* -
* The result should use a conversion-dependent alternate form
*
* '+' -
* -
* y4
* y
* -
* The result will always include a sign
*
* ' ' -
* -
* y4
* y
* -
* The result will include a leading space for positive values
*
* '0' -
* -
* y
* y
* -
* The result will be zero-padded
*
* ',' -
* -
* y2
* y5
* -
* The result will include locale-specific {@linkplain
* java.text.DecimalFormatSymbols#getGroupingSeparator grouping separators}
*
* '(' -
* -
* y4
* y5
* -
* The result will enclose negative numbers in parentheses
*
*
*
* 1 Depends on the definition of {@link Formattable}.
*
*
2 For {@code 'd'} conversion only.
*
*
3 For {@code 'o'}, {@code 'x'}, and {@code 'X'}
* conversions only.
*
*
4 For {@code 'd'}, {@code 'o'}, {@code 'x'}, and
* {@code 'X'} conversions applied to {@link java.math.BigInteger BigInteger}
* or {@code 'd'} applied to {@code byte}, {@link Byte}, {@code short}, {@link
* Short}, {@code int} and {@link Integer}, {@code long}, and {@link Long}.
*
*
5 For {@code 'e'}, {@code 'E'}, {@code 'f'},
* {@code 'g'}, and {@code 'G'} conversions only.
*
*
Any characters not explicitly defined as flags are illegal and are
* reserved for future extensions.
*
*
Width
*
* The width is the minimum number of characters to be written to the
* output. For the line separator conversion, width is not applicable; if it
* is provided, an exception will be thrown.
*
*
Precision
*
* For general argument types, the precision is the maximum number of
* characters to be written to the output.
*
*
For the floating-point conversions {@code 'a'}, {@code 'A'}, {@code 'e'},
* {@code 'E'}, and {@code 'f'} the precision is the number of digits after the
* radix point. If the conversion is {@code 'g'} or {@code 'G'}, then the
* precision is the total number of digits in the resulting magnitude after
* rounding.
*
*
For character, integral, and date/time argument types and the percent
* and line separator conversions, the precision is not applicable; if a
* precision is provided, an exception will be thrown.
*
*
Argument Index
*
* The argument index is a decimal integer indicating the position of the
* argument in the argument list. The first argument is referenced by
* "{@code 1$}", the second by "{@code 2$}", etc.
*
*
Another way to reference arguments by position is to use the
* {@code '<'} ('\u003c') flag, which causes the argument for
* the previous format specifier to be re-used. For example, the following two
* statements would produce identical strings:
*
*
* Calendar c = ...;
* String s1 = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
*
* String s2 = String.format("Duke's Birthday: %1$tm %<te,%<tY", c);
*
*
*
* Details
*
* This section is intended to provide behavioral details for formatting,
* including conditions and exceptions, supported data types, localization, and
* interactions between flags, conversions, and data types. For an overview of
* formatting concepts, refer to the Summary
*
*
Any characters not explicitly defined as conversions, date/time
* conversion suffixes, or flags are illegal and are reserved for
* future extensions. Use of such a character in a format string will
* cause an {@link UnknownFormatConversionException} or {@link
* UnknownFormatFlagsException} to be thrown.
*
*
If the format specifier contains a width or precision with an invalid
* value or which is otherwise unsupported, then a {@link
* IllegalFormatWidthException} or {@link IllegalFormatPrecisionException}
* respectively will be thrown.
*
*
If a format specifier contains a conversion character that is not
* applicable to the corresponding argument, then an {@link
* IllegalFormatConversionException} will be thrown.
*
*
All specified exceptions may be thrown by any of the {@code format}
* methods of {@code Formatter} as well as by any {@code format} convenience
* methods such as {@link String#format(String,Object...) String.format} and
* {@link java.io.PrintStream#printf(String,Object...) PrintStream.printf}.
*
*
Conversions denoted by an upper-case character (i.e. {@code 'B'},
* {@code 'H'}, {@code 'S'}, {@code 'C'}, {@code 'X'}, {@code 'E'},
* {@code 'G'}, {@code 'A'}, and {@code 'T'}) are the same as those for the
* corresponding lower-case conversion characters except that the result is
* converted to upper case according to the rules of the prevailing {@link
* java.util.Locale Locale}. The result is equivalent to the following
* invocation of {@link String#toUpperCase()}
*
*
* out.toUpperCase()
*
* General
*
* The following general conversions may be applied to any argument type:
*
*
*
* {@code 'b'}
* '\u0062'
* Produces either "{@code true}" or "{@code false}" as returned by
* {@link Boolean#toString(boolean)}.
*
* If the argument is {@code null}, then the result is
* "{@code false}". If the argument is a {@code boolean} or {@link
* Boolean}, then the result is the string returned by {@link
* String#valueOf(boolean) String.valueOf()}. Otherwise, the result is
* "{@code true}".
*
*
If the {@code '#'} flag is given, then a {@link
* FormatFlagsConversionMismatchException} will be thrown.
*
*
{@code 'B'}
* '\u0042'
* The upper-case variant of {@code 'b'}.
*
* {@code 'h'}
* '\u0068'
* Produces a string representing the hash code value of the object.
*
* If the argument, arg is {@code null}, then the
* result is "{@code null}". Otherwise, the result is obtained
* by invoking {@code Integer.toHexString(arg.hashCode())}.
*
*
If the {@code '#'} flag is given, then a {@link
* FormatFlagsConversionMismatchException} will be thrown.
*
*
{@code 'H'}
* '\u0048'
* The upper-case variant of {@code 'h'}.
*
* {@code 's'}
* '\u0073'
* Produces a string.
*
* If the argument is {@code null}, then the result is
* "{@code null}". If the argument implements {@link Formattable}, then
* its {@link Formattable#formatTo formatTo} method is invoked.
* Otherwise, the result is obtained by invoking the argument's
* {@code toString()} method.
*
*
If the {@code '#'} flag is given and the argument is not a {@link
* Formattable} , then a {@link FormatFlagsConversionMismatchException}
* will be thrown.
*
*
{@code 'S'}
* '\u0053'
* The upper-case variant of {@code 's'}.
*
*
*
* The following flags apply to general conversions:
*
*
*
* {@code '-'}
* '\u002d'
* Left justifies the output. Spaces ('\u0020') will be
* added at the end of the converted value as required to fill the minimum
* width of the field. If the width is not provided, then a {@link
* MissingFormatWidthException} will be thrown. If this flag is not given
* then the output will be right-justified.
*
* {@code '#'}
* '\u0023'
* Requires the output use an alternate form. The definition of the
* form is specified by the conversion.
*
*
*
* The width is the minimum number of characters to
* be written to the
* output. If the length of the converted value is less than the width then
* the output will be padded by ' ' ('\u0020')
* until the total number of characters equals the width. The padding is on
* the left by default. If the {@code '-'} flag is given, then the padding
* will be on the right. If the width is not specified then there is no
* minimum.
*
*
The precision is the maximum number of characters to be written to the
* output. The precision is applied before the width, thus the output will be
* truncated to {@code precision} characters even if the width is greater than
* the precision. If the precision is not specified then there is no explicit
* limit on the number of characters.
*
*
Character
*
* This conversion may be applied to {@code char} and {@link Character}. It
* may also be applied to the types {@code byte}, {@link Byte},
* {@code short}, and {@link Short}, {@code int} and {@link Integer} when
* {@link Character#isValidCodePoint} returns {@code true}. If it returns
* {@code false} then an {@link IllegalFormatCodePointException} will be
* thrown.
*
*
*
* {@code 'c'}
* '\u0063'
* Formats the argument as a Unicode character as described in Unicode Character
* Representation. This may be more than one 16-bit {@code char} in
* the case where the argument represents a supplementary character.
*
* If the {@code '#'} flag is given, then a {@link
* FormatFlagsConversionMismatchException} will be thrown.
*
*
{@code 'C'}
* '\u0043'
* The upper-case variant of {@code 'c'}.
*
*
*
* The {@code '-'} flag defined for General
* conversions applies. If the {@code '#'} flag is given, then a {@link
* FormatFlagsConversionMismatchException} will be thrown.
*
*
The width is defined as for General conversions.
*
*
The precision is not applicable. If the precision is specified then an
* {@link IllegalFormatPrecisionException} will be thrown.
*
*
Numeric
*
* Numeric conversions are divided into the following categories:
*
*
*
* - Byte, Short, Integer, and Long
*
*
- BigInteger
*
*
- Float and Double
*
*
- BigDecimal
*
*
*
* Numeric types will be formatted according to the following algorithm:
*
*
Number Localization Algorithm
*
*
After digits are obtained for the integer part, fractional part, and
* exponent (as appropriate for the data type), the following transformation
* is applied:
*
*
*
* - Each digit character d in the string is replaced by a
* locale-specific digit computed relative to the current locale's
* {@linkplain java.text.DecimalFormatSymbols#getZeroDigit() zero digit}
* z; that is d - {@code '0'}
* + z.
*
*
- If a decimal separator is present, a locale-specific {@linkplain
* java.text.DecimalFormatSymbols#getDecimalSeparator decimal separator} is
* substituted.
*
*
- If the {@code ','} ('\u002c')
* flag is given, then the locale-specific {@linkplain
* java.text.DecimalFormatSymbols#getGroupingSeparator grouping separator} is
* inserted by scanning the integer part of the string from least significant
* to most significant digits and inserting a separator at intervals defined by
* the locale's {@linkplain java.text.DecimalFormat#getGroupingSize() grouping
* size}.
*
*
- If the {@code '0'} flag is given, then the locale-specific {@linkplain
* java.text.DecimalFormatSymbols#getZeroDigit() zero digits} are inserted
* after the sign character, if any, and before the first non-zero digit, until
* the length of the string is equal to the requested field width.
*
*
- If the value is negative and the {@code '('} flag is given, then a
* {@code '('} ('\u0028') is prepended and a {@code ')'}
* ('\u0029') is appended.
*
*
- If the value is negative (or floating-point negative zero) and
* {@code '('} flag is not given, then a {@code '-'} ('\u002d')
* is prepended.
*
*
- If the {@code '+'} flag is given and the value is positive or zero (or
* floating-point positive zero), then a {@code '+'} ('\u002b')
* will be prepended.
*
*
*
* If the value is NaN or positive infinity the literal strings "NaN" or
* "Infinity" respectively, will be output. If the value is negative infinity,
* then the output will be "(Infinity)" if the {@code '('} flag is given
* otherwise the output will be "-Infinity". These values are not localized.
*
*
Byte, Short, Integer, and Long
*
*
The following conversions may be applied to {@code byte}, {@link Byte},
* {@code short}, {@link Short}, {@code int} and {@link Integer},
* {@code long}, and {@link Long}.
*
*
*
* {@code 'd'}
* '\u0064'
* Formats the argument as a decimal integer. The localization algorithm is applied.
*
* If the {@code '0'} flag is given and the value is negative, then
* the zero padding will occur after the sign.
*
*
If the {@code '#'} flag is given then a {@link
* FormatFlagsConversionMismatchException} will be thrown.
*
*
{@code 'o'}
* '\u006f'
* Formats the argument as an integer in base eight. No localization
* is applied.
*
* If x is negative then the result will be an unsigned value
* generated by adding 2n to the value where {@code n} is the
* number of bits in the type as returned by the static {@code SIZE} field
* in the {@linkplain Byte#SIZE Byte}, {@linkplain Short#SIZE Short},
* {@linkplain Integer#SIZE Integer}, or {@linkplain Long#SIZE Long}
* classes as appropriate.
*
*
If the {@code '#'} flag is given then the output will always begin
* with the radix indicator {@code '0'}.
*
*
If the {@code '0'} flag is given then the output will be padded
* with leading zeros to the field width following any indication of sign.
*
*
If {@code '('}, {@code '+'}, ' ', or {@code ','} flags
* are given then a {@link FormatFlagsConversionMismatchException} will be
* thrown.
*
*
{@code 'x'}
* '\u0078'
* Formats the argument as an integer in base sixteen. No
* localization is applied.
*
* If x is negative then the result will be an unsigned value
* generated by adding 2n to the value where {@code n} is the
* number of bits in the type as returned by the static {@code SIZE} field
* in the {@linkplain Byte#SIZE Byte}, {@linkplain Short#SIZE Short},
* {@linkplain Integer#SIZE Integer}, or {@linkplain Long#SIZE Long}
* classes as appropriate.
*
*
If the {@code '#'} flag is given then the output will always begin
* with the radix indicator {@code "0x"}.
*
*
If the {@code '0'} flag is given then the output will be padded to
* the field width with leading zeros after the radix indicator or sign (if
* present).
*
*
If {@code '('}, ' ', {@code '+'}, or
* {@code ','} flags are given then a {@link
* FormatFlagsConversionMismatchException} will be thrown.
*
*
{@code 'X'}
* '\u0058'
* The upper-case variant of {@code 'x'}. The entire string
* representing the number will be converted to {@linkplain
* String#toUpperCase upper case} including the {@code 'x'} (if any) and
* all hexadecimal digits {@code 'a'} - {@code 'f'}
* ('\u0061' - '\u0066').
*
*
*
* If the conversion is {@code 'o'}, {@code 'x'}, or {@code 'X'} and
* both the {@code '#'} and the {@code '0'} flags are given, then result will
* contain the radix indicator ({@code '0'} for octal and {@code "0x"} or
* {@code "0X"} for hexadecimal), some number of zeros (based on the width),
* and the value.
*
*
If the {@code '-'} flag is not given, then the space padding will occur
* before the sign.
*
*
The following flags apply to numeric integral
* conversions:
*
*
*
* {@code '+'}
* '\u002b'
* Requires the output to include a positive sign for all positive
* numbers. If this flag is not given then only negative values will
* include a sign.
*
* If both the {@code '+'} and ' ' flags are given
* then an {@link IllegalFormatFlagsException} will be thrown.
*
*
' '
* '\u0020'
* Requires the output to include a single extra space
* ('\u0020') for non-negative values.
*
* If both the {@code '+'} and ' ' flags are given
* then an {@link IllegalFormatFlagsException} will be thrown.
*
*
{@code '0'}
* '\u0030'
* Requires the output to be padded with leading {@linkplain
* java.text.DecimalFormatSymbols#getZeroDigit zeros} to the minimum field
* width following any sign or radix indicator except when converting NaN
* or infinity. If the width is not provided, then a {@link
* MissingFormatWidthException} will be thrown.
*
* If both the {@code '-'} and {@code '0'} flags are given then an
* {@link IllegalFormatFlagsException} will be thrown.
*
*
{@code ','}
* '\u002c'
* Requires the output to include the locale-specific {@linkplain
* java.text.DecimalFormatSymbols#getGroupingSeparator group separators} as
* described in the "group" section of the
* localization algorithm.
*
* {@code '('}
* '\u0028'
* Requires the output to prepend a {@code '('}
* ('\u0028') and append a {@code ')'}
* ('\u0029') to negative values.
*
*
*
* If no flags are given the default formatting is
* as follows:
*
*
*
* - The output is right-justified within the {@code width}
*
*
- Negative numbers begin with a {@code '-'} ('\u002d')
*
*
- Positive numbers and zero do not include a sign or extra leading
* space
*
*
- No grouping separators are included
*
*
*
* The width is the minimum number of characters to
* be written to the output. This includes any signs, digits, grouping
* separators, radix indicator, and parentheses. If the length of the
* converted value is less than the width then the output will be padded by
* spaces ('\u0020') until the total number of characters equals
* width. The padding is on the left by default. If {@code '-'} flag is
* given then the padding will be on the right. If width is not specified then
* there is no minimum.
*
*
The precision is not applicable. If precision is specified then an
* {@link IllegalFormatPrecisionException} will be thrown.
*
*
BigInteger
*
*
The following conversions may be applied to {@link
* java.math.BigInteger}.
*
*
*
* {@code 'd'}
* '\u0064'
* Requires the output to be formatted as a decimal integer. The localization algorithm is applied.
*
* If the {@code '#'} flag is given {@link
* FormatFlagsConversionMismatchException} will be thrown.
*
*
{@code 'o'}
* '\u006f'
* Requires the output to be formatted as an integer in base eight.
* No localization is applied.
*
* If x is negative then the result will be a signed value
* beginning with {@code '-'} ('\u002d'). Signed output is
* allowed for this type because unlike the primitive types it is not
* possible to create an unsigned equivalent without assuming an explicit
* data-type size.
*
*
If x is positive or zero and the {@code '+'} flag is given
* then the result will begin with {@code '+'} ('\u002b').
*
*
If the {@code '#'} flag is given then the output will always begin
* with {@code '0'} prefix.
*
*
If the {@code '0'} flag is given then the output will be padded
* with leading zeros to the field width following any indication of sign.
*
*
If the {@code ','} flag is given then a {@link
* FormatFlagsConversionMismatchException} will be thrown.
*
*
{@code 'x'}
* '\u0078'
* Requires the output to be formatted as an integer in base
* sixteen. No localization is applied.
*
* If x is negative then the result will be a signed value
* beginning with {@code '-'} ('\u002d'). Signed output is
* allowed for this type because unlike the primitive types it is not
* possible to create an unsigned equivalent without assuming an explicit
* data-type size.
*
*
If x is positive or zero and the {@code '+'} flag is given
* then the result will begin with {@code '+'} ('\u002b').
*
*
If the {@code '#'} flag is given then the output will always begin
* with the radix indicator {@code "0x"}.
*
*
If the {@code '0'} flag is given then the output will be padded to
* the field width with leading zeros after the radix indicator or sign (if
* present).
*
*
If the {@code ','} flag is given then a {@link
* FormatFlagsConversionMismatchException} will be thrown.
*
*
{@code 'X'}
* '\u0058'
* The upper-case variant of {@code 'x'}. The entire string
* representing the number will be converted to {@linkplain
* String#toUpperCase upper case} including the {@code 'x'} (if any) and
* all hexadecimal digits {@code 'a'} - {@code 'f'}
* ('\u0061' - '\u0066').
*
*
*
* If the conversion is {@code 'o'}, {@code 'x'}, or {@code 'X'} and
* both the {@code '#'} and the {@code '0'} flags are given, then result will
* contain the base indicator ({@code '0'} for octal and {@code "0x"} or
* {@code "0X"} for hexadecimal), some number of zeros (based on the width),
* and the value.
*
*
If the {@code '0'} flag is given and the value is negative, then the
* zero padding will occur after the sign.
*
*
If the {@code '-'} flag is not given, then the space padding will occur
* before the sign.
*
*
All flags defined for Byte, Short, Integer, and
* Long apply. The default behavior when no flags are
* given is the same as for Byte, Short, Integer, and Long.
*
*
The specification of width is the same as
* defined for Byte, Short, Integer, and Long.
*
*
The precision is not applicable. If precision is specified then an
* {@link IllegalFormatPrecisionException} will be thrown.
*
*
Float and Double
*
*
The following conversions may be applied to {@code float}, {@link
* Float}, {@code double} and {@link Double}.
*
*
*
* {@code 'e'}
* '\u0065'
* Requires the output to be formatted using computerized scientific notation. The localization algorithm is applied.
*
* The formatting of the magnitude m depends upon its value.
*
*
If m is NaN or infinite, the literal strings "NaN" or
* "Infinity", respectively, will be output. These values are not
* localized.
*
*
If m is positive-zero or negative-zero, then the exponent
* will be {@code "+00"}.
*
*
Otherwise, the result is a string that represents the sign and
* magnitude (absolute value) of the argument. The formatting of the sign
* is described in the localization
* algorithm. The formatting of the magnitude m depends upon its
* value.
*
*
Let n be the unique integer such that 10n
* <= m < 10n+1; then let a be the
* mathematically exact quotient of m and 10n so
* that 1 <= a < 10. The magnitude is then represented as the
* integer part of a, as a single decimal digit, followed by the
* decimal separator followed by decimal digits representing the fractional
* part of a, followed by the exponent symbol {@code 'e'}
* ('\u0065'), followed by the sign of the exponent, followed
* by a representation of n as a decimal integer, as produced by the
* method {@link Long#toString(long, int)}, and zero-padded to include at
* least two digits.
*
*
The number of digits in the result for the fractional part of
* m or a is equal to the precision. If the precision is not
* specified then the default value is {@code 6}. If the precision is less
* than the number of digits which would appear after the decimal point in
* the string returned by {@link Float#toString(float)} or {@link
* Double#toString(double)} respectively, then the value will be rounded
* using the {@linkplain java.math.BigAny#ROUND_HALF_UP round half up
* algorithm}. Otherwise, zeros may be appended to reach the precision.
* For a canonical representation of the value, use {@link
* Float#toString(float)} or {@link Double#toString(double)} as
* appropriate.
*
*
If the {@code ','} flag is given, then an {@link
* FormatFlagsConversionMismatchException} will be thrown.
*
*
{@code 'E'}
* '\u0045'
* The upper-case variant of {@code 'e'}. The exponent symbol
* will be {@code 'E'} ('\u0045').
*
* {@code 'g'}
* '\u0067'
* Requires the output to be formatted in general scientific notation
* as described below. The localization
* algorithm is applied.
*
* After rounding for the precision, the formatting of the resulting
* magnitude m depends on its value.
*
*
If m is greater than or equal to 10-4 but less
* than 10precision then it is represented in decimal format.
*
*
If m is less than 10-4 or greater than or equal to
* 10precision, then it is represented in computerized scientific notation.
*
*
The total number of significant digits in m is equal to the
* precision. If the precision is not specified, then the default value is
* {@code 6}. If the precision is {@code 0}, then it is taken to be
* {@code 1}.
*
*
If the {@code '#'} flag is given then an {@link
* FormatFlagsConversionMismatchException} will be thrown.
*
*
{@code 'G'}
* '\u0047'
* The upper-case variant of {@code 'g'}.
*
* {@code 'f'}
* '\u0066'
* Requires the output to be formatted using decimal
* format. The localization algorithm is
* applied.
*
* The result is a string that represents the sign and magnitude
* (absolute value) of the argument. The formatting of the sign is
* described in the localization
* algorithm. The formatting of the magnitude m depends upon its
* value.
*
*
If m NaN or infinite, the literal strings "NaN" or
* "Infinity", respectively, will be output. These values are not
* localized.
*
*
The magnitude is formatted as the integer part of m, with no
* leading zeroes, followed by the decimal separator followed by one or
* more decimal digits representing the fractional part of m.
*
*
The number of digits in the result for the fractional part of
* m or a is equal to the precision. If the precision is not
* specified then the default value is {@code 6}. If the precision is less
* than the number of digits which would appear after the decimal point in
* the string returned by {@link Float#toString(float)} or {@link
* Double#toString(double)} respectively, then the value will be rounded
* using the {@linkplain java.math.BigAny#ROUND_HALF_UP round half up
* algorithm}. Otherwise, zeros may be appended to reach the precision.
* For a canonical representation of the value, use {@link
* Float#toString(float)} or {@link Double#toString(double)} as
* appropriate.
*
*
{@code 'a'}
* '\u0061'
* Requires the output to be formatted in hexadecimal exponential
* form. No localization is applied.
*
* The result is a string that represents the sign and magnitude
* (absolute value) of the argument x.
*
*
If x is negative or a negative-zero value then the result
* will begin with {@code '-'} ('\u002d').
*
*
If x is positive or a positive-zero value and the
* {@code '+'} flag is given then the result will begin with {@code '+'}
* ('\u002b').
*
*
The formatting of the magnitude m depends upon its value.
*
*
*
* - If the value is NaN or infinite, the literal strings "NaN" or
* "Infinity", respectively, will be output.
*
*
- If m is zero then it is represented by the string
* {@code "0x0.0p0"}.
*
*
- If m is a {@code double} value with a normalized
* representation then substrings are used to represent the significand and
* exponent fields. The significand is represented by the characters
* {@code "0x1."} followed by the hexadecimal representation of the rest
* of the significand as a fraction. The exponent is represented by
* {@code 'p'} ('\u0070') followed by a decimal string of the
* unbiased exponent as if produced by invoking {@link
* Integer#toString(int) Integer.toString} on the exponent value. If the
* precision is specified, the value is rounded to the given number of
* hexadecimal digits.
*
*
- If m is a {@code double} value with a subnormal
* representation then, unless the precision is specified to be in the range
* 1 through 12, inclusive, the significand is represented by the characters
* {@code '0x0.'} followed by the hexadecimal representation of the rest of
* the significand as a fraction, and the exponent represented by
* {@code 'p-1022'}. If the precision is in the interval
* [1, 12], the subnormal value is normalized such that it
* begins with the characters {@code '0x1.'}, rounded to the number of
* hexadecimal digits of precision, and the exponent adjusted
* accordingly. Note that there must be at least one nonzero digit in a
* subnormal significand.
*
*
*
* If the {@code '('} or {@code ','} flags are given, then a {@link
* FormatFlagsConversionMismatchException} will be thrown.
*
*
{@code 'A'}
* '\u0041'
* The upper-case variant of {@code 'a'}. The entire string
* representing the number will be converted to upper case including the
* {@code 'x'} ('\u0078') and {@code 'p'}
* ('\u0070' and all hexadecimal digits {@code 'a'} -
* {@code 'f'} ('\u0061' - '\u0066').
*
*
*
* All flags defined for Byte, Short, Integer, and
* Long apply.
*
*
If the {@code '#'} flag is given, then the decimal separator will
* always be present.
*
*
If no flags are given the default formatting
* is as follows:
*
*
*
* - The output is right-justified within the {@code width}
*
*
- Negative numbers begin with a {@code '-'}
*
*
- Positive numbers and positive zero do not include a sign or extra
* leading space
*
*
- No grouping separators are included
*
*
- The decimal separator will only appear if a digit follows it
*
*
*
* The width is the minimum number of characters
* to be written to the output. This includes any signs, digits, grouping
* separators, decimal separators, exponential symbol, radix indicator,
* parentheses, and strings representing infinity and NaN as applicable. If
* the length of the converted value is less than the width then the output
* will be padded by spaces ('\u0020') until the total number of
* characters equals width. The padding is on the left by default. If the
* {@code '-'} flag is given then the padding will be on the right. If width
* is not specified then there is no minimum.
*
*
If the conversion is {@code 'e'},
* {@code 'E'} or {@code 'f'}, then the precision is the number of digits
* after the decimal separator. If the precision is not specified, then it is
* assumed to be {@code 6}.
*
*
If the conversion is {@code 'g'} or {@code 'G'}, then the precision is
* the total number of significant digits in the resulting magnitude after
* rounding. If the precision is not specified, then the default value is
* {@code 6}. If the precision is {@code 0}, then it is taken to be
* {@code 1}.
*
*
If the conversion is {@code 'a'} or {@code 'A'}, then the precision
* is the number of hexadecimal digits after the radix point. If the
* precision is not provided, then all of the digits as returned by {@link
* Double#toHexString(double)} will be output.
*
*
BigDecimal
*
*
The following conversions may be applied {@link java.math.BigAny
* BigDecimal}.
*
*
*
* {@code 'e'}
* '\u0065'
* Requires the output to be formatted using computerized scientific notation. The localization algorithm is applied.
*
* The formatting of the magnitude m depends upon its value.
*
*
If m is positive-zero or negative-zero, then the exponent
* will be {@code "+00"}.
*
*
Otherwise, the result is a string that represents the sign and
* magnitude (absolute value) of the argument. The formatting of the sign
* is described in the localization
* algorithm. The formatting of the magnitude m depends upon its
* value.
*
*
Let n be the unique integer such that 10n
* <= m < 10n+1; then let a be the
* mathematically exact quotient of m and 10n so
* that 1 <= a < 10. The magnitude is then represented as the
* integer part of a, as a single decimal digit, followed by the
* decimal separator followed by decimal digits representing the fractional
* part of a, followed by the exponent symbol {@code 'e'}
* ('\u0065'), followed by the sign of the exponent, followed
* by a representation of n as a decimal integer, as produced by the
* method {@link Long#toString(long, int)}, and zero-padded to include at
* least two digits.
*
*
The number of digits in the result for the fractional part of
* m or a is equal to the precision. If the precision is not
* specified then the default value is {@code 6}. If the precision is
* less than the number of digits to the right of the decimal point then
* the value will be rounded using the
* {@linkplain java.math.BigAny#ROUND_HALF_UP round half up
* algorithm}. Otherwise, zeros may be appended to reach the precision.
* For a canonical representation of the value, use {@link
* BigAny#toString()}.
*
*
If the {@code ','} flag is given, then an {@link
* FormatFlagsConversionMismatchException} will be thrown.
*
*
{@code 'E'}
* '\u0045'
* The upper-case variant of {@code 'e'}. The exponent symbol
* will be {@code 'E'} ('\u0045').
*
* {@code 'g'}
* '\u0067'
* Requires the output to be formatted in general scientific notation
* as described below. The localization
* algorithm is applied.
*
* After rounding for the precision, the formatting of the resulting
* magnitude m depends on its value.
*
*
If m is greater than or equal to 10-4 but less
* than 10precision then it is represented in decimal format.
*
*
If m is less than 10-4 or greater than or equal to
* 10precision, then it is represented in computerized scientific notation.
*
*
The total number of significant digits in m is equal to the
* precision. If the precision is not specified, then the default value is
* {@code 6}. If the precision is {@code 0}, then it is taken to be
* {@code 1}.
*
*
If the {@code '#'} flag is given then an {@link
* FormatFlagsConversionMismatchException} will be thrown.
*
*
{@code 'G'}
* '\u0047'
* The upper-case variant of {@code 'g'}.
*
* {@code 'f'}
* '\u0066'
* Requires the output to be formatted using decimal
* format. The localization algorithm is
* applied.
*
* The result is a string that represents the sign and magnitude
* (absolute value) of the argument. The formatting of the sign is
* described in the localization
* algorithm. The formatting of the magnitude m depends upon its
* value.
*
*
The magnitude is formatted as the integer part of m, with no
* leading zeroes, followed by the decimal separator followed by one or
* more decimal digits representing the fractional part of m.
*
*
The number of digits in the result for the fractional part of
* m or a is equal to the precision. If the precision is not
* specified then the default value is {@code 6}. If the precision is
* less than the number of digits to the right of the decimal point
* then the value will be rounded using the
* {@linkplain java.math.BigAny#ROUND_HALF_UP round half up
* algorithm}. Otherwise, zeros may be appended to reach the precision.
* For a canonical representation of the value, use {@link
* BigAny#toString()}.
*
*
*
* All flags defined for Byte, Short, Integer, and
* Long apply.
*
*
If the {@code '#'} flag is given, then the decimal separator will
* always be present.
*
*
The default behavior when no flags are
* given is the same as for Float and Double.
*
*
The specification of width and precision is the same as defined for Float and
* Double.
*
*
Date/Time
*
* This conversion may be applied to {@code long}, {@link Long}, {@link
* Calendar}, {@link Date} and {@link TemporalAccessor TemporalAccessor}
*
*
*
* {@code 't'}
* '\u0074'
* Prefix for date and time conversion characters.
* {@code 'T'}
* '\u0054'
* The upper-case variant of {@code 't'}.
*
*
*
* The following date and time conversion character suffixes are defined
* for the {@code 't'} and {@code 'T'} conversions. The types are similar to
* but not completely identical to those defined by GNU {@code date} and
* POSIX {@code strftime(3c)}. Additional conversion types are provided to
* access Java-specific functionality (e.g. {@code 'L'} for milliseconds
* within the second).
*
*
The following conversion characters are used for formatting times:
*
*
*
* {@code 'H'}
* '\u0048'
* Hour of the day for the 24-hour clock, formatted as two digits with
* a leading zero as necessary i.e. {@code 00 - 23}. {@code 00}
* corresponds to midnight.
*
* {@code 'I'}
* '\u0049'
* Hour for the 12-hour clock, formatted as two digits with a leading
* zero as necessary, i.e. {@code 01 - 12}. {@code 01} corresponds to
* one o'clock (either morning or afternoon).
*
* {@code 'k'}
* '\u006b'
* Hour of the day for the 24-hour clock, i.e. {@code 0 - 23}.
* {@code 0} corresponds to midnight.
*
* {@code 'l'}
* '\u006c'
* Hour for the 12-hour clock, i.e. {@code 1 - 12}. {@code 1}
* corresponds to one o'clock (either morning or afternoon).
*
* {@code 'M'}
* '\u004d'
* Minute within the hour formatted as two digits with a leading zero
* as necessary, i.e. {@code 00 - 59}.
*
* {@code 'S'}
* '\u0053'
* Seconds within the minute, formatted as two digits with a leading
* zero as necessary, i.e. {@code 00 - 60} ("{@code 60}" is a special
* value required to support leap seconds).
*
* {@code 'L'}
* '\u004c'
* Millisecond within the second formatted as three digits with
* leading zeros as necessary, i.e. {@code 000 - 999}.
*
* {@code 'N'}
* '\u004e'
* Nanosecond within the second, formatted as nine digits with leading
* zeros as necessary, i.e. {@code 000000000 - 999999999}. The precision
* of this value is limited by the resolution of the underlying operating
* system or hardware.
*
* {@code 'p'}
* '\u0070'
* Locale-specific {@linkplain
* java.text.DateFormatSymbols#getAmPmStrings morning or afternoon} marker
* in lower case, e.g."{@code am}" or "{@code pm}". Use of the
* conversion prefix {@code 'T'} forces this output to upper case. (Note
* that {@code 'p'} produces lower-case output. This is different from
* GNU {@code date} and POSIX {@code strftime(3c)} which produce
* upper-case output.)
*
* {@code 'z'}
* '\u007a'
* RFC 822
* style numeric time zone offset from GMT, e.g. {@code -0800}. This
* value will be adjusted as necessary for Daylight Saving Time. For
* {@code long}, {@link Long}, and {@link Date} the time zone used is
* the {@linkplain TimeZone#getDefault() default time zone} for this
* instance of the Java virtual machine.
*
* {@code 'Z'}
* '\u005a'
* A string representing the abbreviation for the time zone. This
* value will be adjusted as necessary for Daylight Saving Time. For
* {@code long}, {@link Long}, and {@link Date} the time zone used is
* the {@linkplain TimeZone#getDefault() default time zone} for this
* instance of the Java virtual machine. The Formatter's locale will
* supersede the locale of the argument (if any).
*
* {@code 's'}
* '\u0073'
* Seconds since the beginning of the epoch starting at 1 January 1970
* {@code 00:00:00} UTC, i.e. {@code Long.MIN_VALUE/1000} to
* {@code Long.MAX_VALUE/1000}.
*
* {@code 'Q'}
* '\u004f'
* Milliseconds since the beginning of the epoch starting at 1 January
* 1970 {@code 00:00:00} UTC, i.e. {@code Long.MIN_VALUE} to
* {@code Long.MAX_VALUE}. The precision of this value is limited by
* the resolution of the underlying operating system or hardware.
*
*
*
* The following conversion characters are used for formatting dates:
*
*
*
* {@code 'B'}
* '\u0042'
* Locale-specific {@linkplain java.text.DateFormatSymbols#getMonths
* full month name}, e.g. {@code "January"}, {@code "February"}.
*
* {@code 'b'}
* '\u0062'
* Locale-specific {@linkplain
* java.text.DateFormatSymbols#getShortMonths abbreviated month name},
* e.g. {@code "Jan"}, {@code "Feb"}.
*
* {@code 'h'}
* '\u0068'
* Same as {@code 'b'}.
*
* {@code 'A'}
* '\u0041'
* Locale-specific full name of the {@linkplain
* java.text.DateFormatSymbols#getWeekdays day of the week},
* e.g. {@code "Sunday"}, {@code "Monday"}
*
* {@code 'a'}
* '\u0061'
* Locale-specific short name of the {@linkplain
* java.text.DateFormatSymbols#getShortWeekdays day of the week},
* e.g. {@code "Sun"}, {@code "Mon"}
*
* {@code 'C'}
* '\u0043'
* Four-digit year divided by {@code 100}, formatted as two digits
* with leading zero as necessary, i.e. {@code 00 - 99}
*
* {@code 'Y'}
* '\u0059' Year, formatted to at least
* four digits with leading zeros as necessary, e.g. {@code 0092} equals
* {@code 92} CE for the Gregorian calendar.
*
* {@code 'y'}
* '\u0079'
* Last two digits of the year, formatted with leading zeros as
* necessary, i.e. {@code 00 - 99}.
*
* {@code 'j'}
* '\u006a'
* Day of year, formatted as three digits with leading zeros as
* necessary, e.g. {@code 001 - 366} for the Gregorian calendar.
* {@code 001} corresponds to the first day of the year.
*
* {@code 'm'}
* '\u006d'
* Month, formatted as two digits with leading zeros as necessary,
* i.e. {@code 01 - 13}, where "{@code 01}" is the first month of the
* year and ("{@code 13}" is a special value required to support lunar
* calendars).
*
* {@code 'd'}
* '\u0064'
* Day of month, formatted as two digits with leading zeros as
* necessary, i.e. {@code 01 - 31}, where "{@code 01}" is the first day
* of the month.
*
* {@code 'e'}
* '\u0065'
* Day of month, formatted as two digits, i.e. {@code 1 - 31} where
* "{@code 1}" is the first day of the month.
*
*
*
* The following conversion characters are used for formatting common
* date/time compositions.
*
*
*
* {@code 'R'}
* '\u0052'
* Time formatted for the 24-hour clock as {@code "%tH:%tM"}
*
* {@code 'T'}
* '\u0054'
* Time formatted for the 24-hour clock as {@code "%tH:%tM:%tS"}.
*
* {@code 'r'}
* '\u0072'
* Time formatted for the 12-hour clock as {@code "%tI:%tM:%tS
* %Tp"}. The location of the morning or afternoon marker
* ({@code '%Tp'}) may be locale-dependent.
*
* {@code 'D'}
* '\u0044'
* Date formatted as {@code "%tm/%td/%ty"}.
*
* {@code 'F'}
* '\u0046'
* ISO 8601
* complete date formatted as {@code "%tY-%tm-%td"}.
*
* {@code 'c'}
* '\u0063'
* Date and time formatted as {@code "%ta %tb %td %tT %tZ %tY"},
* e.g. {@code "Sun Jul 20 16:17:00 EDT 1969"}.
*
*
*
* The {@code '-'} flag defined for General
* conversions applies. If the {@code '#'} flag is given, then a {@link
* FormatFlagsConversionMismatchException} will be thrown.
*
*
The width is the minimum number of characters to
* be written to the output. If the length of the converted value is less than
* the {@code width} then the output will be padded by spaces
* ('\u0020') until the total number of characters equals width.
* The padding is on the left by default. If the {@code '-'} flag is given
* then the padding will be on the right. If width is not specified then there
* is no minimum.
*
*
The precision is not applicable. If the precision is specified then an
* {@link IllegalFormatPrecisionException} will be thrown.
*
*
Percent
*
* The conversion does not correspond to any argument.
*
*
*
* {@code '%'}
* The result is a literal {@code '%'} ('\u0025')
*
* The width is the minimum number of characters to
* be written to the output including the {@code '%'}. If the length of the
* converted value is less than the {@code width} then the output will be
* padded by spaces ('\u0020') until the total number of
* characters equals width. The padding is on the left. If width is not
* specified then just the {@code '%'} is output.
*
*
The {@code '-'} flag defined for General
* conversions applies. If any other flags are provided, then a
* {@link FormatFlagsConversionMismatchException} will be thrown.
*
*
The precision is not applicable. If the precision is specified an
* {@link IllegalFormatPrecisionException} will be thrown.
*
*
*
* Line Separator
*
* The conversion does not correspond to any argument.
*
*
*
* {@code 'n'}
* the platform-specific line separator as returned by {@link
* System#getProperty System.getProperty("line.separator")}.
*
*
*
* Flags, width, and precision are not applicable. If any are provided an
* {@link IllegalFormatFlagsException}, {@link IllegalFormatWidthException},
* and {@link IllegalFormatPrecisionException}, respectively will be thrown.
*
*
Argument Index
*
* Format specifiers can reference arguments in three ways:
*
*
*
* - Explicit indexing is used when the format specifier contains an
* argument index. The argument index is a decimal integer indicating the
* position of the argument in the argument list. The first argument is
* referenced by "{@code 1$}", the second by "{@code 2$}", etc. An argument
* may be referenced more than once.
*
*
For example:
*
*
* formatter.format("%4$s %3$s %2$s %1$s %4$s %3$s %2$s %1$s",
* "a", "b", "c", "d")
* // -> "d c b a d c b a"
*
*
* - Relative indexing is used when the format specifier contains a
* {@code '<'} ('\u003c') flag which causes the argument for
* the previous format specifier to be re-used. If there is no previous
* argument, then a {@link MissingFormatArgumentException} is thrown.
*
*
* formatter.format("%s %s %<s %<s", "a", "b", "c", "d")
* // -> "a b b b"
* // "c" and "d" are ignored because they are not referenced
*
*
* - Ordinary indexing is used when the format specifier contains
* neither an argument index nor a {@code '<'} flag. Each format specifier
* which uses ordinary indexing is assigned a sequential implicit index into
* argument list which is independent of the indices used by explicit or
* relative indexing.
*
*
* formatter.format("%s %s %s %s", "a", "b", "c", "d")
* // -> "a b c d"
*
*
*
*
* It is possible to have a format string which uses all forms of indexing,
* for example:
*
*
* formatter.format("%2$s %s %<s %s", "a", "b", "c", "d")
* // -> "b a a b"
* // "c" and "d" are ignored because they are not referenced
*
*
* The maximum number of arguments is limited by the maximum dimension of a
* Java array as defined by
* The Java™ Virtual Machine Specification.
* If the argument index is does not correspond to an
* available argument, then a {@link MissingFormatArgumentException} is thrown.
*
*
If there are more arguments than format specifiers, the extra arguments
* are ignored.
*
*
Unless otherwise specified, passing a {@code null} argument to any
* method or constructor in this class will cause a {@link
* NullPointerException} to be thrown.
*
* @author Iris Clark
* @since 1.5
*/
public final class Formatter implements Closeable, Flushable
{
private Appendable a;
private IOException lastException;
private static double scaleUp;
// 1 (sign) + 19 (max # sig digits) + 1 ('.') + 1 ('e') + 1 (sign)
// + 3 (max # exp digits) + 4 (error) = 30
private static final int MAX_FD_CHARS= 30;
/**
* Returns a charset object for the given charset name.
* @throws NullPointerException is csn is null
* @throws UnsupportedEncodingException if the charset is not supported
*/
private static Charset toCharset(String csn) throws UnsupportedEncodingException
{
Objects.requireNonNull(csn, "charsetName");
try
{
return Charset.forName(csn);
}
catch (IllegalCharsetNameException | UnsupportedCharsetException unused)
{
// UnsupportedEncodingException should be thrown
throw new UnsupportedEncodingException(csn);
}
}
private static char getZero(Locale l)
{
if ((l != null) && !l.equals(Locale.US))
{
DecimalFormatSymbols dfs= DecimalFormatSymbols.getInstance(l);
return dfs.getZeroDigit();
}
else
{
return '0';
}
}
/**
* Returns the destination for the output.
*
* @return The destination for the output
*
* @throws FormatterClosedException
* If this formatter has been closed by invoking its {@link
* #close()} method
*/
public Appendable out()
{
ensureOpen();
return a;
}
/**
* Returns the result of invoking {@code toString()} on the destination
* for the output. For example, the following code formats text into a
* {@link StringBuilder} then retrieves the resultant string:
*
*
* Formatter f = new Formatter();
* f.format("Last reboot at %tc", lastRebootDate);
* String s = f.toString();
* // -> s == "Last reboot at Sat Jan 01 00:00:00 PST 2000"
*
*
* An invocation of this method behaves in exactly the same way as the
* invocation
*
*
* out().toString()
*
* Depending on the specification of {@code toString} for the {@link
* Appendable}, the returned string may or may not contain the characters
* written to the destination. For instance, buffers typically return
* their contents in {@code toString()}, but streams cannot since the
* data is discarded.
*
* @return The result of invoking {@code toString()} on the destination
* for the output
*
* @throws FormatterClosedException
* If this formatter has been closed by invoking its {@link
* #close()} method
*/
public String toString()
{
// ensureOpen();
// return a.toString();
return "";
}
/**
* Flushes this formatter. If the destination implements the {@link
* java.io.Flushable} interface, its {@code flush} method will be invoked.
*
*
Flushing a formatter writes any buffered output in the destination
* to the underlying stream.
*
* @throws FormatterClosedException
* If this formatter has been closed by invoking its {@link
* #close()} method
*/
public void flush()
{
ensureOpen();
if (a instanceof Flushable)
{
try
{
((Flushable) a).flush();
}
catch (IOException ioe)
{
lastException= ioe;
}
}
}
/**
* Closes this formatter. If the destination implements the {@link
* java.io.Closeable} interface, its {@code close} method will be invoked.
*
*
Closing a formatter allows it to release resources it may be holding
* (such as open files). If the formatter is already closed, then invoking
* this method has no effect.
*
*
Attempting to invoke any methods except {@link #ioException()} in
* this formatter after it has been closed will result in a {@link
* FormatterClosedException}.
*/
public void close()
{
if (a == null)
return;
try
{
if (a instanceof Closeable)
((Closeable) a).close();
}
catch (IOException ioe)
{
lastException= ioe;
}
finally
{
a= null;
}
}
private void ensureOpen()
{
if (a == null)
throw new FormatterClosedException();
}
/**
* Returns the {@code IOException} last thrown by this formatter's {@link
* Appendable}.
*
*
If the destination's {@code append()} method never throws
* {@code IOException}, then this method will always return {@code null}.
*
* @return The last exception thrown by the Appendable or {@code null} if
* no such exception exists.
*/
public IOException ioException()
{
return lastException;
}
/**
* Writes a formatted string to this object's destination using the
* specified format string and arguments. The locale used is the one
* defined during the construction of this formatter.
*
* @param format
* A format string as described in Format string
* syntax.
*
* @param args
* Arguments referenced by the format specifiers in the format
* string. If there are more arguments than format specifiers, the
* extra arguments are ignored. The maximum number of arguments is
* limited by the maximum dimension of a Java array as defined by
* The Java™ Virtual Machine Specification.
*
* @throws IllegalFormatException
* If a format string contains an illegal syntax, a format
* specifier that is incompatible with the given arguments,
* insufficient arguments given the format string, or other
* illegal conditions. For specification of all possible
* formatting errors, see the Details
* section of the formatter class specification.
*
* @throws FormatterClosedException
* If this formatter has been closed by invoking its {@link
* #close()} method
*
* @return This formatter
*/
public Formatter format(String format, Object... args)
{
return format(new Locale(""), format, args);
}
/**
* Writes a formatted string to this object's destination using the
* specified locale, format string, and arguments.
*
* @param l
* The {@linkplain java.util.Locale locale} to apply during
* formatting. If {@code l} is {@code null} then no localization
* is applied. This does not change this object's locale that was
* set during construction.
*
* @param format
* A format string as described in Format string
* syntax
*
* @param args
* Arguments referenced by the format specifiers in the format
* string. If there are more arguments than format specifiers, the
* extra arguments are ignored. The maximum number of arguments is
* limited by the maximum dimension of a Java array as defined by
* The Java™ Virtual Machine Specification.
*
* @throws IllegalFormatException
* If a format string contains an illegal syntax, a format
* specifier that is incompatible with the given arguments,
* insufficient arguments given the format string, or other
* illegal conditions. For specification of all possible
* formatting errors, see the Details
* section of the formatter class specification.
*
* @throws FormatterClosedException
* If this formatter has been closed by invoking its {@link
* #close()} method
*
* @return This formatter
*/
public Formatter format(Locale l, String format, Object... args)
{
// ensureOpen();
//
// // index of last argument referenced
// int last= -1;
// // last ordinary index
// int lasto= -1;
//
// FormatString[] fsa= parse(format);
// for (int i= 0; i < fsa.length; i++)
// {
// FormatString fs= fsa[i];
// int index= fs.index();
// try
// {
// switch (index)
// {
// case -2: // fixed string, "%n", or "%%"
// fs.print(null, l);
// break;
// case -1: // relative index
// if (last < 0 || (args != null && last > args.length - 1))
// throw new MissingFormatArgumentException(fs.toString());
// fs.print((args == null ? null : args[last]), l);
// break;
// case 0: // ordinary index
// lasto++;
// last= lasto;
// if (args != null && lasto > args.length - 1)
// throw new MissingFormatArgumentException(fs.toString());
// fs.print((args == null ? null : args[lasto]), l);
// break;
// default: // explicit index
// last= index - 1;
// if (args != null && last > args.length - 1)
// throw new MissingFormatArgumentException(fs.toString());
// fs.print((args == null ? null : args[last]), l);
// break;
// }
// }
// catch (IOException x)
// {
// lastException= x;
// }
// }
return this;
}
// %[argument_index$][flags][width][.precision][t]conversion
private static final String formatSpecifier= "%(\\d+\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])";
private static Pattern fsPattern= Pattern.compile(formatSpecifier);
/**
* Finds format specifiers in the format string.
*/
private FormatString[] parse(String s)
{
return new FormatString[0];
}
private static void checkText(String s, int start, int end)
{
for (int i= start; i < end; i++)
{
// Any '%' found in the region starts an invalid format specifier.
if (s.charAt(i) == '%')
{
char c= (i == end - 1) ? '%' : s.charAt(i + 1);
throw new UnknownFormatConversionException(String.valueOf(c));
}
}
}
private interface FormatString
{
int index();
void print(Object arg, Locale l) throws IOException;
String toString();
}
private class FixedString implements FormatString
{
private String s;
FixedString(String s)
{
this.s= s;
}
public int index()
{
return -2;
}
public void print(Object arg, Locale l) throws IOException
{
a.append(s);
}
public String toString()
{
return s;
}
}
/**
* Enum for {@code BigDecimal} formatting.
*/
public enum BigDecimalLayoutForm
{
/**
* Format the {@code BigDecimal} in computerized scientific notation.
*/
SCIENTIFIC,
/**
* Format the {@code BigDecimal} as a decimal number.
*/
DECIMAL_FLOAT
};
private static class Flags
{
private int flags;
static final Flags NONE= new Flags(0); // ''
// duplicate declarations from Formattable.java
static final Flags LEFT_JUSTIFY= new Flags(1 << 0); // '-'
static final Flags UPPERCASE= new Flags(1 << 1); // '^'
static final Flags ALTERNATE= new Flags(1 << 2); // '#'
// numerics
static final Flags PLUS= new Flags(1 << 3); // '+'
static final Flags LEADING_SPACE= new Flags(1 << 4); // ' '
static final Flags ZERO_PAD= new Flags(1 << 5); // '0'
static final Flags GROUP= new Flags(1 << 6); // ','
static final Flags PARENTHESES= new Flags(1 << 7); // '('
// indexing
static final Flags PREVIOUS= new Flags(1 << 8); // '<'
private Flags(int f)
{
flags= f;
}
public int valueOf()
{
return flags;
}
public boolean contains(Flags f)
{
return (flags & f.valueOf()) == f.valueOf();
}
public Flags dup()
{
return new Flags(flags);
}
private Flags add(Flags f)
{
flags|= f.valueOf();
return this;
}
public Flags remove(Flags f)
{
flags&= ~f.valueOf();
return this;
}
public static Flags parse(String s)
{
char[] ca= s.toCharArray();
Flags f= new Flags(0);
for (int i= 0; i < ca.length; i++)
{
Flags v= parse(ca[i]);
if (f.contains(v))
throw new DuplicateFormatFlagsException(v.toString());
f.add(v);
}
return f;
}
// parse those flags which may be provided by users
private static Flags parse(char c)
{
switch (c)
{
case '-':
return LEFT_JUSTIFY;
case '#':
return ALTERNATE;
case '+':
return PLUS;
case ' ':
return LEADING_SPACE;
case '0':
return ZERO_PAD;
case ',':
return GROUP;
case '(':
return PARENTHESES;
case '<':
return PREVIOUS;
default:
throw new UnknownFormatFlagsException(String.valueOf(c));
}
}
// Returns a string representation of the current {@code Flags}.
public static String toString(Flags f)
{
return f.toString();
}
public String toString()
{
StringBuilder sb= new StringBuilder();
if (contains(LEFT_JUSTIFY))
sb.append('-');
if (contains(UPPERCASE))
sb.append('^');
if (contains(ALTERNATE))
sb.append('#');
if (contains(PLUS))
sb.append('+');
if (contains(LEADING_SPACE))
sb.append(' ');
if (contains(ZERO_PAD))
sb.append('0');
if (contains(GROUP))
sb.append(',');
if (contains(PARENTHESES))
sb.append('(');
if (contains(PREVIOUS))
sb.append('<');
return sb.toString();
}
}
private static class Conversion
{
// Byte, Short, Integer, Long, BigInteger
// (and associated primitives due to autoboxing)
static final char DECIMAL_INTEGER= 'd';
static final char OCTAL_INTEGER= 'o';
static final char HEXADECIMAL_INTEGER= 'x';
static final char HEXADECIMAL_INTEGER_UPPER= 'X';
// Float, Double, BigDecimal
// (and associated primitives due to autoboxing)
static final char SCIENTIFIC= 'e';
static final char SCIENTIFIC_UPPER= 'E';
static final char GENERAL= 'g';
static final char GENERAL_UPPER= 'G';
static final char DECIMAL_FLOAT= 'f';
static final char HEXADECIMAL_FLOAT= 'a';
static final char HEXADECIMAL_FLOAT_UPPER= 'A';
// Character, Byte, Short, Integer
// (and associated primitives due to autoboxing)
static final char CHARACTER= 'c';
static final char CHARACTER_UPPER= 'C';
// java.util.Date, java.util.Calendar, long
static final char DATE_TIME= 't';
static final char DATE_TIME_UPPER= 'T';
// if (arg.TYPE != boolean) return boolean
// if (arg != null) return true; else return false;
static final char BOOLEAN= 'b';
static final char BOOLEAN_UPPER= 'B';
// if (arg instanceof Formattable) arg.formatTo()
// else arg.toString();
static final char STRING= 's';
static final char STRING_UPPER= 'S';
// arg.hashCode()
static final char HASHCODE= 'h';
static final char HASHCODE_UPPER= 'H';
static final char LINE_SEPARATOR= 'n';
static final char PERCENT_SIGN= '%';
static boolean isValid(char c)
{
return (isGeneral(c) || isInteger(c) || isFloat(c) || isText(c) || c == 't' || isCharacter(c));
}
// Returns true iff the Conversion is applicable to all objects.
static boolean isGeneral(char c)
{
switch (c)
{
case BOOLEAN:
case BOOLEAN_UPPER:
case STRING:
case STRING_UPPER:
case HASHCODE:
case HASHCODE_UPPER:
return true;
default:
return false;
}
}
// Returns true iff the Conversion is applicable to character.
static boolean isCharacter(char c)
{
switch (c)
{
case CHARACTER:
case CHARACTER_UPPER:
return true;
default:
return false;
}
}
// Returns true iff the Conversion is an integer type.
static boolean isInteger(char c)
{
switch (c)
{
case DECIMAL_INTEGER:
case OCTAL_INTEGER:
case HEXADECIMAL_INTEGER:
case HEXADECIMAL_INTEGER_UPPER:
return true;
default:
return false;
}
}
// Returns true iff the Conversion is a floating-point type.
static boolean isFloat(char c)
{
switch (c)
{
case SCIENTIFIC:
case SCIENTIFIC_UPPER:
case GENERAL:
case GENERAL_UPPER:
case DECIMAL_FLOAT:
case HEXADECIMAL_FLOAT:
case HEXADECIMAL_FLOAT_UPPER:
return true;
default:
return false;
}
}
// Returns true iff the Conversion does not require an argument
static boolean isText(char c)
{
switch (c)
{
case LINE_SEPARATOR:
case PERCENT_SIGN:
return true;
default:
return false;
}
}
}
private static class DateTime
{
static final char HOUR_OF_DAY_0= 'H'; // (00 - 23)
static final char HOUR_0= 'I'; // (01 - 12)
static final char HOUR_OF_DAY= 'k'; // (0 - 23) -- like H
static final char HOUR= 'l'; // (1 - 12) -- like I
static final char MINUTE= 'M'; // (00 - 59)
static final char NANOSECOND= 'N'; // (000000000 - 999999999)
static final char MILLISECOND= 'L'; // jdk, not in gnu (000 - 999)
static final char MILLISECOND_SINCE_EPOCH= 'Q'; // (0 - 99...?)
static final char AM_PM= 'p'; // (am or pm)
static final char SECONDS_SINCE_EPOCH= 's'; // (0 - 99...?)
static final char SECOND= 'S'; // (00 - 60 - leap second)
static final char TIME= 'T'; // (24 hour hh:mm:ss)
static final char ZONE_NUMERIC= 'z'; // (-1200 - +1200) - ls minus?
static final char ZONE= 'Z'; // (symbol)
// Date
static final char NAME_OF_DAY_ABBREV= 'a'; // 'a'
static final char NAME_OF_DAY= 'A'; // 'A'
static final char NAME_OF_MONTH_ABBREV= 'b'; // 'b'
static final char NAME_OF_MONTH= 'B'; // 'B'
static final char CENTURY= 'C'; // (00 - 99)
static final char DAY_OF_MONTH_0= 'd'; // (01 - 31)
static final char DAY_OF_MONTH= 'e'; // (1 - 31) -- like d
// * static final char ISO_WEEK_OF_YEAR_2 = 'g'; // cross %y %V
// * static final char ISO_WEEK_OF_YEAR_4 = 'G'; // cross %Y %V
static final char NAME_OF_MONTH_ABBREV_X= 'h'; // -- same b
static final char DAY_OF_YEAR= 'j'; // (001 - 366)
static final char MONTH= 'm'; // (01 - 12)
// * static final char DAY_OF_WEEK_1 = 'u'; // (1 - 7) Monday
// * static final char WEEK_OF_YEAR_SUNDAY = 'U'; // (0 - 53) Sunday+
// * static final char WEEK_OF_YEAR_MONDAY_01 = 'V'; // (01 - 53) Monday+
// * static final char DAY_OF_WEEK_0 = 'w'; // (0 - 6) Sunday
// * static final char WEEK_OF_YEAR_MONDAY = 'W'; // (00 - 53) Monday
static final char YEAR_2= 'y'; // (00 - 99)
static final char YEAR_4= 'Y'; // (0000 - 9999)
// Composites
static final char TIME_12_HOUR= 'r'; // (hh:mm:ss [AP]M)
static final char TIME_24_HOUR= 'R'; // (hh:mm same as %H:%M)
// * static final char LOCALE_TIME = 'X'; // (%H:%M:%S) - parse format?
static final char DATE_TIME= 'c';
// (Sat Nov 04 12:02:33 EST 1999)
static final char DATE= 'D'; // (mm/dd/yy)
static final char ISO_STANDARD_DATE= 'F'; // (%Y-%m-%d)
// * static final char LOCALE_DATE = 'x'; // (mm/dd/yy)
static boolean isValid(char c)
{
switch (c)
{
case HOUR_OF_DAY_0:
case HOUR_0:
case HOUR_OF_DAY:
case HOUR:
case MINUTE:
case NANOSECOND:
case MILLISECOND:
case MILLISECOND_SINCE_EPOCH:
case AM_PM:
case SECONDS_SINCE_EPOCH:
case SECOND:
case TIME:
case ZONE_NUMERIC:
case ZONE:
// Date
case NAME_OF_DAY_ABBREV:
case NAME_OF_DAY:
case NAME_OF_MONTH_ABBREV:
case NAME_OF_MONTH:
case CENTURY:
case DAY_OF_MONTH_0:
case DAY_OF_MONTH:
// * case ISO_WEEK_OF_YEAR_2:
// * case ISO_WEEK_OF_YEAR_4:
case NAME_OF_MONTH_ABBREV_X:
case DAY_OF_YEAR:
case MONTH:
// * case DAY_OF_WEEK_1:
// * case WEEK_OF_YEAR_SUNDAY:
// * case WEEK_OF_YEAR_MONDAY_01:
// * case DAY_OF_WEEK_0:
// * case WEEK_OF_YEAR_MONDAY:
case YEAR_2:
case YEAR_4:
// Composites
case TIME_12_HOUR:
case TIME_24_HOUR:
// * case LOCALE_TIME:
case DATE_TIME:
case DATE:
case ISO_STANDARD_DATE:
// * case LOCALE_DATE:
return true;
default:
return false;
}
}
}
}