KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > util > Formatter


1 /*
2  * @(#)Formatter.java 1.16 05/01/04
3  *
4  * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.util;
9
10 import java.io.BufferedWriter JavaDoc;
11 import java.io.Closeable JavaDoc;
12 import java.io.IOException JavaDoc;
13 import java.io.File JavaDoc;
14 import java.io.FileOutputStream JavaDoc;
15 import java.io.FileNotFoundException JavaDoc;
16 import java.io.Flushable JavaDoc;
17 import java.io.OutputStream JavaDoc;
18 import java.io.OutputStreamWriter JavaDoc;
19 import java.io.PrintStream JavaDoc;
20 import java.io.UnsupportedEncodingException JavaDoc;
21 import java.math.BigDecimal JavaDoc;
22 import java.math.BigInteger JavaDoc;
23 import java.math.MathContext JavaDoc;
24 import java.nio.charset.Charset JavaDoc;
25 import java.text.DateFormatSymbols JavaDoc;
26 import java.text.DecimalFormat JavaDoc;
27 import java.text.DecimalFormatSymbols JavaDoc;
28 import java.text.NumberFormat JavaDoc;
29 import java.util.Calendar JavaDoc;
30 import java.util.Date JavaDoc;
31 import java.util.Locale JavaDoc;
32 import java.util.regex.Matcher JavaDoc;
33 import java.util.regex.Pattern JavaDoc;
34
35 import sun.misc.FpUtils;
36 import sun.misc.DoubleConsts;
37 import sun.misc.FormattedFloatingDecimal;
38
39 /**
40  * An interpreter for printf-style format strings. This class provides support
41  * for layout justification and alignment, common formats for numeric, string,
42  * and date/time data, and locale-specific output. Common Java types such as
43  * <tt>byte</tt>, {@link java.math.BigDecimal BigDecimal}, and {@link Calendar}
44  * are supported. Limited formatting customization for arbitrary user types is
45  * provided through the {@link Formattable} interface.
46  *
47  * <p> Formatters are not necessarily safe for multithreaded access. Thread
48  * safety is optional and is the responsibility of users of methods in this
49  * class.
50  *
51  * <p> Formatted printing for the Java language is heavily inspired by C's
52  * <tt>printf</tt>. Although the format strings are similar to C, some
53  * customizations have been made to accommodate the Java language and exploit
54  * some of its features. Also, Java formatting is more strict than C's; for
55  * example, if a conversion is incompatible with a flag, an exception will be
56  * thrown. In C inapplicable flags are silently ignored. The format strings
57  * are thus intended to be recognizable to C programmers but not necessarily
58  * completely compatible with those in C.
59  *
60  * <p> Examples of expected usage:
61  *
62  * <blockquote><pre>
63  * StringBuilder sb = new StringBuilder();
64  * // Send all output to the Appendable object sb
65  * Formatter formatter = new Formatter(sb, Locale.US);
66  *
67  * // Explicit argument indices may be used to re-order output.
68  * formatter.format("%4$2s %3$2s %2$2s %1$2s", "a", "b", "c", "d")
69  * // -> " d c b a"
70  *
71  * // Optional locale as the first argument can be used to get
72  * // locale-specific formatting of numbers. The precision and width can be
73  * // given to round and align the value.
74  * formatter.format(Locale.FRANCE, "e = %+10.4f", Math.E);
75  * // -> "e = +2,7183"
76  *
77  * // The '(' numeric flag may be used to format negative numbers with
78  * // parentheses rather than a minus sign. Group separators are
79  * // automatically inserted.
80  * formatter.format("Amount gained or lost since last statement: $ %(,.2f",
81  * balanceDelta);
82  * // -> "Amount gained or lost since last statement: $ (6,217.58)"
83  * </pre></blockquote>
84  *
85  * <p> Convenience methods for common formatting requests exist as illustrated
86  * by the following invocations:
87  *
88  * <blockquote><pre>
89  * // Writes a formatted string to System.out.
90  * System.out.format("Local time: %tT", Calendar.getInstance());
91  * // -> "Local time: 13:34:18"
92  *
93  * // Writes formatted output to System.err.
94  * System.err.printf("Unable to open file '%1$s': %2$s",
95  * fileName, exception.getMessage());
96  * // -> "Unable to open file 'food': No such file or directory"
97  * </pre></blockquote>
98  *
99  * <p> Like C's <tt>sprintf(3)</tt>, Strings may be formatted using the static
100  * method {@link String#format(String,Object...) String.format}:
101  *
102  * <blockquote><pre>
103  * // Format a string containing a date.
104  * import java.util.Calendar;
105  * import java.util.GregorianCalendar;
106  * import static java.util.Calendar.*;
107  *
108  * Calendar c = new GregorianCalendar(1995, MAY, 23);
109  * String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
110  * // -> s == "Duke's Birthday: May 23, 1995"
111  * </pre></blockquote>
112  *
113  * <a name="org"><h3> Organization </h3></a>
114  *
115  * <p> This specification is divided into two sections. The first section, <a
116  * HREF="#summary">Summary</a>, covers the basic formatting concepts. This
117  * section is intended for users who want to get started quickly and are
118  * familiar with formatted printing in other programming languages. The second
119  * section, <a HREF="#detail">Details</a>, covers the specific implementation
120  * details. It is intended for users who want more precise specification of
121  * formatting behavior.
122  *
123  * <a name="summary"><h3> Summary </h3></a>
124  *
125  * <p> This section is intended to provide a brief overview of formatting
126  * concepts. For precise behavioral details, refer to the <a
127  * HREF="#detail">Details</a> section.
128  *
129  * <a name="syntax"><h4> Format String Syntax </h4></a>
130  *
131  * <p> Every method which produces formatted output requires a <i>format
132  * string</i> and an <i>argument list</i>. The format string is a {@link
133  * String} which may contain fixed text and one or more embedded <i>format
134  * specifiers</i>. Consider the following example:
135  *
136  * <blockquote><pre>
137  * Calendar c = ...;
138  * String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
139  * </pre></blockquote>
140  *
141  * This format string is the first argument to the <tt>format</tt> method. It
142  * contains three format specifiers "<tt>%1$tm</tt>", "<tt>%1$te</tt>", and
143  * "<tt>%1$tY</tt>" which indicate how the arguments should be processed and
144  * where they should be inserted in the text. The remaining portions of the
145  * format string are fixed text including <tt>"Dukes Birthday: "</tt> and any
146  * other spaces or punctuation.
147  *
148  * The argument list consists of all arguments passed to the method after the
149  * format string. In the above example, the argument list is of size one and
150  * consists of the new {@link java.util.Calendar Calendar} object.
151  *
152  * <ul>
153  *
154  * <li> The format specifiers for general, character, and numeric types have
155  * the following syntax:
156  *
157  * <blockquote><pre>
158  * %[argument_index$][flags][width][.precision]conversion
159  * </pre></blockquote>
160  *
161  * <p> The optional <i>argument_index</i> is a decimal integer indicating the
162  * position of the argument in the argument list. The first argument is
163  * referenced by "<tt>1$</tt>", the second by "<tt>2$</tt>", etc.
164  *
165  * <p> The optional <i>flags</i> is a set of characters that modify the output
166  * format. The set of valid flags depends on the conversion.
167  *
168  * <p> The optional <i>width</i> is a non-negative decimal integer indicating
169  * the minimum number of characters to be written to the output.
170  *
171  * <p> The optional <i>precision</i> is a non-negative decimal integer usually
172  * used to restrict the number of characters. The specific behavior depends on
173  * the conversion.
174  *
175  * <p> The required <i>conversion</i> is a character indicating how the
176  * argument should be formatted. The set of valid conversions for a given
177  * argument depends on the argument's data type.
178  *
179  * <li> The format specifiers for types which are used to represents dates and
180  * times have the following syntax:
181  *
182  * <blockquote><pre>
183  * %[argument_index$][flags][width]conversion
184  * </pre></blockquote>
185  *
186  * <p> The optional <i>argument_index</i>, <i>flags</i> and <i>width</i> are
187  * defined as above.
188  *
189  * <p> The required <i>conversion</i> is a two character sequence. The first
190  * character is <tt>'t'</tt> or <tt>'T'</tt>. The second character indicates
191  * the format to be used. These characters are similar to but not completely
192  * identical to those defined by GNU <tt>date</tt> and POSIX
193  * <tt>strftime(3c)</tt>.
194  *
195  * <li> The format specifiers which do not correspond to arguments have the
196  * following syntax:
197  *
198  * <blockquote><pre>
199  * %[flags][width]conversion
200  * </pre></blockquote>
201  *
202  * <p> The optional <i>flags</i> and <i>width</i> is defined as above.
203  *
204  * <p> The required <i>conversion</i> is a character indicating content to be
205  * inserted in the output.
206  *
207  * </ul>
208  *
209  * <h4> Conversions </h4>
210  *
211  * <p> Conversions are divided into the following categories:
212  *
213  * <ol>
214  *
215  * <li> <b>General</b> - may be applied to any argument
216  * type
217  *
218  * <li> <b>Character</b> - may be applied to basic types which represent
219  * Unicode characters: <tt>char</tt>, {@link Character}, <tt>byte</tt>, {@link
220  * Byte}, <tt>short</tt>, and {@link Short}. This conversion may also be
221  * applied to the types <tt>int</tt> and {@link Integer} when {@link
222  * Character#isValidCodePoint} returns <tt>true</tt>
223  *
224  * <li> <b>Numeric</b>
225  *
226  * <ol>
227  *
228  * <li> <b>Integral</b> - may be applied to Java integral types: <tt>byte</tt>,
229  * {@link Byte}, <tt>short</tt>, {@link Short}, <tt>int</tt> and {@link
230  * Integer}, <tt>long</tt>, {@link Long}, and {@link java.math.BigInteger
231  * BigInteger}
232  *
233  * <li><b>Floating Point</b> - may be applied to Java floating-point types:
234  * <tt>float</tt>, {@link Float}, <tt>double</tt>, {@link Double}, and {@link
235  * java.math.BigDecimal BigDecimal}
236  *
237  * </ol>
238  *
239  * <li> <b>Date/Time</b> - may be applied to Java types which are capable of
240  * encoding a date or time: <tt>long</tt>, {@link Long}, {@link Calendar}, and
241  * {@link Date}.
242  *
243  * <li> <b>Percent</b> - produces a literal <tt>'%'</tt>
244  * (<tt>'&#92;u0025'</tt>)
245  *
246  * <li> <b>Line Separator</b> - produces the platform-specific line separator
247  *
248  * </ol>
249  *
250  * <p> The following table summarizes the supported conversions. Conversions
251  * denoted by an upper-case character (i.e. <tt>'B'</tt>, <tt>'H'</tt>,
252  * <tt>'S'</tt>, <tt>'C'</tt>, <tt>'X'</tt>, <tt>'E'</tt>, <tt>'G'</tt>,
253  * <tt>'A'</tt>, and <tt>'T'</tt>) are the same as those for the corresponding
254  * lower-case conversion characters except that the result is converted to
255  * upper case according to the rules of the prevailing {@link java.util.Locale
256  * Locale}. The result is equivalent to the following invocation of {@link
257  * String#toUpperCase()}
258  *
259  * <pre>
260  * out.toUpperCase() </pre>
261  *
262  * <table cellpadding=5 summary="genConv">
263  *
264  * <tr><th valign="bottom"> Conversion
265  * <th valign="bottom"> Argument Category
266  * <th valign="bottom"> Description
267  *
268  * <tr><td valign="top"> <tt>'b'</tt>, <tt>'B'</tt>
269  * <td valign="top"> general
270  * <td> If the argument <i>arg</i> is <tt>null</tt>, then the result is
271  * "<tt>false</tt>". If <i>arg</i> is a <tt>boolean</tt> or {@link
272  * Boolean}, then the result is the string returned by {@link
273  * String#valueOf(boolean) String.valueOf()}. Otherwise, the result is
274  * "true".
275  *
276  * <tr><td valign="top"> <tt>'h'</tt>, <tt>'H'</tt>
277  * <td valign="top"> general
278  * <td> If the argument <i>arg</i> is <tt>null</tt>, then the result is
279  * "<tt>null</tt>". Otherwise, the result is obtained by invoking
280  * <tt>Integer.toHexString(arg.hashCode())</tt>.
281  *
282  * <tr><td valign="top"> <tt>'s'</tt>, <tt>'S'</tt>
283  * <td valign="top"> general
284  * <td> If the argument <i>arg</i> is <tt>null</tt>, then the result is
285  * "<tt>null</tt>". If <i>arg</i> implements {@link Formattable}, then
286  * {@link Formattable#formatTo arg.formatTo} is invoked. Otherwise, the
287  * result is obtained by invoking <tt>arg.toString()</tt>.
288  *
289  * <tr><td valign="top"><tt>'c'</tt>, <tt>'C'</tt>
290  * <td valign="top"> character
291  * <td> The result is a Unicode character
292  *
293  * <tr><td valign="top"><tt>'d'</tt>
294  * <td valign="top"> integral
295  * <td> The result is formatted as a decimal integer
296  *
297  * <tr><td valign="top"><tt>'o'</tt>
298  * <td valign="top"> integral
299  * <td> The result is formatted as an octal integer
300  *
301  * <tr><td valign="top"><tt>'x'</tt>, <tt>'X'</tt>
302  * <td valign="top"> integral
303  * <td> The result is formatted as a hexadecimal integer
304  *
305  * <tr><td valign="top"><tt>'e'</tt>, <tt>'E'</tt>
306  * <td valign="top"> floating point
307  * <td> The result is formatted as a decimal number in computerized
308  * scientific notation
309  *
310  * <tr><td valign="top"><tt>'f'</tt>
311  * <td valign="top"> floating point
312  * <td> The result is formatted as a decimal number
313  *
314  * <tr><td valign="top"><tt>'g'</tt>, <tt>'G'</tt>
315  * <td valign="top"> floating point
316  * <td> The result is formatted using computerized scientific notation or
317  * decimal format, depending on the precision and the value after rounding.
318  *
319  * <tr><td valign="top"><tt>'a'</tt>, <tt>'A'</tt>
320  * <td valign="top"> floating point
321  * <td> The result is formatted as a hexadecimal floating-point number with
322  * a significand and an exponent
323  *
324  * <tr><td valign="top"><tt>'t'</tt>, <tt>'T'</tt>
325  * <td valign="top"> date/time
326  * <td> Prefix for date and time conversion characters. See <a
327  * HREF="#dt">Date/Time Conversions</a>.
328  *
329  * <tr><td valign="top"><tt>'%'</tt>
330  * <td valign="top"> percent
331  * <td> The result is a literal <tt>'%'</tt> (<tt>'&#92;u0025'</tt>)
332  *
333  * <tr><td valign="top"><tt>'n'</tt>
334  * <td valign="top"> line separator
335  * <td> The result is the platform-specific line separator
336  *
337  * </table>
338  *
339  * <p> Any characters not explicitly defined as conversions are illegal and are
340  * reserved for future extensions.
341  *
342  * <a name="dt"><h4> Date/Time Conversions </h4></a>
343  *
344  * <p> The following date and time conversion suffix characters are defined for
345  * the <tt>'t'</tt> and <tt>'T'</tt> conversions. The types are similar to but
346  * not completely identical to those defined by GNU <tt>date</tt> and POSIX
347  * <tt>strftime(3c)</tt>. Additional conversion types are provided to access
348  * Java-specific functionality (e.g. <tt>'L'</tt> for milliseconds within the
349  * second).
350  *
351  * <p> The following conversion characters are used for formatting times:
352  *
353  * <table cellpadding=5 summary="time">
354  *
355  * <tr><td valign="top"> <tt>'H'</tt>
356  * <td> Hour of the day for the 24-hour clock, formatted as two digits with
357  * a leading zero as necessary i.e. <tt>00 - 23</tt>.
358  *
359  * <tr><td valign="top"><tt>'I'</tt>
360  * <td> Hour for the 12-hour clock, formatted as two digits with a leading
361  * zero as necessary, i.e. <tt>01 - 12</tt>.
362  *
363  * <tr><td valign="top"><tt>'k'</tt>
364  * <td> Hour of the day for the 24-hour clock, i.e. <tt>0 - 23</tt>.
365  *
366  * <tr><td valign="top"><tt>'l'</tt>
367  * <td> Hour for the 12-hour clock, i.e. <tt>1 - 12</tt>.
368  *
369  * <tr><td valign="top"><tt>'M'</tt>
370  * <td> Minute within the hour formatted as two digits with a leading zero
371  * as necessary, i.e. <tt>00 - 59</tt>.
372  *
373  * <tr><td valign="top"><tt>'S'</tt>
374  * <td> Seconds within the minute, formatted as two digits with a leading
375  * zero as necessary, i.e. <tt>00 - 60</tt> ("<tt>60</tt>" is a special
376  * value required to support leap seconds).
377  *
378  * <tr><td valign="top"><tt>'L'</tt>
379  * <td> Millisecond within the second formatted as three digits with
380  * leading zeros as necessary, i.e. <tt>000 - 999</tt>.
381  *
382  * <tr><td valign="top"><tt>'N'</tt>
383  * <td> Nanosecond within the second, formatted as nine digits with leading
384  * zeros as necessary, i.e. <tt>000000000 - 999999999</tt>.
385  *
386  * <tr><td valign="top"><tt>'p'</tt>
387  * <td> Locale-specific {@linkplain
388  * java.text.DateFormatSymbols#getAmPmStrings morning or afternoon} marker
389  * in lower case, e.g."<tt>am</tt>" or "<tt>pm</tt>". Use of the conversion
390  * prefix <tt>'T'</tt> forces this output to upper case.
391  *
392  * <tr><td valign="top"><tt>'z'</tt>
393  * <td> <a HREF="http://www.ietf.org/rfc/rfc0822.txt">RFC&nbsp;822</a>
394  * style numeric time zone offset from GMT, e.g. <tt>-0800</tt>.
395  *
396  * <tr><td valign="top"><tt>'Z'</tt>
397  * <td> A string representing the abbreviation for the time zone. The
398  * Formatter's locale will supersede the locale of the argument (if any).
399  *
400  * <tr><td valign="top"><tt>'s'</tt>
401  * <td> Seconds since the beginning of the epoch starting at 1 January 1970
402  * <tt>00:00:00</tt> UTC, i.e. <tt>Long.MIN_VALUE/1000</tt> to
403  * <tt>Long.MAX_VALUE/1000</tt>.
404  *
405  * <tr><td valign="top"><tt>'Q'</tt>
406  * <td> Milliseconds since the beginning of the epoch starting at 1 January
407  * 1970 <tt>00:00:00</tt> UTC, i.e. <tt>Long.MIN_VALUE</tt> to
408  * <tt>Long.MAX_VALUE</tt>.
409  *
410  * </table>
411  *
412  * <p> The following conversion characters are used for formatting dates:
413  *
414  * <table cellpadding=5 summary="date">
415  *
416  * <tr><td valign="top"><tt>'B'</tt>
417  * <td> Locale-specific {@linkplain java.text.DateFormatSymbols#getMonths
418  * full month name}, e.g. <tt>"January"</tt>, <tt>"February"</tt>.
419  *
420  * <tr><td valign="top"><tt>'b'</tt>
421  * <td> Locale-specific {@linkplain
422  * java.text.DateFormatSymbols#getShortMonths abbreviated month name},
423  * e.g. <tt>"Jan"</tt>, <tt>"Feb"</tt>.
424  *
425  * <tr><td valign="top"><tt>'h'</tt>
426  * <td> Same as <tt>'b'</tt>.
427  *
428  * <tr><td valign="top"><tt>'A'</tt>
429  * <td> Locale-specific full name of the {@linkplain
430  * java.text.DateFormatSymbols#getWeekdays day of the week},
431  * e.g. <tt>"Sunday"</tt>, <tt>"Monday"</tt>
432  *
433  * <tr><td valign="top"><tt>'a'</tt>
434  * <td> Locale-specific short name of the {@linkplain
435  * java.text.DateFormatSymbols#getShortWeekdays day of the week},
436  * e.g. <tt>"Sun"</tt>, <tt>"Mon"</tt>
437  *
438  * <tr><td valign="top"><tt>'C'</tt>
439  * <td> Four-digit year divided by <tt>100</tt>, formatted as two digits
440  * with leading zero as necessary, i.e. <tt>00 - 99</tt>
441  *
442  * <tr><td valign="top"><tt>'Y'</tt>
443  * <td> Year, formatted as at least four digits with leading zeros as
444  * necessary, e.g. <tt>0092</tt> equals <tt>92</tt> CE for the Gregorian
445  * calendar.
446  *
447  * <tr><td valign="top"><tt>'y'</tt>
448  * <td> Last two digits of the year, formatted with leading zeros as
449  * necessary, i.e. <tt>00 - 99</tt>.
450  *
451  * <tr><td valign="top"><tt>'j'</tt>
452  * <td> Day of year, formatted as three digits with leading zeros as
453  * necessary, e.g. <tt>001 - 366</tt> for the Gregorian calendar.
454  *
455  * <tr><td valign="top"><tt>'m'</tt>
456  * <td> Month, formatted as two digits with leading zeros as necessary,
457  * i.e. <tt>01 - 13</tt>.
458  *
459  * <tr><td valign="top"><tt>'d'</tt>
460  * <td> Day of month, formatted as two digits with leading zeros as
461  * necessary, i.e. <tt>01 - 31</tt>
462  *
463  * <tr><td valign="top"><tt>'e'</tt>
464  * <td> Day of month, formatted as two digits, i.e. <tt>1 - 31</tt>.
465  *
466  * </table>
467  *
468  * <p> The following conversion characters are used for formatting common
469  * date/time compositions.
470  *
471  * <table cellpadding=5 summary="composites">
472  *
473  * <tr><td valign="top"><tt>'R'</tt>
474  * <td> Time formatted for the 24-hour clock as <tt>"%tH:%tM"</tt>
475  *
476  * <tr><td valign="top"><tt>'T'</tt>
477  * <td> Time formatted for the 24-hour clock as <tt>"%tH:%tM:%tS"</tt>.
478  *
479  * <tr><td valign="top"><tt>'r'</tt>
480  * <td> Time formatted for the 12-hour clock as <tt>"%tI:%tM:%tS %Tp"</tt>.
481  * The location of the morning or afternoon marker (<tt>'%Tp'</tt>) may be
482  * locale-dependent.
483  *
484  * <tr><td valign="top"><tt>'D'</tt>
485  * <td> Date formatted as <tt>"%tm/%td/%ty"</tt>.
486  *
487  * <tr><td valign="top"><tt>'F'</tt>
488  * <td> <a HREF="http://www.w3.org/TR/NOTE-datetime">ISO&nbsp;8601</a>
489  * complete date formatted as <tt>"%tY-%tm-%td"</tt>.
490  *
491  * <tr><td valign="top"><tt>'c'</tt>
492  * <td> Date and time formatted as <tt>"%ta %tb %td %tT %tZ %tY"</tt>,
493  * e.g. <tt>"Sun Jul 20 16:17:00 EDT 1969"</tt>.
494  *
495  * </table>
496  *
497  * <p> Any characters not explicitly defined as date/time conversion suffixes
498  * are illegal and are reserved for future extensions.
499  *
500  * <h4> Flags </h4>
501  *
502  * <p> The following table summarizes the supported flags. <i>y</i> means the
503  * flag is supported for the indicated argument types.
504  *
505  * <table cellpadding=5 summary="genConv">
506  *
507  * <tr><th valign="bottom"> Flag <th valign="bottom"> General
508  * <th valign="bottom"> Character <th valign="bottom"> Integral
509  * <th valign="bottom"> Floating Point
510  * <th valign="bottom"> Date/Time
511  * <th valign="bottom"> Description
512  *
513  * <tr><td> '-' <td align="center" valign="top"> y
514  * <td align="center" valign="top"> y
515  * <td align="center" valign="top"> y
516  * <td align="center" valign="top"> y
517  * <td align="center" valign="top"> y
518  * <td> The result will be left-justified.
519  *
520  * <tr><td> '#' <td align="center" valign="top"> y<sup>1</sup>
521  * <td align="center" valign="top"> -
522  * <td align="center" valign="top"> y<sup>3</sup>
523  * <td align="center" valign="top"> y
524  * <td align="center" valign="top"> -
525  * <td> The result should use a conversion-dependent alternate form
526  *
527  * <tr><td> '+' <td align="center" valign="top"> -
528  * <td align="center" valign="top"> -
529  * <td align="center" valign="top"> y<sup>4</sup>
530  * <td align="center" valign="top"> y
531  * <td align="center" valign="top"> -
532  * <td> The result will always include a sign
533  *
534  * <tr><td> '&nbsp;&nbsp;' <td align="center" valign="top"> -
535  * <td align="center" valign="top"> -
536  * <td align="center" valign="top"> y<sup>4</sup>
537  * <td align="center" valign="top"> y
538  * <td align="center" valign="top"> -
539  * <td> The result will include a leading space for positive values
540  *
541  * <tr><td> '0' <td align="center" valign="top"> -
542  * <td align="center" valign="top"> -
543  * <td align="center" valign="top"> y
544  * <td align="center" valign="top"> y
545  * <td align="center" valign="top"> -
546  * <td> The result will be zero-padded
547  *
548  * <tr><td> ',' <td align="center" valign="top"> -
549  * <td align="center" valign="top"> -
550  * <td align="center" valign="top"> y<sup>2</sup>
551  * <td align="center" valign="top"> y<sup>5</sup>
552  * <td align="center" valign="top"> -
553  * <td> The result will include locale-specific {@linkplain
554  * java.text.DecimalFormatSymbols#getGroupingSeparator grouping separators}
555  *
556  * <tr><td> '(' <td align="center" valign="top"> -
557  * <td align="center" valign="top"> -
558  * <td align="center" valign="top"> y<sup>4</sup>
559  * <td align="center" valign="top"> y<sup>5</sup>
560  * <td align="center"> -
561  * <td> The result will enclose negative numbers in parentheses
562  *
563  * </table>
564  *
565  * <p> <sup>1</sup> Depends on the definition of {@link Formattable}.
566  *
567  * <p> <sup>2</sup> For <tt>'d'</tt> conversion only.
568  *
569  * <p> <sup>3</sup> For <tt>'o'</tt>, <tt>'x'</tt>, and <tt>'X'</tt>
570  * conversions only.
571  *
572  * <p> <sup>4</sup> For <tt>'d'</tt>, <tt>'o'</tt>, <tt>'x'</tt>, and
573  * <tt>'X'</tt> conversions applied to {@link java.math.BigInteger BigInteger}
574  * or <tt>'d'</tt> applied to <tt>byte</tt>, {@link Byte}, <tt>short</tt>, {@link
575  * Short}, <tt>int</tt> and {@link Integer}, <tt>long</tt>, and {@link Long}.
576  *
577  * <p> <sup>5</sup> For <tt>'e'</tt>, <tt>'E'</tt>, <tt>'f'</tt>,
578  * <tt>'g'</tt>, and <tt>'G'</tt> conversions only.
579  *
580  * <p> Any characters not explicitly defined as flags are illegal and are
581  * reserved for future extensions.
582  *
583  * <h4> Width </h4>
584  *
585  * <p> The width is the minimum number of characters to be written to the
586  * output. For the line separator conversion, width is not applicable; if it
587  * is provided, an exception will be thrown.
588  *
589  * <h4> Precision </h4>
590  *
591  * <p> For general argument types, the precision is the maximum number of
592  * characters to be written to the output.
593  *
594  * <p> For the floating-point conversions <tt>'e'</tt>, <tt>'E'</tt>, and
595  * <tt>'f'</tt> the precision is the number of digits after the decimal
596  * separator. If the conversion is <tt>'g'</tt> or <tt>'G'</tt>, then the
597  * precision is the total number of digits in the resulting magnitude after
598  * rounding. If the conversion is <tt>'a'</tt> or <tt>'A'</tt>, then the
599  * precision must not be specified.
600  *
601  * <p> For character, integral, and date/time argument types and the percent
602  * and line separator conversions, the precision is not applicable; if a
603  * precision is provided, an exception will be thrown.
604  *
605  * <h4> Argument Index </h4>
606  *
607  * <p> The argument index is a decimal integer indicating the position of the
608  * argument in the argument list. The first argument is referenced by
609  * "<tt>1$</tt>", the second by "<tt>2$</tt>", etc.
610  *
611  * <p> Another way to reference arguments by position is to use the
612  * <tt>'<'</tt> (<tt>'&#92;u003c'</tt>) flag, which causes the argument for the
613  * previous format specifier to be re-used. For example, the following two
614  * statements would produce identical strings:
615  *
616  * <blockquote><pre>
617  * Calendar c = ...;
618  * String s1 = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
619  *
620  * String s2 = String.format("Duke's Birthday: %1$tm %<$te,%<$tY", c);
621  * </pre></blockquote>
622  *
623  * <hr>
624  * <a name="detail"><h3> Details </h3></a>
625  *
626  * <p> This section is intended to provide behavioral details for formatting,
627  * including conditions and exceptions, supported data types, localization, and
628  * interactions between flags, conversions, and data types. For an overview of
629  * formatting concepts, refer to the <a HREF="#summary">Summary</a>
630  *
631  * <p> Any characters not explicitly defined as conversions, date/time
632  * conversion suffixes, or flags are illegal and are reserved for
633  * future extensions. Use of such a character in a format string will
634  * cause an {@link UnknownFormatConversionException} or {@link
635  * UnknownFormatFlagsException} to be thrown.
636  *
637  * <p> If the format specifier contains a width or precision with an invalid
638  * value or which is otherwise unsupported, then a {@link
639  * IllegalFormatWidthException} or {@link IllegalFormatPrecisionException}
640  * respectively will be thrown.
641  *
642  * <p> If a format specifier contains a conversion character that is not
643  * applicable to the corresponding argument, then an {@link
644  * IllegalFormatConversionException} will be thrown.
645  *
646  * <p> All specified exceptions may be thrown by any of the <tt>format</tt>
647  * methods of <tt>Formatter</tt> as well as by any <tt>format</tt> convenience
648  * methods such as {@link String#format(String,Object...) String.format} and
649  * {@link java.io.PrintStream#printf(String,Object...) PrintStream.printf}.
650  *
651  * <p> Conversions denoted by an upper-case character (i.e. <tt>'B'</tt>,
652  * <tt>'H'</tt>, <tt>'S'</tt>, <tt>'C'</tt>, <tt>'X'</tt>, <tt>'E'</tt>,
653  * <tt>'G'</tt>, <tt>'A'</tt>, and <tt>'T'</tt>) are the same as those for the
654  * corresponding lower-case conversion characters except that the result is
655  * converted to upper case according to the rules of the prevailing {@link
656  * java.util.Locale Locale}. The result is equivalent to the following
657  * invocation of {@link String#toUpperCase()}
658  *
659  * <pre>
660  * out.toUpperCase() </pre>
661  *
662  * <a name="dgen"><h4> General </h4></a>
663  *
664  * <p> The following general conversions may be applied to any argument type:
665  *
666  * <table cellpadding=5 summary="dgConv">
667  *
668  * <tr><td valign="top"> <tt>'b'</tt>
669  * <td valign="top"> <tt>'&#92;u0062'</tt>
670  * <td> Produces either "<tt>true</tt>" or "<tt>false</tt>" as returned by
671  * {@link Boolean#toString(boolean)}.
672  *
673  * <p> If the argument is <tt>null</tt>, then the result is
674  * "<tt>false</tt>". If the argument is a <tt>boolean</tt> or {@link
675  * Boolean}, then the result is the string returned by {@link
676  * String#valueOf(boolean) String.valueOf()}. Otherwise, the result is
677  * "<tt>true</tt>".
678  *
679  * <p> If the <tt>'#'</tt> flag is given, then a {@link
680  * FormatFlagsConversionMismatchException} will be thrown.
681  *
682  * <tr><td valign="top"> <tt>'B'</tt>
683  * <td valign="top"> <tt>'&#92;u0042'</tt>
684  * <td> The upper-case variant of <tt>'b'</tt>.
685  *
686  * <tr><td valign="top"> <tt>'h'</tt>
687  * <td valign="top"> <tt>'&#92;u0068'</tt>
688  * <td> Produces a string representing the hash code value of the object.
689  *
690  * <p> If the argument, <i>arg</i> is <tt>null</tt>, then the
691  * result is "<tt>null</tt>". Otherwise, the result is obtained
692  * by invoking <tt>Integer.toHexString(arg.hashCode())</tt>.
693  *
694  * <p> If the <tt>'#'</tt> flag is given, then a {@link
695  * FormatFlagsConversionMismatchException} will be thrown.
696  *
697  * <tr><td valign="top"> <tt>'H'</tt>
698  * <td valign="top"> <tt>'&#92;u0048'</tt>
699  * <td> The upper-case variant of <tt>'h'</tt>.
700  *
701  * <tr><td valign="top"> <tt>'s'</tt>
702  * <td valign="top"> <tt>'&#92;u0073'</tt>
703  * <td> Produces a string.
704  *
705  * <p> If the argument is <tt>null</tt>, then the result is
706  * "<tt>null</tt>". If the argument implements {@link Formattable}, then
707  * its {@link Formattable#formatTo formatTo} method is invoked.
708  * Otherwise, the result is obtained by invoking the argument's
709  * <tt>toString()</tt> method.
710  *
711  * <p> If the <tt>'#'</tt> flag is given and the argument is not a {@link
712  * Formattable} , then a {@link FormatFlagsConversionMismatchException}
713  * will be thrown.
714  *
715  * <tr><td valign="top"> <tt>'S'</tt>
716  * <td valign="top"> <tt>'&#92;u0053'</tt>
717  * <td> The upper-case variant of <tt>'s'</tt>.
718  *
719  * </table>
720  *
721  * <p> The following flags apply to general conversions:
722  *
723  * <a name="dFlags"><table cellpadding=5 summary="dFlags"></a>
724  *
725  * <tr><td valign="top"> <tt>'-'</tt>
726  * <td valign="top"> <tt>'&#92;u002d'</tt>
727  * <td> Left justifies the output. Spaces (<tt>'&#92;u0020'</tt>) will be
728  * added at the end of the converted value as required to fill the minimum
729  * width of the field. If the width is not provided, then a {@link
730  * MissingFormatWidthException} will be thrown. If this flag is not given
731  * then the output will be right-justified.
732  *
733  * <tr><td valign="top"> <tt>'#'</tt>
734  * <td valign="top"> <tt>'&#92;u0023'</tt>
735  * <td> Requires the output use an alternate form. The definition of the
736  * form is specified by the conversion.
737  *
738  * </table>
739  *
740  * <a name="genWidth"></a>
741  *
742  * <p> The width is the minimum number of characters to be written to the
743  * output. If the length of the converted value is less than the width then
744  * the output will be padded by <tt>'&nbsp;&nbsp;'</tt> (<tt>&#92;u0020'</tt>)
745  * until the total number of characters equals the width. The padding is on
746  * the left by default. If the <tt>'-'</tt> flag is given, then the padding
747  * will be on the right. If the width is not specified then there is no
748  * minimum.
749  *
750  * <p> The precision is the maximum number of characters to be written to the
751  * output. The precision is applied before the width, thus the output will be
752  * truncated to <tt>precision</tt> characters even if the width is greater than
753  * the precision. If the precision is not specified then there is no explicit
754  * limit on the number of characters.
755  *
756  * <a name="dchar"><h4> Character </h4></a>
757  *
758  * This conversion may be applied to <tt>char</tt>, {@link Character},
759  * <tt>byte</tt>, {@link Byte}, <tt>short</tt>, and {@link Short}. This
760  * conversion may also be applied to the types <tt>int</tt> and {@link Integer}
761  * when {@link Character#isValidCodePoint} returns <tt>true</tt>. If it
762  * returns <tt>false</tt> then an {@link IllegalFormatCodePointException} will
763  * be thrown.
764  *
765  * <table cellpadding=5 summary="charConv">
766  *
767  * <tr><td valign="top"> <tt>'c'</tt>
768  * <td valign="top"> <tt>'&#92;u0063'</tt>
769  * <td> Formats the argument as a Unicode character as described in <a
770  * HREF="../lang/Character.html#unicode">Unicode Character
771  * Representation</a>. This may be more than one 16-bit <tt>char</tt> in
772  * the case where the argument represents a supplementary character.
773  *
774  * <p> If the <tt>'#'</tt> flag is given, then a {@link
775  * FormatFlagsConversionMismatchException} will be thrown.
776  *
777  * <tr><td valign="top"> <tt>'C'</tt>
778  * <td valign="top"> <tt>'&#92;u0043'</tt>
779  * <td> The upper-case variant of <tt>'c'</tt>.
780  *
781  * </table>
782  *
783  * <p> The <tt>'-'</tt> flag defined for <a HREF="#dFlags">General
784  * conversions</a> applies. If the <tt>'#'</tt> flag is given, then a {@link
785  * FormatFlagsConversionMismatchException} will be thrown.
786  *
787  * <p> The width is defined as for <a HREF="#genWidth">General conversions</a>.
788  *
789  * <p> The precision is not applicable. If the precision is specified then an
790  * {@link IllegalFormatPrecisionException} will be thrown.
791  *
792  * <a name="dnum"><h4> Numeric </h4></a>
793  *
794  * <p> Numeric conversions are divided into the following categories:
795  *
796  * <ol>
797  *
798  * <li> <a HREF="#dnint"><b>Byte, Short, Integer, and Long</b></a>
799  *
800  * <li> <a HREF="#dnbint"><b>BigInteger</b></a>
801  *
802  * <li> <a HREF="#dndec"><b>Float and Double</b></a>
803  *
804  * <li> <a HREF="#dndec"><b>BigDecimal</b></a>
805  *
806  * </ol>
807  *
808  * <p> Numeric types will be formatted according to the following algorithm:
809  *
810  * <p><b><a name="l10n algorithm"> Number Localization Algorithm<a></b>
811  *
812  * <p> After digits are obtained for the integer part, fractional part, and
813  * exponent (as appropriate for the data type), the following transformation
814  * is applied:
815  *
816  * <ol>
817  *
818  * <li> Each digit character <i>d</i> in the string is replaced by a
819  * locale-specific digit computed relative to the current locale's
820  * {@linkplain java.text.DecimalFormatSymbols#getZeroDigit() zero digit}
821  * <i>z</i>; that is <i>d&nbsp;-&nbsp;</i> <tt>'0'</tt>
822  * <i>&nbsp;+&nbsp;z</i>.
823  *
824  * <li> If a decimal separator is present, a locale-specific {@linkplain
825  * java.text.DecimalFormatSymbols#getDecimalSeparator decimal separator} is
826  * substituted.
827  *
828  * <li> <a name="l10n group"></a> If the <tt>','</tt> (<tt>'&#92;u002c'</tt>)
829  * flag is given, then the locale-specific {@linkplain
830  * java.text.DecimalFormatSymbols#getGroupingSeparator grouping separator} is
831  * inserted by scanning the integer part of the string from least significant
832  * to most significant digits and inserting a separator at intervals defined by
833  * the locale's {@linkplain java.text.DecimalFormat#getGroupingSize() grouping
834  * size}.
835  *
836  * <li> If the <tt>'0'</tt> flag is given, then the locale-specific {@linkplain
837  * java.text.DecimalFormatSymbols#getZeroDigit() zero digits} are inserted
838  * after the sign character, if any, and before the first non-zero digit, until
839  * the length of the string is equal to the requested field width.
840  *
841  * <li> If the value is negative and the <tt>'('</tt> flag is given, then a
842  * <tt>'('</tt> (<tt>'&#92;u0028'</tt>) is prepended and a <tt>')'</tt>
843  * (<tt>'&#92;u0029'</tt>) is appended.
844  *
845  * <li> If the value is negative (or floating-point negative zero) and
846  * <tt>'('</tt> flag is not given, then a <tt>'-'</tt> (<tt>'&#92;u002d'</tt>)
847  * is prepended.
848  *
849  * <li> If the <tt>'+'</tt> flag is given and the value is positive or zero (or
850  * floating-point positive zero), then a <tt>'+'</tt> (<tt>'&#92;u002b'</tt>)
851  * will be prepended.
852  *
853  * </ol>
854  *
855  * <p> If the value is NaN or positive infinity the literal strings "NaN" or
856  * "Infinity" respectively, will be output. If the value is negative infinity,
857  * then the output will be "(Infinity)" if the <tt>'('</tt> flag is given
858  * otherwise the output will be "-Infinity". These values are not localized.
859  *
860  * <p><a name="dnint"><b> Byte, Short, Integer, and Long </b></a>
861  *
862  * <p> The following conversions may be applied to <tt>byte</tt>, {@link Byte},
863  * <tt>short</tt>, {@link Short}, <tt>int</tt> and {@link Integer},
864  * <tt>long</tt>, and {@link Long}.
865  *
866  * <table cellpadding=5 summary="IntConv">
867  *
868  * <tr><td valign="top"> <tt>'d'</tt>
869  * <td valign="top"> <tt>'&#92;u0054'</tt>
870  * <td> Formats the argument as a decimal integer. The <a
871  * HREF="#l10n algorithm">localization algorithm</a> is applied.
872  *
873  * <p> If the <tt>'0'</tt> flag is given and the value is negative, then
874  * the zero padding will occur after the sign.
875  *
876  * <p> If the <tt>'#'</tt> flag is given then a {@link
877  * FormatFlagsConversionMismatchException} will be thrown.
878  *
879  * <tr><td valign="top"> <tt>'o'</tt>
880  * <td valign="top"> <tt>'&#92;u006f'</tt>
881  * <td> Formats the argument as an integer in base eight. No localization
882  * is applied.
883  *
884  * <p> If <i>x</i> is negative then the result will be an unsigned value
885  * generated by adding 2<sup>n</sup> to the value where <tt>n</tt> is the
886  * number of bits in the type as returned by the static <tt>SIZE</tt> field
887  * in the {@linkplain Byte#SIZE Byte}, {@linkplain Short#SIZE Short},
888  * {@linkplain Integer#SIZE Integer}, or {@linkplain Long#SIZE Long}
889  * classes as appropriate.
890  *
891  * <p> If the <tt>'#'</tt> flag is given then the output will always begin
892  * with the radix indicator <tt>'0'</tt>.
893  *
894  * <p> If the <tt>'0'</tt> flag is given then the output will be padded
895  * with leading zeros to the field width following any indication of sign.
896  *
897  * <p> If <tt>'('</tt>, <tt>'+'</tt>, '&nbsp&nbsp;', or <tt>','</tt> flags
898  * are given then a {@link FormatFlagsConversionMismatchException} will be
899  * thrown.
900  *
901  * <tr><td valign="top"> <tt>'x'</tt>
902  * <td valign="top"> <tt>'&#92;u0078'</tt>
903  * <td> Formats the argument as an integer in base sixteen. No
904  * localization is applied.
905  *
906  * <p> If <i>x</i> is negative then the result will be an unsigned value
907  * generated by adding 2<sup>n</sup> to the value where <tt>n</tt> is the
908  * number of bits in the type as returned by the static <tt>SIZE</tt> field
909  * in the {@linkplain Byte#SIZE Byte}, {@linkplain Short#SIZE Short},
910  * {@linkplain Integer#SIZE Integer}, or {@linkplain Long#SIZE Long}
911  * classes as appropriate.
912  *
913  * <p> If the <tt>'#'</tt> flag is given then the output will always begin
914  * with the radix indicator <tt>"0x"</tt>.
915  *
916  * <p> If the <tt>'0'</tt> flag is given then the output will be padded to
917  * the field width with leading zeros after the radix indicator or sign (if
918  * present).
919  *
920  * <p> If <tt>'('</tt>, <tt>'&nbsp;&nbsp;'</tt>, <tt>'+'</tt>, or
921  * <tt>','</tt> flags are given then a {@link
922  * FormatFlagsConversionMismatchException} will be thrown.
923  *
924  * <tr><td valign="top"> <tt>'X'</tt>
925  * <td valign="top"> <tt>'&#92;u0058'</tt>
926  * <td> The upper-case variant of <tt>'x'</tt>. The entire string
927  * representing the number will be converted to {@linkplain
928  * String#toUpperCase upper case} including the <tt>'x'</tt> (if any) and
929  * all hexadecimal digits <tt>'a'</tt> - <tt>'f'</tt>
930  * (<tt>'&#92;u0061'</tt> - <tt>'&#92;u0066'</tt>).
931  *
932  * </table>
933  *
934  * <p> If the conversion is <tt>'o'</tt>, <tt>'x'</tt>, or <tt>'X'</tt> and
935  * both the <tt>'#'</tt> and the <tt>'0'</tt> flags are given, then result will
936  * contain the radix indicator (<tt>'0'</tt> for octal and <tt>"0x"</tt> or
937  * <tt>"0X"</tt> for hexadecimal), some number of zeros (based on the width),
938  * and the value.
939  *
940  * <p> If the <tt>'-'</tt> flag is not given, then the space padding will occur
941  * before the sign.
942  *
943  * <p> The following flags apply to numeric integral conversions:
944  *
945  * <table cellpadding=5 summary="intFlags"><a name="intFlags"></a>
946  *
947  * <tr><td valign="top"> <tt>'+'</tt>
948  * <td valign="top"> <tt>'&#92;u002b'</tt>
949  * <td> Requires the output to include a positive sign for all positive
950  * numbers. If this flag is not given then only negative values will
951  * include a sign.
952  *
953  * <p> If both the <tt>'+'</tt> and <tt>'&nbsp;&nbsp;'</tt> flags are given
954  * then an {@link IllegalFormatFlagsException} will be thrown.
955  *
956  * <tr><td valign="top"> <tt>'&nbsp;&nbsp;'</tt>
957  * <td valign="top"> <tt>'&#92;u0020'</tt>
958  * <td> Requires the output to include a single extra space
959  * (<tt>'&#92;u0020'</tt>) for non-negative values.
960  *
961  * <p> If both the <tt>'+'</tt> and <tt>'&nbsp;&nbsp;'</tt> flags are given
962  * then an {@link IllegalFormatFlagsException} will be thrown.
963  *
964  * <tr><td valign="top"> <tt>'0'</tt>
965  * <td valign="top"> <tt>'&#92;u0030'</tt>
966  * <td> Requires the output to be padded with leading {@linkplain
967  * java.text.DecimalFormatSymbols#getZeroDigit zeros} to the minimum field
968  * width following any sign or radix indicator except when converting NaN
969  * or infinity. If the width is not provided, then a {@link
970  * MissingFormatWidthException} will be thrown.
971  *
972  * <p> If both the <tt>'-'</tt> and <tt>'0'</tt> flags are given then an
973  * {@link IllegalFormatFlagsException} will be thrown.
974  *
975  * <tr><td valign="top"> <tt>','</tt>
976  * <td valign="top"> <tt>'&#92;u002c'</tt>
977  * <td> Requires the output to include the locale-specific {@linkplain
978  * java.text.DecimalFormatSymbols#getGroupingSeparator group separators} as
979  * described in the <a HREF="#l10n group">"group" section</a> of the
980  * localization algorithm.
981  *
982  * <tr><td valign="top"> <tt>'('</tt>
983  * <td valign="top"> <tt>'&#92;u0028'</tt>
984  * <td> Requires the output to prepend a <tt>'('</tt>
985  * (<tt>'&#92;u0028'</tt>) and append a <tt>')'</tt>
986  * (<tt>'&#92;u0029'</tt>) to negative values.
987  *
988  * </table>
989  *
990  * <a name="intdFlags"></a><p> If no flags are given the default formatting is
991  * as follows:
992  *
993  * <ul>
994  *
995  * <li> The output is right-justified within the <tt>width</tt>
996  *
997  * <li> Negative numbers begin with a <tt>'-'</tt> (<tt>'&#92;u002d'</tt>)
998  *
999  * <li> Positive numbers and zero do not include a sign or extra leading
1000 * space
1001 *
1002 * <li> No grouping separators are included
1003 *
1004 * </ul>
1005 *
1006 * <a name="intWidth"></a><p> The width is the minimum number of characters to
1007 * be written to the output. This includes any signs, digits, grouping
1008 * separators, radix indicator, and parentheses. If the length of the
1009 * converted value is less than the width then the output will be padded by
1010 * spaces (<tt>'&#92;u0020'</tt>) until the total number of characters equals
1011 * width. The padding is on the left by default. If <tt>'-'</tt> flag is
1012 * given then the padding will be on the right. If width is not specified then
1013 * there is no minimum.
1014 *
1015 * <p> The precision is not applicable. If precision is specified then an
1016 * {@link IllegalFormatPrecisionException} will be thrown.
1017 *
1018 * <p><a name="dnbint"><b> BigInteger </b></a>
1019 *
1020 * <p> The following conversions may be applied to {@link
1021 * java.math.BigInteger}.
1022 *
1023 * <table cellpadding=5 summary="BIntConv">
1024 *
1025 * <tr><td valign="top"> <tt>'d'</tt>
1026 * <td valign="top"> <tt>'&#92;u0054'</tt>
1027 * <td> Requires the output to be formatted as a decimal integer. The <a
1028 * HREF="#l10n algorithm">localization algorithm</a> is applied.
1029 *
1030 * <p> If the <tt>'#'</tt> flag is given {@link
1031 * FormatFlagsConversionMismatchException} will be thrown.
1032 *
1033 * <tr><td valign="top"> <tt>'o'</tt>
1034 * <td valign="top"> <tt>'&#92;u006f'</tt>
1035 * <td> Requires the output to be formatted as an integer in base eight.
1036 * No localization is applied.
1037 *
1038 * <p> If <i>x</i> is negative then the result will be a signed value
1039 * beginning with <tt>'-'</tt> (<tt>'&#92;u002d'</tt>). Signed output is
1040 * allowed for this type because unlike the primitive types it is not
1041 * possible to create an unsigned equivalent without assuming an explicit
1042 * data-type size.
1043 *
1044 * <p> If <i>x</i> is positive or zero and the <tt>'+'</tt> flag is given
1045 * then the result will begin with <tt>'+'</tt> (<tt>'&#92;u002b'</tt>).
1046 *
1047 * <p> If the <tt>'#'</tt> flag is given then the output will always begin
1048 * with <tt>'0'</tt> prefix.
1049 *
1050 * <p> If the <tt>'0'</tt> flag is given then the output will be padded
1051 * with leading zeros to the field width following any indication of sign.
1052 *
1053 * <p> If the <tt>','</tt> flag is given then a {@link
1054 * FormatFlagsConversionMismatchException} will be thrown.
1055 *
1056 * <tr><td valign="top"> <tt>'x'</tt>
1057 * <td valign="top"> <tt>'&#92;u0078'</tt>
1058 * <td> Requires the output to be formatted as an integer in base
1059 * sixteen. No localization is applied.
1060 *
1061 * <p> If <i>x</i> is negative then the result will be a signed value
1062 * beginning with <tt>'-'</tt> (<tt>'&#92;u002d'</tt>). Signed output is
1063 * allowed for this type because unlike the primitive types it is not
1064 * possible to create an unsigned equivalent without assuming an explicit
1065 * data-type size.
1066 *
1067 * <p> If <i>x</i> is positive or zero and the <tt>'+'</tt> flag is given
1068 * then the result will begin with <tt>'+'</tt> (<tt>'&#92;u002b'</tt>).
1069 *
1070 * <p> If the <tt>'#'</tt> flag is given then the output will always begin
1071 * with the radix indicator <tt>"0x"</tt>.
1072 *
1073 * <p> If the <tt>'0'</tt> flag is given then the output will be padded to
1074 * the field width with leading zeros after the radix indicator or sign (if
1075 * present).
1076 *
1077 * <p> If the <tt>','</tt> flag is given then a {@link
1078 * FormatFlagsConversionMismatchException} will be thrown.
1079 *
1080 * <tr><td valign="top"> <tt>'X'</tt>
1081 * <td valign="top"> <tt>'&#92;u0058'</tt>
1082 * <td> The upper-case variant of <tt>'x'</tt>. The entire string
1083 * representing the number will be converted to {@linkplain
1084 * String#toUpperCase upper case} including the <tt>'x'</tt> (if any) and
1085 * all hexadecimal digits <tt>'a'</tt> - <tt>'f'</tt>
1086 * (<tt>'&#92;u0061'</tt> - <tt>'&#92;u0066'</tt>).
1087 *
1088 * </table>
1089 *
1090 * <p> If the conversion is <tt>'o'</tt>, <tt>'x'</tt>, or <tt>'X'</tt> and
1091 * both the <tt>'#'</tt> and the <tt>'0'</tt> flags are given, then result will
1092 * contain the base indicator (<tt>'0'</tt> for octal and <tt>"0x"</tt> or
1093 * <tt>"0X"</tt> for hexadecimal), some number of zeros (based on the width),
1094 * and the value.
1095 *
1096 * <p> If the <tt>'0'</tt> flag is given and the value is negative, then the
1097 * zero padding will occur after the sign.
1098 *
1099 * <p> If the <tt>'-'</tt> flag is not given, then the space padding will occur
1100 * before the sign.
1101 *
1102 * <p> All <a HREF="#intFlags">flags</a> defined for Byte, Short, Integer, and
1103 * Long apply. The <a HREF="#intdFlags">default behavior</a> when no flags are
1104 * given is the same as for Byte, Short, Integer, and Long.
1105 *
1106 * <p> The specification of <a HREF="#intWidth">width</a> is the same as
1107 * defined for Byte, Short, Integer, and Long.
1108 *
1109 * <p> The precision is not applicable. If precision is specified then an
1110 * {@link IllegalFormatPrecisionException} will be thrown.
1111 *
1112 * <p><a name="dndec"><b> Float and Double</b><a>
1113 *
1114 * <p> The following conversions may be applied to <tt>float</tt>, {@link
1115 * Float}, <tt>double</tt> and {@link Double}.
1116 *
1117 * <table cellpadding=5 summary="floatConv">
1118 *
1119 * <tr><td valign="top"> <tt>'e'</tt>
1120 * <td valign="top"> <tt>'&#92;u0065'</tt>
1121 * <td> Requires the output to be formatted using <a
1122 * name="scientific">computerized scientific notation</a>. The <a
1123 * HREF="#l10n algorithm">localization algorithm</a> is applied.
1124 *
1125 * <p> The formatting of the magnitude <i>m</i> depends upon its value.
1126 *
1127 * <p> If <i>m</i> is NaN or infinite, the literal strings "NaN" or
1128 * "Infinity", respectively, will be output. These values are not
1129 * localized.
1130 *
1131 * <p> If <i>m</i> is positive-zero or negative-zero, then the exponent
1132 * will be <tt>"+00"</tt>.
1133 *
1134 * <p> Otherwise, the result is a string that represents the sign and
1135 * magnitude (absolute value) of the argument. The formatting of the sign
1136 * is described in the <a HREF="#l10n algorithm">localization
1137 * algorithm</a>. The formatting of the magnitude <i>m</i> depends upon its
1138 * value.
1139 *
1140 * <p> Let <i>n</i> be the unique integer such that 10<sup><i>n</i></sup>
1141 * &lt;= <i>m</i> &lt; 10<sup><i>n</i>+1</sup>; then let <i>a</i> be the
1142 * mathematically exact quotient of <i>m</i> and 10<sup><i>n</i></sup> so
1143 * that 1 &lt;= <i>a</i> &lt; 10. The magnitude is then represented as the
1144 * integer part of <i>a</i>, as a single decimal digit, followed by the
1145 * decimal separator followed by decimal digits representing the fractional
1146 * part of <i>a</i>, followed by the exponent symbol <tt>'e'</tt>
1147 * (<tt>'&#92;u0065'</tt>), followed by the sign of the exponent, followed
1148 * by a representation of <i>n</i> as a decimal integer, as produced by the
1149 * method {@link Long#toString(long, int)}, and zero-padded to include at
1150 * least two digits.
1151 *
1152 * <p> The number of digits in the result for the fractional part of
1153 * <i>m</i> or <i>a</i> is equal to the precision. If the precision is not
1154 * specified then the default value is <tt>6</tt>. If the precision is less
1155 * than the number of digits which would appear after the decimal point in
1156 * the string returned by {@link Float#toString(float)} or {@link
1157 * Double#toString(double)} respectively, then the value will be rounded
1158 * using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
1159 * algorithm}. Otherwise, zeros may be appended to reach the precision.
1160 * For a canonical representation of the value, use {@link
1161 * Float#toString(float)} or {@link Double#toString(double)} as
1162 * appropriate.
1163 *
1164 * <p>If the <tt>','</tt> flag is given, then an {@link
1165 * FormatFlagsConversionMismatchException} will be thrown.
1166 *
1167 * <tr><td valign="top"> <tt>'E'</tt>
1168 * <td valign="top"> <tt>'&#92;u0045'</tt>
1169 * <td> The upper-case variant of <tt>'e'</tt>. The exponent symbol
1170 * will be <tt>'E'</tt> (<tt>'&#92;u0045'</tt>).
1171 *
1172 * <tr><td valign="top"> <tt>'g'</tt>
1173 * <td valign="top"> <tt>'&#92;u0067'</tt>
1174 * <td> Requires the output to be formatted in general scientific notation
1175 * as described below. The <a HREF="#l10n algorithm">localization
1176 * algorithm</a> is applied.
1177 *
1178 * <p> After rounding for the precision, the formatting of the resulting
1179 * magnitude <i>m</i> depends on its value.
1180 *
1181 * <p> If <i>m</i> is greater than or equal to 10<sup>-4</sup> but less
1182 * than 10<sup>precision</sup> then it is represented in <i><a
1183 * HREF="#decimal">decimal format</a></i>.
1184 *
1185 * <p> If <i>m</i> is less than 10<sup>-4<sup> or greater than or equal to
1186 * 10<sup>precision</sup>, then it is represented in <i><a
1187 * HREF="#scientific">computerized scientific notation</a></i>.
1188 *
1189 * <p> The total number of significant digits in <i>m</i> is equal to the
1190 * precision. If the precision is not specified, then the default value is
1191 * <tt>6</tt>. If the precision is <tt>0</tt>, then it is taken to be
1192 * <tt>1</tt>.
1193 *
1194 * <p> If the <tt>'#'</tt> flag is given then an {@link
1195 * FormatFlagsConversionMismatchException} will be thrown.
1196 *
1197 * <tr><td valign="top"> <tt>'G'</tt>
1198 * <td valign="top"> <tt>'&#92;u0047'</tt>
1199 * <td> The upper-case variant of <tt>'g'</tt>.
1200 *
1201 * <tr><td valign="top"> <tt>'f'</tt>
1202 * <td valign="top"> <tt>'&#92;u0066'</tt>
1203 * <td> Requires the output to be formatted using <a name="decimal">decimal
1204 * format</a>. The <a HREF="#l10n algorithm">localization algorithm</a> is
1205 * applied.
1206 *
1207 * <p> The result is a string that represents the sign and magnitude
1208 * (absolute value) of the argument. The formatting of the sign is
1209 * described in the <a HREF="#l10n algorithm">localization
1210 * algorithm</a>. The formatting of the magnitude <i>m</i> depends upon its
1211 * value.
1212 *
1213 * <p> If <i>m</i> NaN or infinite, the literal strings "NaN" or
1214 * "Infinity", respectively, will be output. These values are not
1215 * localized.
1216 *
1217 * <p> The magnitude is formatted as the integer part of <i>m</i>, with no
1218 * leading zeroes, followed by the decimal separator followed by one or
1219 * more decimal digits representing the fractional part of <i>m</i>.
1220 *
1221 * <p> The number of digits in the result for the fractional part of
1222 * <i>m</i> or <i>a</i> is equal to the precision. If the precision is not
1223 * specified then the default value is <tt>6</tt>. If the precision is less
1224 * than the number of digits which would appear after the decimal point in
1225 * the string returned by {@link Float#toString(float)} or {@link
1226 * Double#toString(double)} respectively, then the value will be rounded
1227 * using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
1228 * algorithm}. Otherwise, zeros may be appended to reach the precision.
1229 * For a canonical representation of the value,use {@link
1230 * Float#toString(float)} or {@link Double#toString(double)} as
1231 * appropriate.
1232 *
1233 * <tr><td valign="top"> <tt>'a'</tt>
1234 * <td valign="top"> <tt>'&#92;u0061'</tt>
1235 * <td> Requires the output to be formatted in hexadecimal exponential
1236 * form. No localization is applied.
1237 *
1238 * <p> The result is a string that represents the sign and magnitude
1239 * (absolute value) of the argument <i>x</i>.
1240 *
1241 * <p> If <i>x</i> is negative or a negative-zero value then the result
1242 * will begin with <tt>'-'</tt> (<tt>'&#92;u002d'</tt>).
1243 *
1244 * <p> If <i>x</i> is positive or a positive-zero value and the
1245 * <tt>'+'</tt> flag is given then the result will begin with <tt>'+'</tt>
1246 * (<tt>'&#92;u002b'</tt>).
1247 *
1248 * <p> The formatting of the magnitude <i>m</i> depends upon its value.
1249 *
1250 * <ul>
1251 *
1252 * <li> If the value is NaN or infinite, the literal strings "NaN" or
1253 * "Infinity", respectively, will be output.
1254 *
1255 * <li> If <i>m</i> is zero then it is represented by the string
1256 * <tt>"0x0.0p0"</tt>.
1257 *
1258 * <li> If <i>m</i> is a <tt>double</tt> value with a normalized
1259 * representation then substrings are used to represent the significand and
1260 * exponent fields. The significand is represented by the characters
1261 * <tt>"0x1."</tt> followed by the hexadecimal representation of the rest
1262 * of the significand as a fraction. The exponent is represented by
1263 * <tt>'p'</tt> (<tt>'&#92;u0070'</tt>) followed by a decimal string of the
1264 * unbiased exponent as if produced by invoking {@link
1265 * Integer#toString(int) Integer.toString} on the exponent value.
1266 *
1267 * <li> If <i>m</i> is a <tt>double</tt> value with a subnormal
1268 * representation then the significand is represented by the characters
1269 * <tt>'0x0.'</tt> followed by the hexadecimal representation of the rest
1270 * of the significand as a fraction. The exponent is represented by
1271 * <tt>'p-1022'</tt>. Note that there must be at least one nonzero digit
1272 * in a subnormal significand.
1273 *
1274 * </ul>
1275 *
1276 * <p> If the <tt>'('</tt> or <tt>','</tt> flags are given, then a {@link
1277 * FormatFlagsConversionMismatchException} will be thrown.
1278 *
1279 * <tr><td valign="top"> <tt>'A'</tt>
1280 * <td valign="top"> <tt>'&#92;u0041'</tt>
1281 * <td> The upper-case variant of <tt>'a'</tt>. The entire string
1282 * representing the number will be converted to upper case including the
1283 * <tt>'x'</tt> (<tt>'&#92;u0078'</tt>) and <tt>'p'</tt>
1284 * (<tt>'&#92;u0070'</tt> and all hexadecimal digits <tt>'a'</tt> -
1285 * <tt>'f'</tt> (<tt>'&#92;u0061'</tt> - <tt>'&#92;u0066'</tt>).
1286 *
1287 * </table>
1288 *
1289 * <p> All <a HREF="#intFlags">flags</a> defined for Byte, Short, Integer, and
1290 * Long apply.
1291 *
1292 * <p> If the <tt>'#'</tt> flag is given, then the decimal separator will
1293 * always be present.
1294 *
1295 * <a name="floatdFlags"></a><p> If no flags are given the default formatting
1296 * is as follows:
1297 *
1298 * <ul>
1299 *
1300 * <li> The output is right-justified within the <tt>width</tt>
1301 *
1302 * <li> Negative numbers begin with a <tt>'-'</tt>
1303 *
1304 * <li> Positive numbers and positive zero do not include a sign or extra
1305 * leading space
1306 *
1307 * <li> No grouping separators are included
1308 *
1309 * <li> The decimal separator will only appear if a digit follows it
1310 *
1311 * </ul>
1312 *
1313 * <a name="floatDWidth"></a><p> The width is the minimum number of characters
1314 * to be written to the output. This includes any signs, digits, grouping
1315 * separators, decimal separators, exponential symbol, radix indicator,
1316 * parentheses, and strings representing infinity and NaN as applicable. If
1317 * the length of the converted value is less than the width then the output
1318 * will be padded by spaces (<tt>'&#92;u0020'</tt>) until the total number of
1319 * characters equals width. The padding is on the left by default. If the
1320 * <tt>'-'</tt> flag is given then the padding will be on the right. If width
1321 * is not specified then there is no minimum.
1322 *
1323 * <a name="floatDPrec"></a><p> If the conversion is <tt>'e'</tt>,
1324 * <tt>'E'</tt> or <tt>'f'</tt>, then the precision is the number of digits
1325 * after the decimal separator. If the precision is not specified, then it is
1326 * assumed to be <tt>6</tt>.
1327 *
1328 * <p> If the conversion is <tt>'g'</tt> or <tt>'G'</tt>, then the precision is
1329 * the total number of significant digits in the resulting magnitude after
1330 * rounding. If the precision is not specified, then the default value is
1331 * <tt>6</tt>. If the precision is <tt>0</tt>, then it is taken to be
1332 * <tt>1</tt>.
1333 *
1334 * <p> If the conversion is <tt>'a'</tt> or <tt>'A'</tt>, then the precision
1335 * is the number of hexadecimal digits after the decimal separator. If the
1336 * precision is not provided, then all of the digits as returned by {@link
1337 * Double#toHexString(double)} will be output.
1338 *
1339 * <p><a name="dndec"><b> BigDecimal </b><a>
1340 *
1341 * <p> The following conversions may be applied {@link java.math.BigDecimal
1342 * BigDecimal}.
1343 *
1344 * <table cellpadding=5 summary="floatConv">
1345 *
1346 * <tr><td valign="top"> <tt>'e'</tt>
1347 * <td valign="top"> <tt>'&#92;u0065'</tt>
1348 * <td> Requires the output to be formatted using <a
1349 * name="scientific">computerized scientific notation</a>. The <a
1350 * HREF="#l10n algorithm">localization algorithm</a> is applied.
1351 *
1352 * <p> The formatting of the magnitude <i>m</i> depends upon its value.
1353 *
1354 * <p> If <i>m</i> is positive-zero or negative-zero, then the exponent
1355 * will be <tt>"+00"</tt>.
1356 *
1357 * <p> Otherwise, the result is a string that represents the sign and
1358 * magnitude (absolute value) of the argument. The formatting of the sign
1359 * is described in the <a HREF="#l10n algorithm">localization
1360 * algorithm</a>. The formatting of the magnitude <i>m</i> depends upon its
1361 * value.
1362 *
1363 * <p> Let <i>n</i> be the unique integer such that 10<sup><i>n</i></sup>
1364 * &lt;= <i>m</i> &lt; 10<sup><i>n</i>+1</sup>; then let <i>a</i> be the
1365 * mathematically exact quotient of <i>m</i> and 10<sup><i>n</i></sup> so
1366 * that 1 &lt;= <i>a</i> &lt; 10. The magnitude is then represented as the
1367 * integer part of <i>a</i>, as a single decimal digit, followed by the
1368 * decimal separator followed by decimal digits representing the fractional
1369 * part of <i>a</i>, followed by the exponent symbol <tt>'e'</tt>
1370 * (<tt>'&#92;u0065'</tt>), followed by the sign of the exponent, followed
1371 * by a representation of <i>n</i> as a decimal integer, as produced by the
1372 * method {@link Long#toString(long, int)}, and zero-padded to include at
1373 * least two digits.
1374 *
1375 * <p> The number of digits in the result for the fractional part of
1376 * <i>m</i> or <i>a</i> is equal to the precision. If the precision is not
1377 * specified then the default value is <tt>6</tt>. If the precision is
1378 * less than the number of digits which would appear after the decimal
1379 * point in the string returned by {@link Float#toString(float)} or {@link
1380 * Double#toString(double)} respectively, then the value will be rounded
1381 * using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
1382 * algorithm}. Otherwise, zeros may be appended to reach the precision.
1383 * For a canonical representation of the value, use {@link
1384 * BigDecimal#toString()}.
1385 *
1386 * <p> If the <tt>','</tt> flag is given, then an {@link
1387 * FormatFlagsConversionMismatchException} will be thrown.
1388 *
1389 * <tr><td valign="top"> <tt>'E'</tt>
1390 * <td valign="top"> <tt>'&#92;u0045'</tt>
1391 * <td> The upper-case variant of <tt>'e'</tt>. The exponent symbol
1392 * will be <tt>'E'</tt> (<tt>'&#92;u0045'</tt>).
1393 *
1394 * <tr><td valign="top"> <tt>'g'</tt>
1395 * <td valign="top"> <tt>'&#92;u0067'</tt>
1396 * <td> Requires the output to be formatted in general scientific notation
1397 * as described below. The <a HREF="#l10n algorithm">localization
1398 * algorithm</a> is applied.
1399 *
1400 * <p> After rounding for the precision, the formatting of the resulting
1401 * magnitude <i>m</i> depends on its value.
1402 *
1403 * <p> If <i>m</i> is greater than or equal to 10<sup>-4</sup> but less
1404 * than 10<sup>precision</sup> then it is represented in <i><a
1405 * HREF="#decimal">decimal format</a></i>.
1406 *
1407 * <p> If <i>m</i> is less than 10<sup>-4</sup> or greater than or equal to
1408 * 10<sup>precision</sup>, then it is represented in <i><a
1409 * HREF="#scientific">computerized scientific notation</a></i>.
1410 *
1411 * <p> The total number of significant digits in <i>m</i> is equal to the
1412 * precision. If the precision is not specified, then the default value is
1413 * <tt>6</tt>. If the precision is <tt>0</tt>, then it is taken to be
1414 * <tt>1</tt>.
1415 *
1416 * <p> If the <tt>'#'</tt> flag is given then an {@link
1417 * FormatFlagsConversionMismatchException} will be thrown.
1418 *
1419 * <tr><td valign="top"> <tt>'G'</tt>
1420 * <td valign="top"> <tt>'&#92;u0047'</tt>
1421 * <td> The upper-case variant of <tt>'g'</tt>.
1422 *
1423 * <tr><td valign="top"> <tt>'f'</tt>
1424 * <td valign="top"> <tt>'&#92;u0066'</tt>
1425 * <td> Requires the output to be formatted using <a name="decimal">decimal
1426 * format</a>. The <a HREF="#l10n algorithm">localization algorithm</a> is
1427 * applied.
1428 *
1429 * <p> The result is a string that represents the sign and magnitude
1430 * (absolute value) of the argument. The formatting of the sign is
1431 * described in the <a HREF="#l10n algorithm">localization
1432 * algorithm</a>. The formatting of the magnitude <i>m</i> depends upon its
1433 * value.
1434 *
1435 * <p> The magnitude is formatted as the integer part of <i>m</i>, with no
1436 * leading zeroes, followed by the decimal separator followed by one or
1437 * more decimal digits representing the fractional part of <i>m</i>.
1438 *
1439 * <p> The number of digits in the result for the fractional part of
1440 * <i>m</i> or <i>a</i> is equal to the precision. If the precision is not
1441 * specified then the default value is <tt>6</tt>. If the precision is
1442 * less than the number of digits which would appear after the decimal
1443 * point in the string returned by {@link Float#toString(float)} or {@link
1444 * Double#toString(double)} respectively, then the value will be rounded
1445 * using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
1446 * algorithm}. Otherwise, zeros may be appended to reach the precision.
1447 * For a canonical representation of the value, use {@link
1448 * BigDecimal#toString()}.
1449 *
1450 * </table>
1451 *
1452 * <p> All <a HREF="#intFlags">flags</a> defined for Byte, Short, Integer, and
1453 * Long apply.
1454 *
1455 * <p> If the <tt>'#'</tt> flag is given, then the decimal separator will
1456 * always be present.
1457 *
1458 * <p> The <a HREF="#floatdFlags">default behavior</a> when no flags are
1459 * given is the same as for Float and Double.
1460 *
1461 * <p> The specification of <a HREF="#floatDWidth">width</a> and <a
1462 * HREF="#floatDPrec">precision</a> is the same as defined for Float and
1463 * Double.
1464 *
1465 * <a name="ddt"><h4> Date/Time </h4></a>
1466 *
1467 * <p> This conversion may be applied to <tt>long</tt>, {@link Long}, {@link
1468 * Calendar}, and {@link Date}.
1469 *
1470 * <table cellpadding=5 summary="DTConv">
1471 *
1472 * <tr><td valign="top"> <tt>'t'</tt>
1473 * <td valign="top"> <tt>'&#92;u0074'</tt>
1474 * <td> Prefix for date and time conversion characters.
1475 * <tr><td valign="top"> <tt>'T'</tt>
1476 * <td valign="top"> <tt>'&#92;u0054'</tt>
1477 * <td> The upper-case variant of <tt>'t'</tt>.
1478 *
1479 * </table>
1480 *
1481 * <p> The following date and time conversion character suffixes are defined
1482 * for the <tt>'t'</tt> and <tt>'T'</tt> conversions. The types are similar to
1483 * but not completely identical to those defined by GNU <tt>date</tt> and
1484 * POSIX <tt>strftime(3c)</tt>. Additional conversion types are provided to
1485 * access Java-specific functionality (e.g. <tt>'L'</tt> for milliseconds
1486 * within the second).
1487 *
1488 * <p> The following conversion characters are used for formatting times:
1489 *
1490 * <table cellpadding=5 summary="time">
1491 *
1492 * <tr><td valign="top"> <tt>'H'</tt>
1493 * <td valign="top"> <tt>'&#92;u0048'</tt>
1494 * <td> Hour of the day for the 24-hour clock, formatted as two digits with
1495 * a leading zero as necessary i.e. <tt>00 - 23</tt>. <tt>00</tt>
1496 * corresponds to midnight.
1497 *
1498 * <tr><td valign="top"><tt>'I'</tt>
1499 * <td valign="top"> <tt>'&#92;u0049'</tt>
1500 * <td> Hour for the 12-hour clock, formatted as two digits with a leading
1501 * zero as necessary, i.e. <tt>01 - 12</tt>. <tt>01</tt> corresponds to
1502 * one o'clock (either morning or afternoon).
1503 *
1504 * <tr><td valign="top"><tt>'k'</tt>
1505 * <td valign="top"> <tt>'&#92;u006b'</tt>
1506 * <td> Hour of the day for the 24-hour clock, i.e. <tt>0 - 23</tt>.
1507 * <tt>0</tt> corresponds to midnight.
1508 *
1509 * <tr><td valign="top"><tt>'l'</tt>
1510 * <td valign="top"> <tt>'&#92;u006c'</tt>
1511 * <td> Hour for the 12-hour clock, i.e. <tt>1 - 12</tt>. <tt>1</tt>
1512 * corresponds to one o'clock (either morning or afternoon).
1513 *
1514 * <tr><td valign="top"><tt>'M'</tt>
1515 * <td valign="top"> <tt>'&#92;u004d'</tt>
1516 * <td> Minute within the hour formatted as two digits with a leading zero
1517 * as necessary, i.e. <tt>00 - 59</tt>.
1518 *
1519 * <tr><td valign="top"><tt>'S'</tt>
1520 * <td valign="top"> <tt>'&#92;u0053'</tt>
1521 * <td> Seconds within the minute, formatted as two digits with a leading
1522 * zero as necessary, i.e. <tt>00 - 60</tt> ("<tt>60</tt>" is a special
1523 * value required to support leap seconds).
1524 *
1525 * <tr><td valign="top"><tt>'L'</tt>
1526 * <td valign="top"> <tt>'&#92;u004c'</tt>
1527 * <td> Millisecond within the second formatted as three digits with
1528 * leading zeros as necessary, i.e. <tt>000 - 999</tt>.
1529 *
1530 * <tr><td valign="top"><tt>'N'</tt>
1531 * <td valign="top"> <tt>'&#92;u004e'</tt>
1532 * <td> Nanosecond within the second, formatted as nine digits with leading
1533 * zeros as necessary, i.e. <tt>000000000 - 999999999</tt>. The precision
1534 * of this value is limited by the resolution of the underlying operating
1535 * system or hardware.
1536 *
1537 * <tr><td valign="top"><tt>'p'</tt>
1538 * <td valign="top"> <tt>'&#92;u0070'</tt>
1539 * <td> Locale-specific {@linkplain
1540 * java.text.DateFormatSymbols#getAmPmStrings morning or afternoon} marker
1541 * in lower case, e.g."<tt>am</tt>" or "<tt>pm</tt>". Use of the
1542 * conversion prefix <tt>'T'</tt> forces this output to upper case. (Note
1543 * that <tt>'p'</tt> produces lower-case output. This is different from
1544 * GNU <tt>date</tt> and POSIX <tt>strftime(3c)</tt> which produce
1545 * upper-case output.)
1546 *
1547 * <tr><td valign="top"><tt>'z'</tt>
1548 * <td valign="top"> <tt>'&#92;u007a'</tt>
1549 * <td> <a HREF="http://www.ietf.org/rfc/rfc0822.txt">RFC&nbsp;822</a>
1550 * style numeric time zone offset from GMT, e.g. <tt>-0800</tt>.
1551 *
1552 * <tr><td valign="top"><tt>'Z'</tt>
1553 * <td valign="top"> <tt>'&#92;u005a'</tt>
1554 * <td> A string representing the abbreviation for the time zone.
1555 *
1556 * <tr><td valign="top"><tt>'s'</tt>
1557 * <td valign="top"> <tt>'&#92;u0073'</tt>
1558 * <td> Seconds since the beginning of the epoch starting at 1 January 1970
1559 * <tt>00:00:00</tt> UTC, i.e. <tt>Long.MIN_VALUE/1000</tt> to
1560 * <tt>Long.MAX_VALUE/1000</tt>.
1561 *
1562 * <tr><td valign="top"><tt>'Q'</tt>
1563 * <td valign="top"> <tt>'&#92;u004f'</tt>
1564 * <td> Milliseconds since the beginning of the epoch starting at 1 January
1565 * 1970 <tt>00:00:00</tt> UTC, i.e. <tt>Long.MIN_VALUE</tt> to
1566 * <tt>Long.MAX_VALUE</tt>. The precision of this value is limited by
1567 * the resolution of the underlying operating system or hardware.
1568 *
1569 * </table>
1570 *
1571 * <p> The following conversion characters are used for formatting dates:
1572 *
1573 * <table cellpadding=5 summary="date">
1574 *
1575 * <tr><td valign="top"><tt>'B'</tt>
1576 * <td valign="top"> <tt>'&#92;u0042'</tt>
1577 * <td> Locale-specific {@linkplain java.text.DateFormatSymbols#getMonths
1578 * full month name}, e.g. <tt>"January"</tt>, <tt>"February"</tt>.
1579 *
1580 * <tr><td valign="top"><tt>'b'</tt>
1581 * <td valign="top"> <tt>'&#92;u0062'</tt>
1582 * <td> Locale-specific {@linkplain
1583 * java.text.DateFormatSymbols#getShortMonths abbreviated month name},
1584 * e.g. <tt>"Jan"</tt>, <tt>"Feb"</tt>.
1585 *
1586 * <tr><td valign="top"><tt>'h'</tt>
1587 * <td valign="top"> <tt>'&#92;u0068'</tt>
1588 * <td> Same as <tt>'b'</tt>.
1589 *
1590 * <tr><td valign="top"><tt>'A'</tt>
1591 * <td valign="top"> <tt>'&#92;u0041'</tt>
1592 * <td> Locale-specific full name of the {@linkplain
1593 * java.text.DateFormatSymbols#getWeekdays day of the week},
1594 * e.g. <tt>"Sunday"</tt>, <tt>"Monday"</tt>
1595 *
1596 * <tr><td valign="top"><tt>'a'</tt>
1597 * <td valign="top"> <tt>'&#92;u0061'</tt>
1598 * <td> Locale-specific short name of the {@linkplain
1599 * java.text.DateFormatSymbols#getShortWeekdays day of the week},
1600 * e.g. <tt>"Sun"</tt>, <tt>"Mon"</tt>
1601 *
1602 * <tr><td valign="top"><tt>'C'</tt>
1603 * <td valign="top"> <tt>'&#92;u0043'</tt>
1604 * <td> Four-digit year divided by <tt>100</tt>, formatted as two digits
1605 * with leading zero as necessary, i.e. <tt>00 - 99</tt>
1606 *
1607 * <tr><td valign="top"><tt>'Y'</tt>
1608 * <td valign="top"> <tt>'&#92;u0059'</tt> <td> Year, formatted to at least
1609 * four digits with leading zeros as necessary, e.g. <tt>0092</tt> equals
1610 * <tt>92</tt> CE for the Gregorian calendar.
1611 *
1612 * <tr><td valign="top"><tt>'y'</tt>
1613 * <td valign="top"> <tt>'&#92;u0079'</tt>
1614 * <td> Last two digits of the year, formatted with leading zeros as
1615 * necessary, i.e. <tt>00 - 99</tt>.
1616 *
1617 * <tr><td valign="top"><tt>'j'</tt>
1618 * <td valign="top"> <tt>'&#92;u006a'</tt>
1619 * <td> Day of year, formatted as three digits with leading zeros as
1620 * necessary, e.g. <tt>001 - 366</tt> for the Gregorian calendar.
1621 * <tt>001</tt> corresponds to the first day of the year.
1622 *
1623 * <tr><td valign="top"><tt>'m'</tt>
1624 * <td valign="top"> <tt>'&#92;u006d'</tt>
1625 * <td> Month, formatted as two digits with leading zeros as necessary,
1626 * i.e. <tt>01 - 13</tt>, where "<tt>01</tt>" is the first month of the
1627 * year and ("<tt>13</tt>" is a special value required to support lunar
1628 * calendars).
1629 *
1630 * <tr><td valign="top"><tt>'d'</tt>
1631 * <td valign="top"> <tt>'&#92;u0064'</tt>
1632 * <td> Day of month, formatted as two digits with leading zeros as
1633 * necessary, i.e. <tt>01 - 31</tt>, where "<tt>01</tt>" is the first day
1634 * of the month.
1635 *
1636 * <tr><td valign="top"><tt>'e'</tt>
1637 * <td valign="top"> <tt>'&#92;u0065'</tt>
1638 * <td> Day of month, formatted as two digits, i.e. <tt>1 - 31</tt> where
1639 * "<tt>1</tt>" is the first day of the month.
1640 *
1641 * </table>
1642 *
1643 * <p> The following conversion characters are used for formatting common
1644 * date/time compositions.
1645 *
1646 * <table cellpadding=5 summary="composites">
1647 *
1648 * <tr><td valign="top"><tt>'R'</tt>
1649 * <td valign="top"> <tt>'&#92;u0052'</tt>
1650 * <td> Time formatted for the 24-hour clock as <tt>"%tH:%tM"</tt>
1651 *
1652 * <tr><td valign="top"><tt>'T'</tt>
1653 * <td valign="top"> <tt>'&#92;u0054'</tt>
1654 * <td> Time formatted for the 24-hour clock as <tt>"%tH:%tM:%tS"</tt>.
1655 *
1656 * <tr><td valign="top"><tt>'r'</tt>
1657 * <td valign="top"> <tt>'&#92;u0072'</tt>
1658 * <td> Time formatted for the 12-hour clock as <tt>"%tI:%tM:%tS
1659 * %Tp"</tt>. The location of the morning or afternoon marker
1660 * (<tt>'%Tp'</tt>) may be locale-dependent.
1661 *
1662 * <tr><td valign="top"><tt>'D'</tt>
1663 * <td valign="top"> <tt>'&#92;u0044'</tt>
1664 * <td> Date formatted as <tt>"%tm/%td/%ty"</tt>.
1665 *
1666 * <tr><td valign="top"><tt>'F'</tt>
1667 * <td valign="top"> <tt>'&#92;u0046'</tt>
1668 * <td> <a HREF="http://www.w3.org/TR/NOTE-datetime">ISO&nbsp;8601</a>
1669 * complete date formatted as <tt>"%tY-%tm-%td"</tt>.
1670 *
1671 * <tr><td valign="top"><tt>'c'</tt>
1672 * <td valign="top"> <tt>'&#92;u0063'</tt>
1673 * <td> Date and time formatted as <tt>"%ta %tb %td %tT %tZ %tY"</tt>,
1674 * e.g. <tt>"Sun Jul 20 16:17:00 EDT 1969"</tt>.
1675 *
1676 * </table>
1677 *
1678 * <p> The <tt>'-'</tt> flag defined for <a HREF="#dFlags">General
1679 * conversions</a> applies. If the <tt>'#'</tt> flag is given, then a {@link
1680 * FormatFlagsConversionMismatchException} will be thrown.
1681 *
1682 * <a name="dtWidth"></a><p> The width is the minimum number of characters to
1683 * be written to the output. If the length of the converted value is less than
1684 * the <tt>width</tt> then the output will be padded by spaces
1685 * (<tt>'&#92;u0020'</tt>) until the total number of characters equals width.
1686 * The padding is on the left by default. If the <tt>'-'</tt> flag is given
1687 * then the padding will be on the right. If width is not specified then there
1688 * is no minimum.
1689 *
1690 * <p> The precision is not applicable. If the precision is specified then an
1691 * {@link IllegalFormatPrecisionException} will be thrown.
1692 *
1693 * <a name="dper"><h4> Percent </h4></a>
1694 *
1695 * <p> The conversion does not correspond to any argument.
1696 *
1697 * <table cellpadding=5 summary="DTConv">
1698 *
1699 * <tr><td valign="top"><tt>'%'</tt>
1700 * <td> The result is a literal <tt>'%'</tt> (<tt>'&#92;u0025'</tt>)
1701 *
1702 * <a name="dtWidth"></a><p> The width is the minimum number of characters to
1703 * be written to the output including the <tt>'%'</tt>. If the length of the
1704 * converted value is less than the <tt>width</tt> then the output will be
1705 * padded by spaces (<tt>'&#92;u0020'</tt>) until the total number of
1706 * characters equals width. The padding is on the left. If width is not
1707 * specified then just the <tt>'%'</tt> is output.
1708 *
1709 * <p> The <tt>'-'</tt> flag defined for <a HREF="#dFlags">General
1710 * conversions</a> applies. If any other flags are provided, then a
1711 * {@link FormatFlagsConversionMismatchException} will be thrown.
1712 *
1713 * <p> The precision is not applicable. If the precision is specified an
1714 * {@link IllegalFormatPrecisionException} will be thrown.
1715 *
1716 * </table>
1717 *
1718 * <a name="dls"><h4> Line Separator </h4></a>
1719 *
1720 * <p> The conversion does not correspond to any argument.
1721 *
1722 * <table cellpadding=5 summary="DTConv">
1723 *
1724 * <tr><td valign="top"><tt>'n'</tt>
1725 * <td> the platform-specific line separator as returned by {@link
1726 * System#getProperty System.getProperty("line.separator")}.
1727 *
1728 * </table>
1729 *
1730 * <p> Flags, width, and precision are not applicable. If any are provided an
1731 * {@link IllegalFormatFlagsException}, {@link IllegalFormatWidthException},
1732 * and {@link IllegalFormatPrecisionException}, respectively will be thrown.
1733 *
1734 * <a name="dpos"><h4> Argument Index </h4></a>
1735 *
1736 * <p> Format specifiers can reference arguments in three ways:
1737 *
1738 * <ul>
1739 *
1740 * <li> <i>Explicit indexing</i> is used when the format specifier contains an
1741 * argument index. The argument index is a decimal integer indicating the
1742 * position of the argument in the argument list. The first argument is
1743 * referenced by "<tt>1$</tt>", the second by "<tt>2$</tt>", etc. An argument
1744 * may be referenced more than once.
1745 *
1746 * <p> For example:
1747 *
1748 * <blockquote><pre>
1749 * formatter.format("%4$s %3$s %2$s %1$s %4$s %3$s %2$s %1$s",
1750 * "a", "b", "c", "d")
1751 * // -> "d c b a d c b a"
1752 * </pre></blockquote>
1753 *
1754 * <li> <i>Relative indexing</i> is used when the format specifier contains a
1755 * <tt>'<'</tt> (<tt>'&#92;u003c'</tt>) flag which causes the argument for the
1756 * previous format specifier to be re-used. If there is no previous argument,
1757 * then a {@link MissingFormatArgumentException} is thrown.
1758 *
1759 * <blockquote><pre>
1760 * formatter.format("%s %s %&lt;s %&lt;s", "a", "b", "c", "d")
1761 * // -> "a b b b"
1762 * // "c" and "d" are ignored because they are not referenced
1763 * </pre></blockquote>
1764 *
1765 * <li> <i>Ordinary indexing</i> is used when the format specifier contains
1766 * neither an argument index nor a <tt>'<'</tt> flag. Each format specifier
1767 * which uses ordinary indexing is assigned a sequential implicit index into
1768 * argument list which is independent of the indices used by explicit or
1769 * relative indexing.
1770 *
1771 * <blockquote><pre>
1772 * formatter.format("%s %s %s %s", "a", "b", "c", "d")
1773 * // -> "a b c d"
1774 * </pre></blockquote>
1775 *
1776 * </ul>
1777 *
1778 * <p> It is possible to have a format string which uses all forms of indexing,
1779 * for example:
1780 *
1781 * <blockquote><pre>
1782 * formatter.format("%2$s %s %&lt;s %s", "a", "b", "c", "d")
1783 * // -> "b a a b"
1784 * // "c" and "d" are ignored because they are not referenced
1785 * </pre></blockquote>
1786 *
1787 * <p> The maximum number of arguments is limited by the maximum dimension of a
1788 * Java array as defined by the <a
1789 * HREF="http://java.sun.com/docs/books/vmspec/">Java Virtual Machine
1790 * Specification</a>. If the argument index is does not correspond to an
1791 * available argument, then a {@link MissingFormatArgumentException} is thrown.
1792 *
1793 * <p> If there are more arguments than format specifiers, the extra arguments
1794 * are ignored.
1795 *
1796 * <p> Unless otherwise specified, passing a <tt>null</tt> argument to any
1797 * method or constructor in this class will cause a {@link
1798 * NullPointerException} to be thrown.
1799 *
1800 * @author Iris Garcia
1801 * @version 1.16, 01/04/05
1802 * @since 1.5
1803 */

1804public final class Formatter implements Closeable JavaDoc, Flushable JavaDoc {
1805    private Appendable JavaDoc a;
1806    private Locale JavaDoc l;
1807
1808    private IOException JavaDoc lastException;
1809
1810    private char zero = '0';
1811    private static double scaleUp;
1812
1813    // 1 (sign) + 19 (max # sig digits) + 1 ('.') + 1 ('e') + 1 (sign)
1814
// + 3 (max # exp digits) + 4 (error) = 30
1815
private static final int MAX_FD_CHARS = 30;
1816
1817    // Initialize internal data.
1818
private void init(Appendable JavaDoc a, Locale JavaDoc l) {
1819    this.a = a;
1820    this.l = l;
1821    setZero();
1822    }
1823
1824    /**
1825     * Constructs a new formatter.
1826     *
1827     * <p> The destination of the formatted output is a {@link StringBuilder}
1828     * which may be retrieved by invoking {@link #out out()} and whose
1829     * current content may be converted into a string by invoking {@link
1830     * #toString toString()}. The locale used is the {@linkplain
1831     * Locale#getDefault() default locale} for this instance of the Java
1832     * virtual machine.
1833     */

1834    public Formatter() {
1835    init(new StringBuilder JavaDoc(), Locale.getDefault());
1836    }
1837
1838    /**
1839     * Constructs a new formatter with the specified destination.
1840     *
1841     * <p> The locale used is the {@linkplain Locale#getDefault() default
1842     * locale} for this instance of the Java virtual machine.
1843     *
1844     * @param a
1845     * Destination for the formatted output. If <tt>a</tt> is
1846     * <tt>null</tt> then a {@link StringBuilder} will be created.
1847     */

1848    public Formatter(Appendable JavaDoc a) {
1849    init(a, Locale.getDefault());
1850    }
1851
1852    /**
1853     * Constructs a new formatter with the specified locale.
1854     *
1855     * <p> The destination of the formatted output is a {@link StringBuilder}
1856     * which may be retrieved by invoking {@link #out out()} and whose current
1857     * content may be converted into a string by invoking {@link #toString
1858     * toString()}.
1859     *
1860     * @param l
1861     * The {@linkplain java.util.Locale locale} to apply during
1862     * formatting. If <tt>l</tt> is <tt>null</tt> then no localization
1863     * is applied.
1864     */

1865    public Formatter(Locale JavaDoc l) {
1866    init(new StringBuilder JavaDoc(), l);
1867    }
1868
1869    /**
1870     * Constructs a new formatter with the specified destination and locale.
1871     *
1872     * @param a
1873     * Destination for the formatted output. If <tt>a</tt> is
1874     * <tt>null</tt> then a {@link StringBuilder} will be created.
1875     *
1876     * @param l
1877     * The {@linkplain java.util.Locale locale} to apply during
1878     * formatting. If <tt>l</tt> is <tt>null</tt> then no localization
1879     * is applied.
1880     */

1881    public Formatter(Appendable JavaDoc a, Locale JavaDoc l) {
1882    if (a == null)
1883        a = new StringBuilder JavaDoc();
1884    init(a, l);
1885    }
1886
1887    /**
1888     * Constructs a new formatter with the specified file name.
1889     *
1890     * <p> The charset used is the {@linkplain
1891     * java.nio.charset.Charset#defaultCharset default charset} for this
1892     * instance of the Java virtual machine.
1893     *
1894     * <p> The locale used is the {@linkplain Locale#getDefault() default
1895     * locale} for this instance of the Java virtual machine.
1896     *
1897     * @param fileName
1898     * The name of the file to use as the destination of this
1899     * formatter. If the file exists then it will be truncated to
1900     * zero size; otherwise, a new file will be created. The output
1901     * will be written to the file and is buffered.
1902     *
1903     * @throws SecurityException
1904     * If a security manager is present and {@link
1905     * SecurityManager#checkWrite checkWrite(fileName)} denies write
1906     * access to the file
1907     *
1908     * @throws FileNotFoundException
1909     * If the given file name does not denote an existing, writable
1910     * regular file and a new regular file of that name cannot be
1911     * created, or if some other error occurs while opening or
1912     * creating the file
1913     */

1914    public Formatter(String JavaDoc fileName) throws FileNotFoundException JavaDoc {
1915    init(new BufferedWriter JavaDoc(new OutputStreamWriter JavaDoc(new FileOutputStream JavaDoc(fileName))),
1916         Locale.getDefault());
1917    }
1918
1919    /**
1920     * Constructs a new formatter with the specified file name and charset.
1921     *
1922     * <p> The locale used is the {@linkplain Locale#getDefault default
1923     * locale} for this instance of the Java virtual machine.
1924     *
1925     * @param fileName
1926     * The name of the file to use as the destination of this
1927     * formatter. If the file exists then it will be truncated to
1928     * zero size; otherwise, a new file will be created. The output
1929     * will be written to the file and is buffered.
1930     *
1931     * @param csn
1932     * The name of a supported {@linkplain java.nio.charset.Charset
1933     * charset}
1934     *
1935     * @throws FileNotFoundException
1936     * If the given file name does not denote an existing, writable
1937     * regular file and a new regular file of that name cannot be
1938     * created, or if some other error occurs while opening or
1939     * creating the file
1940     *
1941     * @throws SecurityException
1942     * If a security manager is present and {@link
1943     * SecurityManager#checkWrite checkWrite(fileName)} denies write
1944     * access to the file
1945     *
1946     * @throws UnsupportedEncodingException
1947     * If the named charset is not supported
1948     */

1949    public Formatter(String JavaDoc fileName, String JavaDoc csn)
1950    throws FileNotFoundException JavaDoc, UnsupportedEncodingException JavaDoc
1951    {
1952    this(fileName, csn, Locale.getDefault());
1953    }
1954
1955    /**
1956     * Constructs a new formatter with the specified file name, charset, and
1957     * locale.
1958     *
1959     * @param fileName
1960     * The name of the file to use as the destination of this
1961     * formatter. If the file exists then it will be truncated to
1962     * zero size; otherwise, a new file will be created. The output
1963     * will be written to the file and is buffered.
1964     *
1965     * @param csn
1966     * The name of a supported {@linkplain java.nio.charset.Charset
1967     * charset}
1968     *
1969     * @param l
1970     * The {@linkplain java.util.Locale locale} to apply during
1971     * formatting. If <tt>l</tt> is <tt>null</tt> then no localization
1972     * is applied.
1973     *
1974     * @throws FileNotFoundException
1975     * If the given file name does not denote an existing, writable
1976     * regular file and a new regular file of that name cannot be
1977     * created, or if some other error occurs while opening or
1978     * creating the file
1979     *
1980     * @throws SecurityException
1981     * If a security manager is present and {@link
1982     * SecurityManager#checkWrite checkWrite(fileName)} denies write
1983     * access to the file
1984     *
1985     * @throws UnsupportedEncodingException
1986     * If the named charset is not supported
1987     */

1988    public Formatter(String JavaDoc fileName, String JavaDoc csn, Locale JavaDoc l)
1989    throws FileNotFoundException JavaDoc, UnsupportedEncodingException JavaDoc
1990    {
1991    init(new BufferedWriter JavaDoc(new OutputStreamWriter JavaDoc(new FileOutputStream JavaDoc(fileName), csn)),
1992         l);
1993    }
1994
1995    /**
1996     * Constructs a new formatter with the specified file.
1997     *
1998     * <p> The charset used is the {@linkplain
1999     * java.nio.charset.Charset#defaultCharset default charset} for this
2000     * instance of the Java virtual machine.
2001     *
2002     * <p> The locale used is the {@linkplain Locale#getDefault() default
2003     * locale} for this instance of the Java virtual machine.
2004     *
2005     * @param file
2006     * The file to use as the destination of this formatter. If the
2007     * file exists then it will be truncated to zero size; otherwise,
2008     * a new file will be created. The output will be written to the
2009     * file and is buffered.
2010     *
2011     * @throws SecurityException
2012     * If a security manager is present and {@link
2013     * SecurityManager#checkWrite checkWrite(file.getPath())} denies
2014     * write access to the file
2015     *
2016     * @throws FileNotFoundException
2017     * If the given file object does not denote an existing, writable
2018     * regular file and a new regular file of that name cannot be
2019     * created, or if some other error occurs while opening or
2020     * creating the file
2021     */

2022    public Formatter(File JavaDoc file) throws FileNotFoundException JavaDoc {
2023    init(new BufferedWriter JavaDoc(new OutputStreamWriter JavaDoc(new FileOutputStream JavaDoc(file))),
2024         Locale.getDefault());
2025    }
2026
2027    /**
2028     * Constructs a new formatter with the specified file and charset.
2029     *
2030     * <p> The locale used is the {@linkplain Locale#getDefault default
2031     * locale} for this instance of the Java virtual machine.
2032     *
2033     * @param file
2034     * The file to use as the destination of this formatter. If the
2035     * file exists then it will be truncated to zero size; otherwise,
2036     * a new file will be created. The output will be written to the
2037     * file and is buffered.
2038     *
2039     * @param csn
2040     * The name of a supported {@linkplain java.nio.charset.Charset
2041     * charset}
2042     *
2043     * @throws FileNotFoundException
2044     * If the given file object does not denote an existing, writable
2045     * regular file and a new regular file of that name cannot be
2046     * created, or if some other error occurs while opening or
2047     * creating the file
2048     *
2049     * @throws SecurityException
2050     * If a security manager is present and {@link
2051     * SecurityManager#checkWrite checkWrite(file.getPath())} denies
2052     * write access to the file
2053     *
2054     * @throws UnsupportedEncodingException
2055     * If the named charset is not supported
2056     */

2057    public Formatter(File JavaDoc file, String JavaDoc csn)
2058    throws FileNotFoundException JavaDoc, UnsupportedEncodingException JavaDoc
2059    {
2060    this(file, csn, Locale.getDefault());
2061    }
2062
2063    /**
2064     * Constructs a new formatter with the specified file, charset, and
2065     * locale.
2066     *
2067     * @param file
2068     * The file to use as the destination of this formatter. If the
2069     * file exists then it will be truncated to zero size; otherwise,
2070     * a new file will be created. The output will be written to the
2071     * file and is buffered.
2072     *
2073     * @param csn
2074     * The name of a supported {@linkplain java.nio.charset.Charset
2075     * charset}
2076     *
2077     * @param l
2078     * The {@linkplain java.util.Locale locale} to apply during
2079     * formatting. If <tt>l</tt> is <tt>null</tt> then no localization
2080     * is applied.
2081     *
2082     * @throws FileNotFoundException
2083     * If the given file object does not denote an existing, writable
2084     * regular file and a new regular file of that name cannot be
2085     * created, or if some other error occurs while opening or
2086     * creating the file
2087     *
2088     * @throws SecurityException
2089     * If a security manager is present and {@link
2090     * SecurityManager#checkWrite checkWrite(file.getPath())} denies
2091     * write access to the file
2092     *
2093     * @throws UnsupportedEncodingException
2094     * If the named charset is not supported
2095     */

2096    public Formatter(File JavaDoc file, String JavaDoc csn, Locale JavaDoc l)
2097    throws FileNotFoundException JavaDoc, UnsupportedEncodingException JavaDoc
2098    {
2099    init(new BufferedWriter JavaDoc(new OutputStreamWriter JavaDoc(new FileOutputStream JavaDoc(file), csn)),
2100         l);
2101    }
2102
2103    /**
2104     * Constructs a new formatter with the specified print stream.
2105     *
2106     * <p> The locale used is the {@linkplain Locale#getDefault() default
2107     * locale} for this instance of the Java virtual machine.
2108     *
2109     * <p> Characters are written to the given {@link java.io.PrintStream
2110     * PrintStream} object and are therefore encoded using that object's
2111     * charset.
2112     *
2113     * @param ps
2114     * The stream to use as the destination of this formatter.
2115     */

2116    public Formatter(PrintStream JavaDoc ps) {
2117    if (ps == null)
2118        throw new NullPointerException JavaDoc();
2119    init((Appendable JavaDoc)ps, Locale.getDefault());
2120    }
2121
2122    /**
2123     * Constructs a new formatter with the specified output stream.
2124     *
2125     * <p> The charset used is the {@linkplain
2126     * java.nio.charset.Charset#defaultCharset default charset} for this
2127     * instance of the Java virtual machine.
2128     *
2129     * <p> The locale used is the {@linkplain Locale#getDefault() default
2130     * locale} for this instance of the Java virtual machine.
2131     *
2132     * @param os
2133     * The output stream to use as the destination of this formatter.
2134     * The output will be buffered.
2135     */

2136    public Formatter(OutputStream JavaDoc os) {
2137    init(new BufferedWriter JavaDoc(new OutputStreamWriter JavaDoc(os)),
2138         Locale.getDefault());
2139    }
2140
2141    /**
2142     * Constructs a new formatter with the specified output stream and
2143     * charset.
2144     *
2145     * <p> The locale used is the {@linkplain Locale#getDefault default
2146     * locale} for this instance of the Java virtual machine.
2147     *
2148     * @param os
2149     * The output stream to use as the destination of this formatter.
2150     * The output will be buffered.
2151     *
2152     * @param csn
2153     * The name of a supported {@linkplain java.nio.charset.Charset
2154     * charset}
2155     *
2156     * @throws UnsupportedEncodingException
2157     * If the named charset is not supported
2158     */

2159    public Formatter(OutputStream JavaDoc os, String JavaDoc csn)
2160    throws UnsupportedEncodingException JavaDoc
2161    {
2162    this(os, csn, Locale.getDefault());
2163    }
2164
2165    /**
2166     * Constructs a new formatter with the specified output stream, charset,
2167     * and locale.
2168     *
2169     * @param os
2170     * The output stream to use as the destination of this formatter.
2171     * The output will be buffered.
2172     *
2173     * @param csn
2174     * The name of a supported {@linkplain java.nio.charset.Charset
2175     * charset}
2176     *
2177     * @param l
2178     * The {@linkplain java.util.Locale locale} to apply during
2179     * formatting. If <tt>l</tt> is <tt>null</tt> then no localization
2180     * is applied.
2181     *
2182     * @throws UnsupportedEncodingException
2183     * If the named charset is not supported
2184     */

2185    public Formatter(OutputStream JavaDoc os, String JavaDoc csn, Locale JavaDoc l)
2186    throws UnsupportedEncodingException JavaDoc
2187    {
2188    init(new BufferedWriter JavaDoc(new OutputStreamWriter JavaDoc(os, csn)), l);
2189    }
2190
2191    private void setZero() {
2192    if ((l != null) && !l.equals(Locale.US)) {
2193        DecimalFormatSymbols JavaDoc dfs = new DecimalFormatSymbols JavaDoc(l);
2194        zero = dfs.getZeroDigit();
2195    }
2196    }
2197
2198    /**
2199     * Returns the locale set by the construction of this formatter.
2200     *
2201     * <p> The {@link #format(java.util.Locale,String,Object...) format} method
2202     * for this object which has a locale argument does not change this value.
2203     *
2204     * @return <tt>null</tt> if no localization is applied, otherwise a
2205     * locale
2206     *
2207     * @throws FormatterClosedException
2208     * If this formatter has been closed by invoking its {@link
2209     * #close()} method
2210     */

2211    public Locale JavaDoc locale() {
2212    ensureOpen();
2213    return l;
2214    }
2215
2216    /**
2217     * Returns the destination for the output.
2218     *
2219     * @return The destination for the output
2220     *
2221     * @throws FormatterClosedException
2222     * If this formatter has been closed by invoking its {@link
2223     * #close()} method
2224     */

2225    public Appendable JavaDoc out() {
2226    ensureOpen();
2227    return a;
2228    }
2229
2230    /**
2231     * Returns the result of invoking <tt>toString()</tt> on the destination
2232     * for the output. For example, the following code formats text into a
2233     * {@link StringBuilder} then retrieves the resultant string:
2234     *
2235     * <blockquote><pre>
2236     * Formatter f = new Formatter();
2237     * f.format("Last reboot at %tc", lastRebootDate);
2238     * String s = f.toString();
2239     * // -> s == "Last reboot at Sat Jan 01 00:00:00 PST 2000"
2240     * </pre></blockquote>
2241     *
2242     * <p> An invocation of this method behaves in exactly the same way as the
2243     * invocation
2244     *
2245     * <pre>
2246     * out().toString() </pre>
2247     *
2248     * <p> Depending on the specification of <tt>toString</tt> for the {@link
2249     * Appendable}, the returned string may or may not contain the characters
2250     * written to the destination. For instance, buffers typically return
2251     * their contents in <tt>toString()</tt>, but streams cannot since the
2252     * data is discarded.
2253     *
2254     * @return The result of invoking <tt>toString()</tt> on the destination
2255     * for the output
2256     *
2257     * @throws FormatterClosedException
2258     * If this formatter has been closed by invoking its {@link
2259     * #close()} method
2260     */

2261    public String JavaDoc toString() {
2262    ensureOpen();
2263    return a.toString();
2264    }
2265
2266    /**
2267     * Flushes this formatter. If the destination implements the {@link
2268     * java.io.Flushable} interface, its <tt>flush</tt> method will be invoked.
2269     *
2270     * <p> Flushing a formatter writes any buffered output in the destination
2271     * to the underlying stream.
2272     *
2273     * @throws FormatterClosedException
2274     * If this formatter has been closed by invoking its {@link
2275     * #close()} method
2276     */

2277    public void flush() {
2278    ensureOpen();
2279    if (a instanceof Flushable JavaDoc) {
2280        try {
2281                ((Flushable JavaDoc)a).flush();
2282            } catch (IOException JavaDoc ioe) {
2283                lastException = ioe;
2284            }
2285        }
2286    }
2287
2288    /**
2289     * Closes this formatter. If the destination implements the {@link
2290     * java.io.Closeable} interface, its <tt>close</tt> method will be invoked.
2291     *
2292     * <p> Closing a formatter allows it to release resources it may be holding
2293     * (such as open files). If the formatter is already closed, then invoking
2294     * this method has no effect.
2295     *
2296     * <p> Attempting to invoke any methods except {@link #ioException()} in
2297     * this formatter after it has been closed will result in a {@link
2298     * FormatterClosedException}.
2299     */

2300    public void close() {
2301    if (a == null)
2302        return;
2303    try {
2304        if (a instanceof Closeable JavaDoc)
2305                ((Closeable JavaDoc)a).close();
2306    } catch (IOException JavaDoc ioe) {
2307        lastException = ioe;
2308    } finally {
2309        a = null;
2310        }
2311    }
2312
2313    private void ensureOpen() {
2314    if (a == null)
2315        throw new FormatterClosedException JavaDoc();
2316    }
2317
2318    /**
2319     * Returns the <tt>IOException</tt> last thrown by this formatter's {@link
2320     * Appendable}.
2321     *
2322     * <p> If the destination's <tt>append()</tt> method never throws
2323     * <tt>IOException</tt>, then this method will always return <tt>null</tt>.
2324     *
2325     * @return The last exception thrown by the Appendable or <tt>null</tt> if
2326     * no such exception exists.
2327     */

2328    public IOException JavaDoc ioException() {
2329        return lastException;
2330    }
2331
2332    /**
2333     * Writes a formatted string to this object's destination using the
2334     * specified format string and arguments. The locale used is the one
2335     * defined during the construction of this formatter.
2336     *
2337     * @param format
2338     * A format string as described in <a HREF="#syntax">Format string
2339     * syntax</a>.
2340     *
2341     * @param args
2342     * Arguments referenced by the format specifiers in the format
2343     * string. If there are more arguments than format specifiers, the
2344     * extra arguments are ignored. The maximum number of arguments is
2345     * limited by the maximum dimension of a Java array as defined by
2346     * the <a HREF="http://java.sun.com/docs/books/vmspec/">Java
2347     * Virtual Machine Specification</a>.
2348     *
2349     * @throws IllegalFormatException
2350     * If a format string contains an illegal syntax, a format
2351     * specifier that is incompatible with the given arguments,
2352     * insufficient arguments given the format string, or other
2353     * illegal conditions. For specification of all possible
2354     * formatting errors, see the <a HREF="#detail">Details</a>
2355     * section of the formatter class specification.
2356     *
2357     * @throws FormatterClosedException
2358     * If this formatter has been closed by invoking its {@link
2359     * #close()} method
2360     *
2361     * @return This formatter
2362     */

2363    public Formatter JavaDoc format(String JavaDoc format, Object JavaDoc ... args) {
2364    return format(l, format, args);
2365    }
2366
2367    /**
2368     * Writes a formatted string to this object's destination using the
2369     * specified locale, format string, and arguments.
2370     *
2371     * @param l
2372     * The {@linkplain java.util.Locale locale} to apply during
2373     * formatting. If <tt>l</tt> is <tt>null</tt> then no localization
2374     * is applied. This does not change this object's locale that was
2375     * set during construction.
2376     *
2377     * @param format
2378     * A format string as described in <a HREF="#syntax">Format string
2379     * syntax</a>
2380     *
2381     * @param args
2382     * Arguments referenced by the format specifiers in the format
2383     * string. If there are more arguments than format specifiers, the
2384     * extra arguments are ignored. The maximum number of arguments is
2385     * limited by the maximum dimension of a Java array as defined by
2386     * the <a HREF="http://java.sun.com/docs/books/vmspec/">Java
2387     * Virtual Machine Specification</a>
2388     *
2389     * @throws IllegalFormatException
2390     * If a format string contains an illegal syntax, a format
2391     * specifier that is incompatible with the given arguments,
2392     * insufficient arguments given the format string, or other
2393     * illegal conditions. For specification of all possible
2394     * formatting errors, see the <a HREF="#detail">Details</a>
2395     * section of the formatter class specification.
2396     *
2397     * @throws FormatterClosedException
2398     * If this formatter has been closed by invoking its {@link
2399     * #close()} method
2400     *
2401     * @return This formatter
2402     */

2403    public Formatter JavaDoc format(Locale JavaDoc l, String JavaDoc format, Object JavaDoc ... args) {
2404    ensureOpen();
2405
2406    // index of last argument referenced
2407
int last = -1;
2408    // last ordinary index
2409
int lasto = -1;
2410
2411    FormatString[] fsa = parse(format);
2412    for (int i = 0; i < fsa.length; i++) {
2413        FormatString fs = fsa[i];
2414        int index = fs.index();
2415        try {
2416        switch (index) {
2417        case -2: // fixed string, "%n", or "%%"
2418
fs.print(null, l);
2419            break;
2420        case -1: // relative index
2421
if (last < 0 || (args != null && last > args.length - 1))
2422            throw new MissingFormatArgumentException JavaDoc(fs.toString());
2423            fs.print((args == null ? null : args[last]), l);
2424            break;
2425        case 0: // ordinary index
2426
lasto++;
2427            last = lasto;
2428            if (args != null && lasto > args.length - 1)
2429            throw new MissingFormatArgumentException JavaDoc(fs.toString());
2430            fs.print((args == null ? null : args[lasto]), l);
2431            break;
2432        default: // explicit index
2433
last = index - 1;
2434            if (args != null && last > args.length - 1)
2435            throw new MissingFormatArgumentException JavaDoc(fs.toString());
2436            fs.print((args == null ? null : args[last]), l);
2437            break;
2438        }
2439        } catch (IOException JavaDoc x) {
2440        lastException = x;
2441        }
2442    }
2443    return this;
2444    }
2445
2446    // %[argument_index$][flags][width][.precision][t]conversion
2447
private static final String JavaDoc formatSpecifier
2448    = "%(\\d+\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])";
2449
2450    private static Pattern JavaDoc fsPattern = Pattern.compile(formatSpecifier);
2451
2452    // Look for format specifiers in the format string.
2453
private FormatString[] parse(String JavaDoc s) {
2454    ArrayList JavaDoc al = new ArrayList JavaDoc();
2455    Matcher JavaDoc m = fsPattern.matcher(s);
2456    int i = 0;
2457    while (i < s.length()) {
2458        if (m.find(i)) {
2459        // Anything between the start of the string and the beginning
2460
// of the format specifier is either fixed text or contains
2461
// an invalid format string.
2462
if (m.start() != i) {
2463            // Make sure we didn't miss any invalid format specifiers
2464
checkText(s.substring(i, m.start()));
2465            // Assume previous characters were fixed text
2466
al.add(new FixedString(s.substring(i, m.start())));
2467        }
2468
2469        // Expect 6 groups in regular expression
2470
String JavaDoc[] sa = new String JavaDoc[6];
2471        for (int j = 0; j < m.groupCount(); j++)
2472            {
2473            sa[j] = m.group(j + 1);
2474// System.out.print(sa[j] + " ");
2475
}
2476// System.out.println();
2477
al.add(new FormatSpecifier(this, sa));
2478        i = m.end();
2479        } else {
2480        // No more valid format specifiers. Check for possible invalid
2481
// format specifiers.
2482
checkText(s.substring(i));
2483        // The rest of the string is fixed text
2484
al.add(new FixedString(s.substring(i)));
2485        break;
2486        }
2487    }
2488// FormatString[] fs = new FormatString[al.size()];
2489
// for (int j = 0; j < al.size(); j++)
2490
// System.out.println(((FormatString) al.get(j)).toString());
2491
return (FormatString[]) al.toArray(new FormatString[0]);
2492    }
2493
2494    private void checkText(String JavaDoc s) {
2495    int idx;
2496    // If there are any '%' in the given string, we got a bad format
2497
// specifier.
2498
if ((idx = s.indexOf('%')) != -1) {
2499        char c = (idx > s.length() - 2 ? '%' : s.charAt(idx + 1));
2500        throw new UnknownFormatConversionException JavaDoc(String.valueOf(c));
2501    }
2502    }
2503
2504    private interface FormatString {
2505    int index();
2506    void print(Object JavaDoc arg, Locale JavaDoc l) throws IOException JavaDoc;
2507    String JavaDoc toString();
2508    }
2509
2510    private class FixedString implements FormatString {
2511    private String JavaDoc s;
2512    FixedString(String JavaDoc s) { this.s = s; }
2513    public int index() { return -2; }
2514    public void print(Object JavaDoc arg, Locale JavaDoc l)
2515        throws IOException JavaDoc { a.append(s); }
2516    public String JavaDoc toString() { return s; }
2517    }
2518
2519    public enum BigDecimalLayoutForm { SCIENTIFIC, DECIMAL_FLOAT };
2520
2521    private class FormatSpecifier implements FormatString {
2522    private int index = -1;
2523    private Flags f = Flags.NONE;
2524    private int width;
2525    private int precision;
2526    private boolean dt = false;
2527    private char c;
2528
2529    private Formatter JavaDoc formatter;
2530
2531    // cache the line separator
2532
private String JavaDoc ls;
2533
2534    private int index(String JavaDoc s) {
2535        if (s != null) {
2536        try {
2537            index = Integer.parseInt(s.substring(0, s.length() - 1));
2538        } catch (NumberFormatException JavaDoc x) {
2539            assert(false);
2540        }
2541        } else {
2542        index = 0;
2543        }
2544        return index;
2545    }
2546
2547    public int index() {
2548        return index;
2549    }
2550
2551    private Flags flags(String JavaDoc s) {
2552        f = Flags.parse(s);
2553        if (f.contains(Flags.PREVIOUS))
2554        index = -1;
2555        return f;
2556    }
2557
2558    Flags flags() {
2559        return f;
2560    }
2561
2562    private int width(String JavaDoc s) {
2563        width = -1;
2564        if (s != null) {
2565        try {
2566            width = Integer.parseInt(s);
2567            if (width < 0)
2568            throw new IllegalFormatWidthException JavaDoc(width);
2569        } catch (NumberFormatException JavaDoc x) {
2570            assert(false);
2571        }
2572        }
2573        return width;
2574    }
2575
2576    int width() {
2577        return width;
2578    }
2579
2580    private int precision(String JavaDoc s) {
2581        precision = -1;
2582        if (s != null) {
2583        try {
2584            // remove the '.'
2585
precision = Integer.parseInt(s.substring(1));
2586            if (precision < 0)
2587            throw new IllegalFormatPrecisionException JavaDoc(precision);
2588        } catch (NumberFormatException JavaDoc x) {
2589            assert(false);
2590        }
2591        }
2592        return precision;
2593    }
2594
2595    int precision() {
2596        return precision;
2597    }
2598
2599    private char conversion(String JavaDoc s) {
2600        c = s.charAt(0);
2601        if (!dt) {
2602        if (!Conversion.isValid(c))
2603            throw new UnknownFormatConversionException JavaDoc(String.valueOf(c));
2604        if (Character.isUpperCase(c))
2605            f.add(Flags.UPPERCASE);
2606        c = Character.toLowerCase(c);
2607        if (Conversion.isText(c))
2608            index = -2;
2609        }
2610        return c;
2611    }
2612
2613    private char conversion() {
2614        return c;
2615    }
2616
2617    FormatSpecifier(Formatter JavaDoc formatter, String JavaDoc[] sa) {
2618        this.formatter = formatter;
2619        int idx = 0;
2620
2621        index(sa[idx++]);
2622        flags(sa[idx++]);
2623        width(sa[idx++]);
2624        precision(sa[idx++]);
2625
2626        if (sa[idx] != null) {
2627        dt = true;
2628        if (sa[idx].equals("T"))
2629            f.add(Flags.UPPERCASE);
2630        }
2631        conversion(sa[++idx]);
2632
2633        if (dt)
2634        checkDateTime();
2635        else if (Conversion.isGeneral(c))
2636        checkGeneral();
2637        else if (c == Conversion.CHARACTER)
2638        checkCharacter();
2639        else if (Conversion.isInteger(c))
2640        checkInteger();
2641        else if (Conversion.isFloat(c))
2642        checkFloat();
2643            else if (Conversion.isText(c))
2644        checkText();
2645        else
2646        throw new UnknownFormatConversionException JavaDoc(String.valueOf(c));
2647    }
2648
2649    public void print(Object JavaDoc arg, Locale JavaDoc l) throws IOException JavaDoc {
2650        if (dt) {
2651        printDateTime(arg, l);
2652        return;
2653        }
2654        switch(c) {
2655        case Conversion.DECIMAL_INTEGER:
2656        case Conversion.OCTAL_INTEGER:
2657        case Conversion.HEXADECIMAL_INTEGER:
2658        printInteger(arg, l);
2659        break;
2660        case Conversion.SCIENTIFIC:
2661        case Conversion.GENERAL:
2662        case Conversion.DECIMAL_FLOAT:
2663        case Conversion.HEXADECIMAL_FLOAT:
2664        printFloat(arg, l);
2665        break;
2666        case Conversion.CHARACTER:
2667        printCharacter(arg);
2668        break;
2669        case Conversion.BOOLEAN:
2670        printBoolean(arg);
2671        break;
2672        case Conversion.STRING:
2673        printString(arg, l);
2674        break;
2675        case Conversion.HASHCODE:
2676        printHashCode(arg);
2677        break;
2678        case Conversion.LINE_SEPARATOR:
2679        if (ls == null)
2680            ls = System.getProperty("line.separator");
2681        a.append(ls);
2682        break;
2683        case Conversion.PERCENT_SIGN:
2684        a.append('%');
2685        break;
2686        default:
2687        assert false;
2688        }
2689    }
2690
2691    private void printInteger(Object JavaDoc arg, Locale JavaDoc l) throws IOException JavaDoc {
2692        if (arg == null)
2693        print("null");
2694        else if (arg instanceof Byte JavaDoc)
2695        print(((Byte JavaDoc)arg).byteValue(), l);
2696        else if (arg instanceof Short JavaDoc)
2697        print(((Short JavaDoc)arg).shortValue(), l);
2698        else if (arg instanceof Integer JavaDoc)
2699        print(((Integer JavaDoc)arg).intValue(), l);
2700        else if (arg instanceof Long JavaDoc)
2701        print(((Long JavaDoc)arg).longValue(), l);
2702        else if (arg instanceof BigInteger JavaDoc)
2703        print(((BigInteger JavaDoc)arg), l);
2704        else
2705        failConversion(c, arg);
2706    }
2707
2708    private void printFloat(Object JavaDoc arg, Locale JavaDoc l) throws IOException JavaDoc {
2709        if (arg == null)
2710        print("null");
2711        else if (arg instanceof Float JavaDoc)
2712        print(((Float JavaDoc)arg).floatValue(), l);
2713        else if (arg instanceof Double JavaDoc)
2714        print(((Double JavaDoc)arg).doubleValue(), l);
2715        else if (arg instanceof BigDecimal JavaDoc)
2716        print(((BigDecimal JavaDoc)arg), l);
2717        else
2718        failConversion(c, arg);
2719    }
2720
2721    private void printDateTime(Object JavaDoc arg, Locale JavaDoc l) throws IOException JavaDoc {
2722        if (arg == null) {
2723        print("null");
2724        return;
2725        }
2726        Calendar JavaDoc cal = null;
2727
2728        // Instead of Calendar.setLenient(true), perhaps we should
2729
// wrap the IllegalArgumentException that might be thrown?
2730
if (arg instanceof Long JavaDoc) {
2731        // Note that the following method uses an instance of the
2732
// default time zone (TimeZone.getDefaultRef().
2733
cal = Calendar.getInstance(l);
2734        cal.setTimeInMillis((Long JavaDoc)arg);
2735        } else if (arg instanceof Date JavaDoc) {
2736        // Note that the following method uses an instance of the
2737
// default time zone (TimeZone.getDefaultRef().
2738
cal = Calendar.getInstance(l);
2739        cal.setTime((Date JavaDoc)arg);
2740        } else if (arg instanceof Calendar JavaDoc) {
2741        cal = (Calendar JavaDoc) ((Calendar JavaDoc)arg).clone();
2742        cal.setLenient(true);
2743        } else {
2744        failConversion(c, arg);
2745        }
2746        print(cal, c, l);
2747    }
2748
2749    private void printCharacter(Object JavaDoc arg) throws IOException JavaDoc {
2750        if (arg == null) {
2751        print("null");
2752        return;
2753        }
2754        String JavaDoc s = null;
2755        if (arg instanceof Character JavaDoc) {
2756        s = ((Character JavaDoc)arg).toString();
2757        } else if (arg instanceof Byte JavaDoc) {
2758        byte i = ((Byte JavaDoc)arg).byteValue();
2759        if (Character.isValidCodePoint(i))
2760            s = new String JavaDoc(Character.toChars(i));
2761        else
2762            throw new IllegalFormatCodePointException JavaDoc(i);
2763        } else if (arg instanceof Short JavaDoc) {
2764        short i = ((Short JavaDoc)arg).shortValue();
2765        if (Character.isValidCodePoint(i))
2766            s = new String JavaDoc(Character.toChars(i));
2767        else
2768            throw new IllegalFormatCodePointException JavaDoc(i);
2769        } else if (arg instanceof Integer JavaDoc) {
2770        int i = ((Integer JavaDoc)arg).intValue();
2771        if (Character.isValidCodePoint(i))
2772            s = new String JavaDoc(Character.toChars(i));
2773        else
2774            throw new IllegalFormatCodePointException JavaDoc(i);
2775        } else {
2776        failConversion(c, arg);
2777        }
2778        print(s);
2779    }
2780
2781    private void printString(Object JavaDoc arg, Locale JavaDoc l) throws IOException JavaDoc {
2782        if (arg == null) {
2783        print("null");
2784        } else if (arg instanceof Formattable JavaDoc) {
2785        Formatter JavaDoc fmt = formatter;
2786        if (formatter.locale() != l)
2787            fmt = new Formatter JavaDoc(formatter.out(), l);
2788        ((Formattable JavaDoc)arg).formatTo(fmt, f.valueOf(), width, precision);
2789        } else {
2790        print(arg.toString());
2791        }
2792    }
2793
2794    private void printBoolean(Object JavaDoc arg) throws IOException JavaDoc {
2795        String JavaDoc s;
2796        if (arg != null)
2797        s = ((arg instanceof Boolean JavaDoc)
2798             ? ((Boolean JavaDoc)arg).toString()
2799             : Boolean.toString(true));
2800        else
2801        s = Boolean.toString(false);
2802        print(s);
2803    }
2804
2805    private void printHashCode(Object JavaDoc arg) throws IOException JavaDoc {
2806        String JavaDoc s = (arg == null
2807            ? "null"
2808            : Integer.toHexString(arg.hashCode()));
2809        print(s);
2810    }
2811
2812    private void print(String JavaDoc s) throws IOException JavaDoc {
2813        if (precision != -1 && precision < s.length())
2814        s = s.substring(0, precision);
2815        if (f.contains(Flags.UPPERCASE))
2816        s = s.toUpperCase();
2817        a.append(justify(s));
2818    }
2819
2820    private String JavaDoc justify(String JavaDoc s) {
2821        if (width == -1)
2822        return s;
2823        StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
2824        boolean pad = f.contains(Flags.LEFT_JUSTIFY);
2825        int sp = width - s.length();
2826        if (!pad)
2827        for (int i = 0; i < sp; i++) sb.append(' ');
2828        sb.append(s);
2829        if (pad)
2830        for (int i = 0; i < sp; i++) sb.append(' ');
2831        return sb.toString();
2832    }
2833
2834    public String JavaDoc toString() {
2835        StringBuilder JavaDoc sb = new StringBuilder JavaDoc('%');
2836        // Flags.UPPERCASE is set internally for legal conversions.
2837
Flags dupf = f.dup().remove(Flags.UPPERCASE);
2838        sb.append(dupf.toString());
2839        if (index > 0)
2840        sb.append(index).append('$');
2841        if (width != -1)
2842        sb.append(width);
2843        if (precision != -1)
2844        sb.append('.').append(precision);
2845        if (dt)
2846        sb.append(f.contains(Flags.UPPERCASE) ? 'T' : 't');
2847        sb.append(f.contains(Flags.UPPERCASE)
2848              ? Character.toUpperCase(c) : c);
2849        return sb.toString();
2850    }
2851
2852    private void checkGeneral() {
2853        if ((c == Conversion.BOOLEAN || c == Conversion.HASHCODE)
2854        && f.contains(Flags.ALTERNATE))
2855        failMismatch(Flags.ALTERNATE, c);
2856        // '-' requires a width
2857
if (width == -1 && f.contains(Flags.LEFT_JUSTIFY))
2858        throw new MissingFormatWidthException JavaDoc(toString());
2859        checkBadFlags(Flags.PLUS, Flags.LEADING_SPACE, Flags.ZERO_PAD,
2860              Flags.GROUP, Flags.PARENTHESES);
2861    }
2862
2863    private void checkDateTime() {
2864        if (precision != -1)
2865        throw new IllegalFormatPrecisionException JavaDoc(precision);
2866        if (!DateTime.isValid(c))
2867        throw new UnknownFormatConversionException JavaDoc("t" + c);
2868        checkBadFlags(Flags.ALTERNATE);
2869        // '-' requires a width
2870
if (width == -1 && f.contains(Flags.LEFT_JUSTIFY))
2871        throw new MissingFormatWidthException JavaDoc(toString());
2872    }
2873
2874    private void checkCharacter() {
2875        if (precision != -1)
2876        throw new IllegalFormatPrecisionException JavaDoc(precision);
2877        checkBadFlags(Flags.ALTERNATE);
2878        // '-' requires a width
2879
if (width == -1 && f.contains(Flags.LEFT_JUSTIFY))
2880        throw new MissingFormatWidthException JavaDoc(toString());
2881    }
2882
2883    private void checkInteger() {
2884        checkNumeric();
2885        if (precision != -1)
2886        throw new IllegalFormatPrecisionException JavaDoc(precision);
2887
2888        if (c == Conversion.DECIMAL_INTEGER)
2889        checkBadFlags(Flags.ALTERNATE);
2890        else if (c == Conversion.OCTAL_INTEGER)
2891        checkBadFlags(Flags.GROUP);
2892        else
2893        checkBadFlags(Flags.GROUP);
2894    }
2895
2896    private void checkBadFlags(Flags ... badFlags) {
2897        for (int i = 0; i < badFlags.length; i++)
2898        if (f.contains(badFlags[i]))
2899            failMismatch(badFlags[i], c);
2900    }
2901
2902    private void checkFloat() {
2903        checkNumeric();
2904        if (c == Conversion.DECIMAL_FLOAT) {
2905        } else if (c == Conversion.HEXADECIMAL_FLOAT) {
2906        checkBadFlags(Flags.PARENTHESES, Flags.GROUP);
2907        } else if (c == Conversion.SCIENTIFIC) {
2908        checkBadFlags(Flags.GROUP);
2909        } else if (c == Conversion.GENERAL) {
2910        checkBadFlags(Flags.ALTERNATE);
2911        }
2912    }
2913
2914    private void checkNumeric() {
2915        if (width != -1 && width < 0)
2916        throw new IllegalFormatWidthException JavaDoc(width);
2917
2918        if (precision != -1 && precision < 0)
2919        throw new IllegalFormatPrecisionException JavaDoc(precision);
2920
2921        // '-' and '0' require a width
2922
if (width == -1
2923        && (f.contains(Flags.LEFT_JUSTIFY) || f.contains(Flags.ZERO_PAD)))
2924        throw new MissingFormatWidthException JavaDoc(toString());
2925
2926        // bad combination
2927
if ((f.contains(Flags.PLUS) && f.contains(Flags.LEADING_SPACE))
2928        || (f.contains(Flags.LEFT_JUSTIFY) && f.contains(Flags.ZERO_PAD)))
2929        throw new IllegalFormatFlagsException JavaDoc(f.toString());
2930    }
2931
2932    private void checkText() {
2933        if (precision != -1)
2934        throw new IllegalFormatPrecisionException JavaDoc(precision);
2935        switch (c) {
2936        case Conversion.PERCENT_SIGN:
2937        if (f.valueOf() != Flags.LEFT_JUSTIFY.valueOf()
2938            && f.valueOf() != Flags.NONE.valueOf())
2939            throw new IllegalFormatFlagsException JavaDoc(f.toString());
2940        // '-' requires a width
2941
if (width == -1 && f.contains(Flags.LEFT_JUSTIFY))
2942            throw new MissingFormatWidthException JavaDoc(toString());
2943        break;
2944        case Conversion.LINE_SEPARATOR:
2945        if (width != -1)
2946            throw new IllegalFormatWidthException JavaDoc(width);
2947        if (f.valueOf() != Flags.NONE.valueOf())
2948            throw new IllegalFormatFlagsException JavaDoc(f.toString());
2949        break;
2950        default:
2951        assert false;
2952        }
2953    }
2954
2955    private void print(byte value, Locale JavaDoc l) throws IOException JavaDoc {
2956        long v = value;
2957        if (value < 0
2958        && (c == Conversion.OCTAL_INTEGER
2959            || c == Conversion.HEXADECIMAL_INTEGER)) {
2960        v += (1L << 8);
2961        assert v >= 0 : v;
2962        }
2963        print(v, l);
2964    }
2965
2966    private void print(short value, Locale JavaDoc l) throws IOException JavaDoc {
2967        long v = value;
2968        if (value < 0
2969        && (c == Conversion.OCTAL_INTEGER
2970            || c == Conversion.HEXADECIMAL_INTEGER)) {
2971        v += (1L << 16);
2972        assert v >= 0 : v;
2973        }
2974        print(v, l);
2975    }
2976
2977    private void print(int value, Locale JavaDoc l) throws IOException JavaDoc {
2978        long v = value;
2979        if (value < 0
2980        && (c == Conversion.OCTAL_INTEGER
2981            || c == Conversion.HEXADECIMAL_INTEGER)) {
2982        v += (1L << 32);
2983        assert v >= 0 : v;
2984        }
2985        print(v, l);
2986    }
2987
2988    private void print(long value, Locale JavaDoc l) throws IOException JavaDoc {
2989
2990        StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
2991
2992        if (c == Conversion.DECIMAL_INTEGER) {
2993        boolean neg = value < 0;
2994        char[] va;
2995        if (value < 0)
2996            va = Long.toString(value, 10).substring(1).toCharArray();
2997        else
2998            va = Long.toString(value, 10).toCharArray();
2999
3000        // leading sign indicator
3001
leadingSign(sb, neg);
3002
3003        // the value
3004
localizedMagnitude(sb, va, f, adjustWidth(width, f, neg), l);
3005
3006        // trailing sign indicator
3007
trailingSign(sb, neg);
3008        } else if (c == Conversion.OCTAL_INTEGER) {
3009        checkBadFlags(Flags.PARENTHESES, Flags.LEADING_SPACE,
3010                  Flags.PLUS);
3011        String JavaDoc s = Long.toOctalString(value);
3012        int len = (f.contains(Flags.ALTERNATE)
3013               ? s.length() + 1
3014               : s.length());
3015
3016        // apply ALTERNATE (radix indicator for octal) before ZERO_PAD
3017
if (f.contains(Flags.ALTERNATE))
3018            sb.append('0');
3019        if (f.contains(Flags.ZERO_PAD))
3020            for (int i = 0; i < width - len; i++) sb.append('0');
3021        sb.append(s);
3022        } else if (c == Conversion.HEXADECIMAL_INTEGER) {
3023        checkBadFlags(Flags.PARENTHESES, Flags.LEADING_SPACE,
3024                  Flags.PLUS);
3025        String JavaDoc s = Long.toHexString(value);
3026        int len = (f.contains(Flags.ALTERNATE)
3027               ? s.length() + 2
3028               : s.length());
3029
3030        // apply ALTERNATE (radix indicator for hex) before ZERO_PAD
3031
if (f.contains(Flags.ALTERNATE))
3032            sb.append(f.contains(Flags.UPPERCASE) ? "0X" : "0x");
3033        if (f.contains(Flags.ZERO_PAD))
3034            for (int i = 0; i < width - len; i++) sb.append('0');
3035        if (f.contains(Flags.UPPERCASE))
3036            s = s.toUpperCase();
3037        sb.append(s);
3038        }
3039
3040        // justify based on width
3041
a.append(justify(sb.toString()));
3042    }
3043
3044    // neg := val < 0
3045
private StringBuilder JavaDoc leadingSign(StringBuilder JavaDoc sb, boolean neg) {
3046        if (!neg) {
3047        if (f.contains(Flags.PLUS)) {
3048            sb.append('+');
3049        } else if (f.contains(Flags.LEADING_SPACE)) {
3050            sb.append(' ');
3051        }
3052        } else {
3053        if (f.contains(Flags.PARENTHESES))
3054            sb.append('(');
3055        else
3056            sb.append('-');
3057        }
3058        return sb;
3059    }
3060
3061    // neg := val < 0
3062
private StringBuilder JavaDoc trailingSign(StringBuilder JavaDoc sb, boolean neg) {
3063        if (neg && f.contains(Flags.PARENTHESES))
3064        sb.append(')');
3065        return sb;
3066    }
3067
3068    private void print(BigInteger JavaDoc value, Locale JavaDoc l) throws IOException JavaDoc {
3069        StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
3070        boolean neg = value.signum() == -1;
3071        BigInteger JavaDoc v = value.abs();
3072
3073        // leading sign indicator
3074
leadingSign(sb, neg);
3075
3076        // the value
3077
if (c == Conversion.DECIMAL_INTEGER) {
3078        char[] va = v.toString().toCharArray();
3079        localizedMagnitude(sb, va, f, adjustWidth(width, f, neg), l);
3080        } else if (c == Conversion.OCTAL_INTEGER) {
3081        String JavaDoc s = v.toString(8);
3082
3083        int len = s.length() + sb.length();
3084        if (neg && f.contains(Flags.PARENTHESES))
3085            len++;
3086
3087        // apply ALTERNATE (radix indicator for octal) before ZERO_PAD
3088
if (f.contains(Flags.ALTERNATE)) {
3089            len++;
3090            sb.append('0');
3091        }
3092        if (f.contains(Flags.ZERO_PAD)) {
3093            for (int i = 0; i < width - len; i++)
3094            sb.append('0');
3095        }
3096        sb.append(s);
3097        } else if (c == Conversion.HEXADECIMAL_INTEGER) {
3098        String JavaDoc s = v.toString(16);
3099
3100        int len = s.length() + sb.length();
3101        if (neg && f.contains(Flags.PARENTHESES))
3102            len++;
3103
3104        // apply ALTERNATE (radix indicator for hex) before ZERO_PAD
3105
if (f.contains(Flags.ALTERNATE)) {
3106            len += 2;
3107            sb.append(f.contains(Flags.UPPERCASE) ? "0X" : "0x");
3108        }
3109        if (f.contains(Flags.ZERO_PAD))
3110            for (int i = 0; i < width - len; i++)
3111            sb.append('0');
3112        if (f.contains(Flags.UPPERCASE))
3113            s = s.toUpperCase();
3114        sb.append(s);
3115        }
3116
3117        // trailing sign indicator
3118
trailingSign(sb, (value.signum() == -1));
3119
3120        // justify based on width
3121
a.append(justify(sb.toString()));
3122    }
3123
3124    private void print(float value, Locale JavaDoc l) throws IOException JavaDoc {
3125        print((double) value, l);
3126    }
3127
3128    private void print(double value, Locale JavaDoc l) throws IOException JavaDoc {
3129        StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
3130        boolean neg = Double.compare(value, 0.0) == -1;
3131
3132        if (!Double.isNaN(value)) {
3133        double v = Math.abs(value);
3134
3135        // leading sign indicator
3136
leadingSign(sb, neg);
3137
3138        // the value
3139
if (!Double.isInfinite(v))
3140            print(sb, v, l, f, c, precision, neg);
3141        else
3142            sb.append(f.contains(Flags.UPPERCASE)
3143                  ? "INFINITY" : "Infinity");
3144
3145        // trailing sign indicator
3146
trailingSign(sb, neg);
3147        } else {
3148        sb.append(f.contains(Flags.UPPERCASE) ? "NAN" : "NaN");
3149        }
3150
3151        // justify based on width
3152
a.append(justify(sb.toString()));
3153    }
3154
3155    // !Double.isInfinite(value) && !Double.isNaN(value)
3156
private void print(StringBuilder JavaDoc sb, double value, Locale JavaDoc l,
3157               Flags f, char c, int precision, boolean neg)
3158        throws IOException JavaDoc
3159    {
3160        if (c == Conversion.SCIENTIFIC) {
3161        // Create a new FormattedFloatingDecimal with the desired
3162
// precision.
3163
int prec = (precision == -1 ? 6 : precision);
3164
3165        FormattedFloatingDecimal fd
3166            = new FormattedFloatingDecimal(value, prec,
3167                        FormattedFloatingDecimal.Form.SCIENTIFIC);
3168
3169        char[] v = new char[MAX_FD_CHARS];
3170        int len = fd.getChars(v);
3171
3172        char[] mant = addZeros(mantissa(v, len), prec);
3173
3174        // If the precision is zero and the '#' flag is set, add the
3175
// requested decimal point.
3176
if (f.contains(Flags.ALTERNATE) && (prec == 0))
3177            mant = addDot(mant);
3178
3179        char[] exp = (value == 0.0)
3180            ? new char[] {'+','0','0'} : exponent(v, len);
3181
3182        int newW = width;
3183        if (width != -1)
3184            newW = adjustWidth(width - exp.length - 1, f, neg);
3185        localizedMagnitude(sb, mant, f, newW, null);
3186
3187        sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e');
3188
3189        Flags flags = f.dup().remove(Flags.GROUP);
3190        char sign = exp[0];
3191        assert(sign == '+' || sign == '-');
3192        sb.append(sign);
3193
3194        char[] tmp = new char[exp.length - 1];
3195        System.arraycopy(exp, 1, tmp, 0, exp.length - 1);
3196        sb.append(localizedMagnitude(null, tmp, flags, -1, null));
3197        } else if (c == Conversion.DECIMAL_FLOAT) {
3198        // Create a new FormattedFloatingDecimal with the desired
3199
// precision.
3200
int prec = (precision == -1 ? 6 : precision);
3201
3202        FormattedFloatingDecimal fd
3203            = new FormattedFloatingDecimal(value, prec,
3204            FormattedFloatingDecimal.Form.DECIMAL_FLOAT);
3205
3206        // MAX_FD_CHARS + 1 (round?)
3207
char[] v = new char[MAX_FD_CHARS + 1
3208                   + Math.abs(fd.getExponent())];
3209        int len = fd.getChars(v);
3210
3211        char[] mant = addZeros(mantissa(v, len), prec);
3212
3213        // If the precision is zero and the '#' flag is set, add the
3214
// requested decimal point.
3215
if (f.contains(Flags.ALTERNATE) && (prec == 0))
3216            mant = addDot(mant);
3217
3218        int newW = width;
3219        if (width != -1)
3220            newW = adjustWidth(width, f, neg);
3221        localizedMagnitude(sb, mant, f, newW, l);
3222        } else if (c == Conversion.GENERAL) {
3223        int prec = precision;
3224        if (precision == -1)
3225            prec = 6;
3226        else if (precision == 0)
3227            prec = 1;
3228
3229        FormattedFloatingDecimal fd
3230            = new FormattedFloatingDecimal(value, prec,
3231            FormattedFloatingDecimal.Form.GENERAL);
3232
3233        // MAX_FD_CHARS + 1 (round?)
3234
char[] v = new char[MAX_FD_CHARS + 1
3235                   + Math.abs(fd.getExponent())];
3236        int len = fd.getChars(v);
3237
3238        char[] exp = exponent(v, len);
3239        if (exp != null) {
3240            prec -= 1;
3241        } else {
3242            prec = prec - (value == 0 ? 0 : fd.getExponentRounded()) - 1;
3243        }
3244
3245        char[] mant = addZeros(mantissa(v, len), prec);
3246        // If the precision is zero and the '#' flag is set, add the
3247
// requested decimal point.
3248
if (f.contains(Flags.ALTERNATE) && (prec == 0))
3249            mant = addDot(mant);
3250
3251        int newW = width;
3252        if (width != -1) {
3253            if (exp != null)
3254            newW = adjustWidth(width - exp.length - 1, f, neg);
3255            else
3256            newW = adjustWidth(width, f, neg);
3257        }
3258        localizedMagnitude(sb, mant, f, newW, null);
3259
3260        if (exp != null) {
3261            sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e');
3262
3263            Flags flags = f.dup().remove(Flags.GROUP);
3264            char sign = exp[0];
3265            assert(sign == '+' || sign == '-');
3266            sb.append(sign);
3267
3268            char[] tmp = new char[exp.length - 1];
3269            System.arraycopy(exp, 1, tmp, 0, exp.length - 1);
3270            sb.append(localizedMagnitude(null, tmp, flags, -1, null));
3271        }
3272        } else if (c == Conversion.HEXADECIMAL_FLOAT) {
3273        int prec = precision;
3274        if (precision == -1)
3275            // assume that we want all of the digits
3276
prec = 0;
3277        else if (precision == 0)
3278            prec = 1;
3279
3280        String JavaDoc s = hexDouble(value, prec);
3281
3282        char[] va;
3283        boolean upper = f.contains(Flags.UPPERCASE);
3284        sb.append(upper ? "0X" : "0x");
3285
3286        if (f.contains(Flags.ZERO_PAD))
3287            for (int i = 0; i < width - s.length() - 2; i++)
3288            sb.append('0');
3289
3290        int idx = s.indexOf('p');
3291        va = s.substring(0, idx).toCharArray();
3292        if (upper) {
3293            String JavaDoc tmp = new String JavaDoc(va);
3294            // don't localize hex
3295
tmp = tmp.toUpperCase(Locale.US);
3296            va = tmp.toCharArray();
3297        }
3298        sb.append(prec != 0 ? addZeros(va, prec) : va);
3299        sb.append(upper ? 'P' : 'p');
3300        sb.append(s.substring(idx+1));
3301        }
3302    }
3303
3304    private char[] mantissa(char[] v, int len) {
3305        int i;
3306        for (i = 0; i < len; i++) {
3307        if (v[i] == 'e')
3308            break;
3309        }
3310        char[] tmp = new char[i];
3311        System.arraycopy(v, 0, tmp, 0, i);
3312        return tmp;
3313    }
3314
3315    private char[] exponent(char[] v, int len) {
3316        int i;
3317        for (i = len - 1; i >= 0; i--) {
3318        if (v[i] == 'e')
3319            break;
3320        }
3321        if (i == -1)
3322        return null;
3323        char[] tmp = new char[len - i - 1];
3324        System.arraycopy(v, i + 1, tmp, 0, len - i - 1);
3325        return tmp;
3326    }
3327
3328    // Add zeros to the requested precision.
3329
private char[] addZeros(char[] v, int prec) {
3330        // Look for the dot. If we don't find one, the we'll need to add
3331
// it before we add the zeros.
3332
int i;
3333        for (i = 0; i < v.length; i++) {
3334        if (v[i] == '.')
3335            break;
3336        }
3337        boolean needDot = false;
3338        if (i == v.length) {
3339        needDot = true;
3340        }
3341
3342        // Determine existing precision.
3343
int outPrec = v.length - i - (needDot ? 0 : 1);
3344        assert (outPrec <= prec);
3345        if (outPrec == prec)
3346        return v;
3347
3348        // Create new array with existing contents.
3349
char[] tmp
3350        = new char[v.length + prec - outPrec + (needDot ? 1 : 0)];
3351        System.arraycopy(v, 0, tmp, 0, v.length);
3352
3353        // Add dot if previously determined to be necessary.
3354
int start = v.length;
3355        if (needDot) {
3356        tmp[v.length] = '.';
3357        start++;
3358        }
3359
3360        // Add zeros.
3361
for (int j = start; j < tmp.length; j++)
3362        tmp[j] = '0';
3363
3364        return tmp;
3365    }
3366
3367    // Method assumes that d > 0.
3368
private String JavaDoc hexDouble(double d, int prec) {
3369        // Let Double.toHexString handle simple cases
3370
if(!FpUtils.isFinite(d) || d == 0.0 || prec == 0 || prec >= 13)
3371        // remove "0x"
3372
return Double.toHexString(d).substring(2);
3373        else {
3374        assert(prec >= 1 && prec <= 12);
3375
3376        int exponent = FpUtils.getExponent(d);
3377        boolean subnormal
3378            = (exponent == DoubleConsts.MIN_EXPONENT - 1);
3379
3380        // If this is subnormal input so normalize (could be faster to
3381
// do as integer operation).
3382
if (subnormal) {
3383            scaleUp = FpUtils.scalb(1.0, 54);
3384            d *= scaleUp;
3385            // Calculate the exponent. This is not just exponent + 54
3386
// since the former is not the normalized exponent.
3387
exponent = FpUtils.getExponent(d);
3388            assert exponent >= DoubleConsts.MIN_EXPONENT &&
3389            exponent <= DoubleConsts.MAX_EXPONENT: exponent;
3390        }
3391
3392        int precision = 1 + prec*4;
3393        int shiftDistance
3394            = DoubleConsts.SIGNIFICAND_WIDTH - precision;
3395        assert(shiftDistance >= 1 && shiftDistance < DoubleConsts.SIGNIFICAND_WIDTH);
3396
3397        long doppel = Double.doubleToLongBits(d);
3398        // Deterime the number of bits to keep.
3399
long newSignif
3400            = (doppel & (DoubleConsts.EXP_BIT_MASK
3401                 | DoubleConsts.SIGNIF_BIT_MASK))
3402                     >> shiftDistance;
3403        // Bits to round away.
3404
long roundingBits = doppel & ~(~0L << shiftDistance);
3405
3406        // To decide how to round, look at the low-order bit of the
3407
// working significand, the highest order discarded bit (the
3408
// round bit) and whether any of the lower order discarded bits
3409
// are nonzero (the sticky bit).
3410

3411        boolean leastZero = (newSignif & 0x1L) == 0L;
3412        boolean round
3413            = ((1L << (shiftDistance - 1) ) & roundingBits) != 0L;
3414        boolean sticky = shiftDistance > 1 &&
3415            (~(1L<< (shiftDistance - 1)) & roundingBits) != 0;
3416        if((leastZero && round && sticky) || (!leastZero && round)) {
3417            newSignif++;
3418        }
3419
3420        long signBit = doppel & DoubleConsts.SIGN_BIT_MASK;
3421        newSignif = signBit | (newSignif << shiftDistance);
3422        double result = Double.longBitsToDouble(newSignif);
3423
3424        if (Double.isInfinite(result) ) {
3425            // Infinite result generated by rounding
3426
return "1.0p1024";
3427        } else {
3428            String JavaDoc res = Double.toHexString(result).substring(2);
3429            if (!subnormal)
3430            return res;
3431            else {
3432            // Create a normalized subnormal string.
3433
int idx = res.indexOf('p');
3434            if (idx == -1) {
3435                // No 'p' character in hex string.
3436
assert false;
3437                return null;
3438            } else {
3439                // Get exponent and append at the end.
3440
String JavaDoc exp = res.substring(idx + 1);
3441                int iexp = Integer.parseInt(exp) -54;
3442                return res.substring(0, idx) + "p"
3443                + Integer.toString(iexp);
3444            }
3445            }
3446        }
3447        }
3448    }
3449
3450    private void print(BigDecimal JavaDoc value, Locale JavaDoc l) throws IOException JavaDoc {
3451        if (c == Conversion.HEXADECIMAL_FLOAT)
3452        failConversion(c, value);
3453        StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
3454        boolean neg = value.signum() == -1;
3455        BigDecimal JavaDoc v = value.abs();
3456        // leading sign indicator
3457
leadingSign(sb, neg);
3458
3459        // the value
3460
print(sb, v, l, f, c, precision, neg);
3461
3462        // trailing sign indicator
3463
trailingSign(sb, neg);
3464
3465        // justify based on width
3466
a.append(justify(sb.toString()));
3467    }
3468
3469    // value > 0
3470
private void print(StringBuilder JavaDoc sb, BigDecimal JavaDoc value, Locale JavaDoc l,
3471               Flags f, char c, int precision, boolean neg)
3472        throws IOException JavaDoc
3473    {
3474        if (c == Conversion.SCIENTIFIC) {
3475        // Create a new BigDecimal with the desired precision.
3476
int prec = (precision == -1 ? 6 : precision);
3477        int scale = value.scale();
3478        int origPrec = value.precision();
3479        int nzeros = 0;
3480        int compPrec;
3481
3482        if (prec > origPrec - 1) {
3483            compPrec = origPrec;
3484            nzeros = prec - (origPrec - 1);
3485        } else {
3486            compPrec = prec + 1;
3487        }
3488
3489        MathContext JavaDoc mc = new MathContext JavaDoc(compPrec);
3490        BigDecimal JavaDoc v
3491            = new BigDecimal JavaDoc(value.unscaledValue(), scale, mc);
3492
3493        BigDecimalLayout bdl
3494            = new BigDecimalLayout(v.unscaledValue(), v.scale(),
3495                       BigDecimalLayoutForm.SCIENTIFIC);
3496
3497        char[] mant = bdl.mantissa();
3498
3499        // Add a decimal point if necessary. The mantissa may not
3500
// contain a decimal point if the scale is zero (the internal
3501
// representation has no fractional part) or the original
3502
// precision is one. Append a decimal point if '#' is set or if
3503
// we require zero padding to get to the requested precision.
3504
if ((origPrec == 1 || !bdl.hasDot())
3505            && (nzeros > 0 || (f.contains(Flags.ALTERNATE))))
3506            mant = addDot(mant);
3507
3508        // Add trailing zeros in the case precision is greater than
3509
// the number of available digits after the decimal separator.
3510
mant = trailingZeros(mant, nzeros);
3511
3512        char[] exp = bdl.exponent();
3513        int newW = width;
3514        if (width != -1)
3515            newW = adjustWidth(width - exp.length - 1, f, neg);
3516        localizedMagnitude(sb, mant, f, newW, null);
3517
3518        sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e');
3519
3520        Flags flags = f.dup().remove(Flags.GROUP);
3521        char sign = exp[0];
3522        assert(sign == '+' || sign == '-');
3523        sb.append(exp[0]);
3524
3525        char[] tmp = new char[exp.length - 1];
3526        System.arraycopy(exp, 1, tmp, 0, exp.length - 1);
3527        sb.append(localizedMagnitude(null, tmp, flags, -1, null));
3528        } else if (c == Conversion.DECIMAL_FLOAT) {
3529        // Create a new BigDecimal with the desired precision.
3530
int prec = (precision == -1 ? 6 : precision);
3531        int scale = value.scale();
3532        int origPrec = value.precision();
3533        int nzeros = 0;
3534        int compPrec;
3535        if (scale < prec) {
3536            compPrec = origPrec;
3537            nzeros = prec - scale;
3538        } else {
3539            compPrec = origPrec - (scale - prec);
3540        }
3541        MathContext JavaDoc mc = new MathContext JavaDoc(compPrec);
3542        BigDecimal JavaDoc v
3543            = new BigDecimal JavaDoc(value.unscaledValue(), scale, mc);
3544
3545        BigDecimalLayout bdl
3546            = new BigDecimalLayout(v.unscaledValue(), v.scale(),
3547                       BigDecimalLayoutForm.DECIMAL_FLOAT);
3548
3549        char mant[] = bdl.mantissa();
3550
3551        // Add a decimal point if necessary. The mantissa may not
3552
// contain a decimal point if the scale is zero (the internal
3553
// representation has no fractional part). Append a decimal
3554
// point if '#' is set or we require zero padding to get to the
3555
// requested precision.
3556
if (scale == 0 && (f.contains(Flags.ALTERNATE) || nzeros > 0))
3557            mant = addDot(bdl.mantissa());
3558
3559        // Add trailing zeros if the precision is greater than the
3560
// number of available digits after the decimal separator.
3561
mant = trailingZeros(mant, nzeros);
3562
3563        localizedMagnitude(sb, mant, f, adjustWidth(width, f, neg), l);
3564        } else if (c == Conversion.GENERAL) {
3565        int prec = precision;
3566        if (precision == -1)
3567            prec = 6;
3568        else if (precision == 0)
3569            prec = 1;
3570
3571        BigDecimal JavaDoc tenToTheNegFour = BigDecimal.valueOf(1, 4);
3572        BigDecimal JavaDoc tenToThePrec = BigDecimal.valueOf(1, -prec);
3573        if ((value.equals(BigDecimal.ZERO))
3574            || ((value.compareTo(tenToTheNegFour) != -1)
3575            && (value.compareTo(tenToThePrec) == -1))) {
3576
3577            int e = - value.scale()
3578            + (value.unscaledValue().toString().length() - 1);
3579
3580            // xxx.yyy
3581
// g precision (# sig digits) = #x + #y
3582
// f precision = #y
3583
// exponent = #x - 1
3584
// => f precision = g precision - exponent - 1
3585
// 0.000zzz
3586
// g precision (# sig digits) = #z
3587
// f precision = #0 (after '.') + #z
3588
// exponent = - #0 (after '.') - 1
3589
// => f precision = g precision - exponent - 1
3590
prec = prec - e - 1;
3591
3592            print(sb, value, l, f, Conversion.DECIMAL_FLOAT, prec,
3593              neg);
3594        } else {
3595            print(sb, value, l, f, Conversion.SCIENTIFIC, prec - 1, neg);
3596        }
3597        } else if (c == Conversion.HEXADECIMAL_FLOAT) {
3598        // This conversion isn't supported. The error should be
3599
// reported earlier.
3600
assert false;
3601        }
3602    }
3603
3604    private class BigDecimalLayout {
3605        private StringBuilder JavaDoc mant;
3606        private StringBuilder JavaDoc exp;
3607        private boolean dot = false;
3608
3609        public BigDecimalLayout(BigInteger JavaDoc intVal, int scale, BigDecimalLayoutForm form) {
3610        layout(intVal, scale, form);
3611        }
3612
3613        public boolean hasDot() {
3614        return dot;
3615        }
3616
3617        // char[] with canonical string representation
3618
public char[] layoutChars() {
3619        StringBuilder JavaDoc sb = new StringBuilder JavaDoc(mant);
3620        if (exp != null) {
3621            sb.append('E');
3622            sb.append(exp);
3623        }
3624        return toCharArray(sb);
3625        }
3626
3627        public char[] mantissa() {
3628        return toCharArray(mant);
3629        }
3630
3631        // The exponent will be formatted as a sign ('+' or '-') followed
3632
// by the exponent zero-padded to include at least two digits.
3633
public char[] exponent() {
3634        return toCharArray(exp);
3635        }
3636
3637        private char[] toCharArray(StringBuilder JavaDoc sb) {
3638        if (sb == null)
3639            return null;
3640        char[] result = new char[sb.length()];
3641        sb.getChars(0, result.length, result, 0);
3642        return result;
3643        }
3644
3645        private void layout(BigInteger JavaDoc intVal, int scale, BigDecimalLayoutForm form) {
3646        char coeff[] = intVal.toString().toCharArray();
3647
3648        // Construct a buffer, with sufficient capacity for all cases.
3649
// If E-notation is needed, length will be: +1 if negative, +1
3650
// if '.' needed, +2 for "E+", + up to 10 for adjusted
3651
// exponent. Otherwise it could have +1 if negative, plus
3652
// leading "0.00000"
3653
mant = new StringBuilder JavaDoc(coeff.length + 14);
3654
3655        if (scale == 0) {
3656            int len = coeff.length;
3657            if (len > 1) {
3658            mant.append(coeff[0]);
3659            if (form == BigDecimalLayoutForm.SCIENTIFIC) {
3660                mant.append('.');
3661                dot = true;
3662                mant.append(coeff, 1, len - 1);
3663                exp = new StringBuilder JavaDoc("+");
3664                if (len < 10)
3665                exp.append("0").append(len - 1);
3666                else
3667                exp.append(len - 1);
3668            } else {
3669                mant.append(coeff, 1, len - 1);
3670            }
3671            } else {
3672            mant.append(coeff);
3673            if (form == BigDecimalLayoutForm.SCIENTIFIC)
3674                exp = new StringBuilder JavaDoc("+00");
3675            }
3676            return;
3677        }
3678        long adjusted = -(long) scale + (coeff.length - 1);
3679        if (form == BigDecimalLayoutForm.DECIMAL_FLOAT) {
3680            // count of padding zeros
3681
int pad = scale - coeff.length;
3682            if (pad >= 0) {
3683            // 0.xxx form
3684
mant.append("0.");
3685            dot = true;
3686            for (; pad > 0 ; pad--) mant.append('0');
3687            mant.append(coeff);
3688            } else {
3689            // xx.xx form
3690
mant.append(coeff, 0, -pad);
3691            mant.append('.');
3692            dot = true;
3693            mant.append(coeff, -pad, scale);
3694            }
3695        } else {
3696            // x.xxx form
3697
mant.append(coeff[0]);
3698            if (coeff.length > 1) {
3699            mant.append('.');
3700            dot = true;
3701            mant.append(coeff, 1, coeff.length-1);
3702            }
3703            exp = new StringBuilder JavaDoc();
3704            if (adjusted != 0) {
3705            long abs = Math.abs(adjusted);
3706            // require sign
3707
exp.append(adjusted < 0 ? '-' : '+');
3708            if (abs < 10)
3709                exp.append('0');
3710            exp.append(abs);
3711            } else {
3712            exp.append("+00");
3713            }
3714        }
3715        }
3716    }
3717
3718    private int adjustWidth(int width, Flags f, boolean neg) {
3719        int newW = width;
3720        if (newW != -1 && neg && f.contains(Flags.PARENTHESES))
3721        newW--;
3722        return newW;
3723    }
3724
3725    // Add a '.' to th mantissa if required
3726
private char[] addDot(char[] mant) {
3727        char[] tmp = mant;
3728        tmp = new char[mant.length + 1];
3729        System.arraycopy(mant, 0, tmp, 0, mant.length);
3730        tmp[tmp.length - 1] = '.';
3731        return tmp;
3732    }
3733
3734    // Add trailing zeros in the case precision is greater than the number
3735
// of available digits after the decimal separator.
3736
private char[] trailingZeros(char[] mant, int nzeros) {
3737        char[] tmp = mant;
3738        if (nzeros > 0) {
3739        tmp = new char[mant.length + nzeros];
3740        System.arraycopy(mant, 0, tmp, 0, mant.length);
3741        for (int i = mant.length; i < tmp.length; i++)
3742            tmp[i] = '0';
3743        }
3744        return tmp;
3745    }
3746
3747    private void print(Calendar JavaDoc t, char c, Locale JavaDoc l) throws IOException JavaDoc
3748    {
3749        StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
3750        print(sb, t, c, l);
3751
3752        // justify based on width
3753
String JavaDoc s = justify(sb.toString());
3754        if (f.contains(Flags.UPPERCASE))
3755        s = s.toUpperCase();
3756
3757        a.append(s);
3758    }
3759
3760    private Appendable JavaDoc print(StringBuilder JavaDoc sb, Calendar JavaDoc t, char c,
3761                 Locale JavaDoc l)
3762        throws IOException JavaDoc
3763    {
3764        assert(width == -1);
3765        if (sb == null)
3766        sb = new StringBuilder JavaDoc();
3767        switch (c) {
3768        case DateTime.HOUR_OF_DAY_0: // 'H' (00 - 23)
3769
case DateTime.HOUR_0: // 'I' (01 - 12)
3770
case DateTime.HOUR_OF_DAY: // 'k' (0 - 23) -- like H
3771
case DateTime.HOUR: { // 'l' (1 - 12) -- like I
3772
int i = t.get(Calendar.HOUR_OF_DAY);
3773        if (c == DateTime.HOUR_0 || c == DateTime.HOUR)
3774            i = (i == 0 || i == 12 ? 12 : i % 12);
3775        Flags flags = (c == DateTime.HOUR_OF_DAY_0
3776                   || c == DateTime.HOUR_0
3777                   ? Flags.ZERO_PAD
3778                   : Flags.NONE);
3779        sb.append(localizedMagnitude(null, i, flags, 2, l));
3780        break;
3781        }
3782        case DateTime.MINUTE: { // 'M' (00 - 59)
3783
int i = t.get(Calendar.MINUTE);
3784        Flags flags = Flags.ZERO_PAD;
3785        sb.append(localizedMagnitude(null, i, flags, 2, l));
3786        break;
3787        }
3788        case DateTime.NANOSECOND: { // 'N' (000000000 - 999999999)
3789
int i = t.get(Calendar.MILLISECOND) * 1000000;
3790        Flags flags = Flags.ZERO_PAD;
3791        sb.append(localizedMagnitude(null, i, flags, 9, l));
3792        break;
3793        }
3794        case DateTime.MILLISECOND: { // 'L' (000 - 999)
3795
int i = t.get(Calendar.MILLISECOND);
3796        Flags flags = Flags.ZERO_PAD;
3797        sb.append(localizedMagnitude(null, i, flags, 3, l));
3798        break;
3799        }
3800        case DateTime.MILLISECOND_SINCE_EPOCH: { // 'Q' (0 - 99...?)
3801
long i = t.getTimeInMillis();
3802        Flags flags = Flags.NONE;
3803        sb.append(localizedMagnitude(null, i, flags, width, l));
3804        break;
3805        }
3806        case DateTime.AM_PM: { // 'p' (am or pm)
3807
// Calendar.AM = 0, Calendar.PM = 1, LocaleElements defines upper
3808
String JavaDoc[] ampm = { "AM", "PM" };
3809        if (l != null && l != Locale.US) {
3810            DateFormatSymbols JavaDoc dfs = new DateFormatSymbols JavaDoc(l);
3811            ampm = dfs.getAmPmStrings();
3812        }
3813        String JavaDoc s = ampm[t.get(Calendar.AM_PM)];
3814        sb.append(s.toLowerCase(l != null ? l : Locale.US));
3815        break;
3816        }
3817        case DateTime.SECONDS_SINCE_EPOCH: { // 's' (0 - 99...?)
3818
long i = t.getTimeInMillis() / 1000;
3819        Flags flags = Flags.NONE;
3820        sb.append(localizedMagnitude(null, i, flags, width, l));
3821        break;
3822        }
3823        case DateTime.SECOND: { // 'S' (00 - 60 - leap second)
3824
int i = t.get(Calendar.SECOND);
3825        Flags flags = Flags.ZERO_PAD;
3826        sb.append(localizedMagnitude(null, i, flags, 2, l));
3827        break;
3828        }
3829        case DateTime.ZONE_NUMERIC: { // 'z' ({-|+}####) - ls minus?
3830
int i = t.get(Calendar.ZONE_OFFSET);
3831        boolean neg = i < 0;
3832        sb.append(neg ? '-' : '+');
3833        if (neg)
3834            i = -i;
3835        int min = i / 60000;
3836        // combine minute and hour into a single integer
3837
int offset = (min / 60) * 100 + (min % 60);
3838        Flags flags = Flags.ZERO_PAD;
3839
3840        sb.append(localizedMagnitude(null, offset, flags, 4, l));
3841        break;
3842        }
3843        case DateTime.ZONE: { // 'Z' (symbol)
3844
TimeZone JavaDoc tz = t.getTimeZone();
3845        sb.append(tz.getDisplayName((t.get(Calendar.DST_OFFSET) != 0),
3846                       TimeZone.SHORT,
3847                       l));
3848        break;
3849        }
3850
3851            // Date
3852
case DateTime.NAME_OF_DAY_ABBREV: // 'a'
3853
case DateTime.NAME_OF_DAY: { // 'A'
3854
int i = t.get(Calendar.DAY_OF_WEEK);
3855        Locale JavaDoc lt = ((l == null) ? Locale.US : l);
3856        DateFormatSymbols JavaDoc dfs = new DateFormatSymbols JavaDoc(lt);
3857        if (c == DateTime.NAME_OF_DAY)
3858            sb.append(dfs.getWeekdays()[i]);
3859        else
3860            sb.append(dfs.getShortWeekdays()[i]);
3861        break;
3862        }
3863        case DateTime.NAME_OF_MONTH_ABBREV: // 'b'
3864
case DateTime.NAME_OF_MONTH_ABBREV_X: // 'h' -- same b
3865
case DateTime.NAME_OF_MONTH: { // 'B'
3866
int i = t.get(Calendar.MONTH);
3867        Locale JavaDoc lt = ((l == null) ? Locale.US : l);
3868        DateFormatSymbols JavaDoc dfs = new DateFormatSymbols JavaDoc(lt);
3869        if (c == DateTime.NAME_OF_MONTH)
3870            sb.append(dfs.getMonths()[i]);
3871        else
3872            sb.append(dfs.getShortMonths()[i]);
3873        break;
3874        }
3875        case DateTime.CENTURY: // 'C' (00 - 99)
3876
case DateTime.YEAR_2: // 'y' (00 - 99)
3877
case DateTime.YEAR_4: { // 'Y' (0000 - 9999)
3878
int i = t.get(Calendar.YEAR);
3879        int size = 2;
3880        switch (c) {
3881        case DateTime.CENTURY:
3882            i /= 100;
3883            break;
3884        case DateTime.YEAR_2:
3885            i %= 100;
3886            break;
3887        case DateTime.YEAR_4:
3888            size = 4;
3889            break;
3890        }
3891        Flags flags = Flags.ZERO_PAD;
3892        sb.append(localizedMagnitude(null, i, flags, size, l));
3893        break;
3894        }
3895        case DateTime.DAY_OF_MONTH_0: // 'd' (01 - 31)
3896
case DateTime.DAY_OF_MONTH: { // 'e' (1 - 31) -- like d
3897
int i = t.get(Calendar.DATE);
3898        Flags flags = (c == DateTime.DAY_OF_MONTH_0
3899                   ? Flags.ZERO_PAD
3900                   : Flags.NONE);
3901        sb.append(localizedMagnitude(null, i, flags, 2, l));
3902        break;
3903        }
3904        case DateTime.DAY_OF_YEAR: { // 'j' (001 - 366)
3905
int i = t.get(Calendar.DAY_OF_YEAR);
3906        Flags flags = Flags.ZERO_PAD;
3907        sb.append(localizedMagnitude(null, i, flags, 3, l));
3908        break;
3909        }
3910        case DateTime.MONTH: { // 'm' (01 - 12)
3911
int i = t.get(Calendar.MONTH) + 1;
3912        Flags flags = Flags.ZERO_PAD;
3913        sb.append(localizedMagnitude(null, i, flags, 2, l));
3914        break;
3915        }
3916
3917            // Composites
3918
case DateTime.TIME: // 'T' (24 hour hh:mm:ss - %tH:%tM:%tS)
3919
case DateTime.TIME_24_HOUR: { // 'R' (hh:mm same as %H:%M)
3920
char sep = ':';
3921        print(sb, t, DateTime.HOUR_OF_DAY_0, l).append(sep);
3922        print(sb, t, DateTime.MINUTE, l);
3923        if (c == DateTime.TIME) {
3924            sb.append(sep);
3925            print(sb, t, DateTime.SECOND, l);
3926        }
3927        break;
3928        }
3929        case DateTime.TIME_12_HOUR: { // 'r' (hh:mm:ss [AP]M)
3930
char sep = ':';
3931        print(sb, t, DateTime.HOUR_0, l).append(sep);
3932        print(sb, t, DateTime.MINUTE, l).append(sep);
3933        print(sb, t, DateTime.SECOND, l).append(' ');
3934        // this may be in wrong place for some locales
3935
StringBuilder JavaDoc tsb = new StringBuilder JavaDoc();
3936        print(tsb, t, DateTime.AM_PM, l);
3937        sb.append(tsb.toString().toUpperCase(l != null ? l : Locale.US));
3938        break;
3939        }
3940        case DateTime.DATE_TIME: { // 'c' (Sat Nov 04 12:02:33 EST 1999)
3941
char sep = ' ';
3942        print(sb, t, DateTime.NAME_OF_DAY_ABBREV, l).append(sep);
3943        print(sb, t, DateTime.NAME_OF_MONTH_ABBREV, l).append(sep);
3944        print(sb, t, DateTime.DAY_OF_MONTH_0, l).append(sep);
3945        print(sb, t, DateTime.TIME, l).append(sep);
3946        print(sb, t, DateTime.ZONE, l).append(sep);
3947        print(sb, t, DateTime.YEAR_4, l);
3948        break;
3949        }
3950        case DateTime.DATE: { // 'D' (mm/dd/yy)
3951
char sep = '/';
3952        print(sb, t, DateTime.MONTH, l).append(sep);
3953        print(sb, t, DateTime.DAY_OF_MONTH_0, l).append(sep);
3954        print(sb, t, DateTime.YEAR_2, l);
3955        break;
3956        }
3957        case DateTime.ISO_STANDARD_DATE: { // 'F' (%Y-%m-%d)
3958
char sep = '-';
3959        print(sb, t, DateTime.YEAR_4, l).append(sep);
3960        print(sb, t, DateTime.MONTH, l).append(sep);
3961        print(sb, t, DateTime.DAY_OF_MONTH_0, l);
3962        break;
3963        }
3964        default:
3965        assert false;
3966        }
3967        return sb;
3968    }
3969
3970    // -- Methods to support throwing exceptions --
3971

3972    private void failMismatch(Flags f, char c) {
3973        String JavaDoc fs = f.toString();
3974        throw new FormatFlagsConversionMismatchException JavaDoc(fs, c);
3975    }
3976
3977    private void failConversion(char c, Object JavaDoc arg) {
3978        throw new IllegalFormatConversionException JavaDoc(c, arg.getClass());
3979    }
3980
3981    private char getZero(Locale JavaDoc l) {
3982        if ((l != null) && !l.equals(locale())) {
3983        DecimalFormatSymbols JavaDoc dfs = new DecimalFormatSymbols JavaDoc(l);
3984        return dfs.getZeroDigit();
3985        }
3986        return zero;
3987    }
3988
3989    private StringBuilder JavaDoc
3990        localizedMagnitude(StringBuilder JavaDoc sb, long value, Flags f,
3991                   int width, Locale JavaDoc l)
3992    {
3993        char[] va = Long.toString(value, 10).toCharArray();
3994        return localizedMagnitude(sb, va, f, width, l);
3995    }
3996
3997    private StringBuilder JavaDoc
3998        localizedMagnitude(StringBuilder JavaDoc sb, char[] value, Flags f,
3999                   int width, Locale JavaDoc l)
4000    {
4001        if (sb == null)
4002        sb = new StringBuilder JavaDoc();
4003        int begin = sb.length();
4004
4005        char zero = getZero(l);
4006
4007        // determine localized grouping separator and size
4008
char grpSep = '\0';
4009        int grpSize = -1;
4010        char decSep = '\0';
4011
4012        int len = value.length;
4013        int dot = len;
4014        for (int j = 0; j < len; j++) {
4015        if (value[j] == '.') {
4016            dot = j;
4017            break;
4018        }
4019        }
4020
4021        if (dot < len) {
4022        if (l == null || l.equals(Locale.US)) {
4023            decSep = '.';
4024        } else {
4025            DecimalFormatSymbols JavaDoc dfs = new DecimalFormatSymbols JavaDoc(l);
4026            decSep = dfs.getDecimalSeparator();
4027        }
4028        }
4029
4030        if (f.contains(Flags.GROUP)) {
4031        if (l == null || l.equals(Locale.US)) {
4032            grpSep = ',';
4033            grpSize = 3;
4034        } else {
4035            DecimalFormatSymbols JavaDoc dfs = new DecimalFormatSymbols JavaDoc(l);
4036            grpSep = dfs.getGroupingSeparator();
4037            DecimalFormat JavaDoc df = (DecimalFormat JavaDoc) NumberFormat.getIntegerInstance(l);
4038            grpSize = df.getGroupingSize();
4039        }
4040        }
4041
4042        // localize the digits inserting group separators as necessary
4043
for (int j = 0; j < len; j++) {
4044        if (j == dot) {
4045            sb.append(decSep);
4046            // no more group separators after the decimal separator
4047
grpSep = '\0';
4048            continue;
4049        }
4050
4051        char c = value[j];
4052        sb.append((char) ((c - '0') + zero));
4053        if (grpSep != '\0' && j != dot - 1 && ((dot - j) % grpSize == 1))
4054            sb.append(grpSep);
4055        }
4056
4057        // apply zero padding
4058
len = sb.length();
4059        if (width != -1 && f.contains(Flags.ZERO_PAD))
4060        for (int k = 0; k < width - len; k++)
4061            sb.insert(begin, zero);
4062
4063        return sb;
4064    }
4065    }
4066
4067    private static class Flags {
4068    private int flags;
4069
4070    static final Flags NONE = new Flags(0); // ''
4071

4072    // duplicate declarations from Formattable.java
4073
static final Flags LEFT_JUSTIFY = new Flags(1<<0); // '-'
4074
static final Flags UPPERCASE = new Flags(1<<1); // '^'
4075
static final Flags ALTERNATE = new Flags(1<<2); // '#'
4076

4077    // numerics
4078
static final Flags PLUS = new Flags(1<<3); // '+'
4079
static final Flags LEADING_SPACE = new Flags(1<<4); // ' '
4080
static final Flags ZERO_PAD = new Flags(1<<5); // '0'
4081
static final Flags GROUP = new Flags(1<<6); // ','
4082
static final Flags PARENTHESES = new Flags(1<<7); // '('
4083

4084    // indexing
4085
static final Flags PREVIOUS = new Flags(1<<8); // '<'
4086

4087    private Flags(int f) {
4088        flags = f;
4089    }
4090
4091    public int valueOf() {
4092        return flags;
4093    }
4094
4095    public boolean contains(Flags f) {
4096        return (flags & f.valueOf()) == f.valueOf();
4097    }
4098
4099    public Flags dup() {
4100        return new Flags(flags);
4101    }
4102
4103    private Flags add(Flags f) {
4104        flags |= f.valueOf();
4105        return this;
4106    }
4107
4108    public Flags remove(Flags f) {
4109        flags &= ~f.valueOf();
4110        return this;
4111    }
4112
4113    public static Flags parse(String JavaDoc s) {
4114        char[] ca = s.toCharArray();
4115        Flags f = new Flags(0);
4116        for (int i = 0; i < ca.length; i++) {
4117        Flags v = parse(ca[i]);
4118        if (f.contains(v))
4119            throw new DuplicateFormatFlagsException JavaDoc(v.toString());
4120        f.add(v);
4121        }
4122        return f;
4123    }
4124
4125    // parse those flags which may be provided by users
4126
private static Flags parse(char c) {
4127        switch (c) {
4128        case '-': return LEFT_JUSTIFY;
4129        case '#': return ALTERNATE;
4130        case '+': return PLUS;
4131        case ' ': return LEADING_SPACE;
4132        case '0': return ZERO_PAD;
4133        case ',': return GROUP;
4134        case '(': return PARENTHESES;
4135        case '<': return PREVIOUS;
4136        default:
4137        throw new UnknownFormatFlagsException JavaDoc(String.valueOf(c));
4138        }
4139    }
4140
4141    // Returns a string representation of the current <tt>Flags</tt>.
4142
public static String JavaDoc toString(Flags f) {
4143        return f.toString();
4144    }
4145
4146    public String JavaDoc toString() {
4147        StringBuilder JavaDoc sb = new StringBuilder JavaDoc();
4148        if (contains(LEFT_JUSTIFY)) sb.append('-');
4149        if (contains(UPPERCASE)) sb.append('^');
4150        if (contains(ALTERNATE)) sb.append('#');
4151        if (contains(PLUS)) sb.append('+');
4152        if (contains(LEADING_SPACE)) sb.append(' ');
4153        if (contains(ZERO_PAD)) sb.append('0');
4154        if (contains(GROUP)) sb.append(',');
4155        if (contains(PARENTHESES)) sb.append('(');
4156        if (contains(PREVIOUS)) sb.append('<');
4157        return sb.toString();
4158    }
4159    }
4160
4161    private static class Conversion {
4162        // Byte, Short, Integer, Long, BigInteger
4163
// (and associated primitives due to autoboxing)
4164
static final char DECIMAL_INTEGER = 'd';
4165    static final char OCTAL_INTEGER = 'o';
4166    static final char HEXADECIMAL_INTEGER = 'x';
4167    static final char HEXADECIMAL_INTEGER_UPPER = 'X';
4168
4169        // Float, Double, BigDecimal
4170
// (and associated primitives due to autoboxing)
4171
static final char SCIENTIFIC = 'e';
4172    static final char SCIENTIFIC_UPPER = 'E';
4173    static final char GENERAL = 'g';
4174    static final char GENERAL_UPPER = 'G';
4175    static final char DECIMAL_FLOAT = 'f';
4176    static final char HEXADECIMAL_FLOAT = 'a';
4177    static final char HEXADECIMAL_FLOAT_UPPER = 'A';
4178
4179        // Character, Byte, Short, Integer
4180
// (and associated primitives due to autoboxing)
4181
static final char CHARACTER = 'c';
4182    static final char CHARACTER_UPPER = 'C';
4183
4184        // java.util.Date, java.util.Calendar, long
4185
static final char DATE_TIME = 't';
4186    static final char DATE_TIME_UPPER = 'T';
4187
4188        // if (arg.TYPE != boolean) return boolean
4189
// if (arg != null) return true; else return false;
4190
static final char BOOLEAN = 'b';
4191    static final char BOOLEAN_UPPER = 'B';
4192        // if (arg instanceof Formattable) arg.formatTo()
4193
// else arg.toString();
4194
static final char STRING = 's';
4195    static final char STRING_UPPER = 'S';
4196        // arg.hashCode()
4197
static final char HASHCODE = 'h';
4198    static final char HASHCODE_UPPER = 'H';
4199
4200    static final char LINE_SEPARATOR = 'n';
4201    static final char PERCENT_SIGN = '%';
4202
4203    static boolean isValid(char c) {
4204        return (isGeneral(c) || isInteger(c) || isFloat(c) || isText(c)
4205            || c == 't' || c == 'c');
4206    }
4207
4208    // Returns true iff the Conversion is applicable to all objects.
4209
static boolean isGeneral(char c) {
4210        switch (c) {
4211        case BOOLEAN:
4212        case BOOLEAN_UPPER:
4213        case STRING:
4214        case STRING_UPPER:
4215        case HASHCODE:
4216        case HASHCODE_UPPER:
4217        return true;
4218        default:
4219        return false;
4220        }
4221    }
4222
4223    // Returns true iff the Conversion is an integer type.
4224
static boolean isInteger(char c) {
4225        switch (c) {
4226        case DECIMAL_INTEGER:
4227        case OCTAL_INTEGER:
4228        case HEXADECIMAL_INTEGER:
4229        case HEXADECIMAL_INTEGER_UPPER:
4230        return true;
4231        default:
4232        return false;
4233        }
4234    }
4235
4236    // Returns true iff the Conversion is a floating-point type.
4237
static boolean isFloat(char c) {
4238        switch (c) {
4239        case SCIENTIFIC:
4240        case SCIENTIFIC_UPPER:
4241        case GENERAL:
4242        case GENERAL_UPPER:
4243        case DECIMAL_FLOAT:
4244        case HEXADECIMAL_FLOAT:
4245        case HEXADECIMAL_FLOAT_UPPER:
4246        return true;
4247        default:
4248        return false;
4249        }
4250    }
4251
4252    // Returns true iff the Conversion does not require an argument
4253
static boolean isText(char c) {
4254        switch (c) {
4255        case LINE_SEPARATOR:
4256        case PERCENT_SIGN:
4257        return true;
4258        default:
4259        return false;
4260        }
4261    }
4262    }
4263
4264    private static class DateTime {
4265        static final char HOUR_OF_DAY_0 = 'H'; // (00 - 23)
4266
static final char HOUR_0 = 'I'; // (01 - 12)
4267
static final char HOUR_OF_DAY = 'k'; // (0 - 23) -- like H
4268
static final char HOUR = 'l'; // (1 - 12) -- like I
4269
static final char MINUTE = 'M'; // (00 - 59)
4270
static final char NANOSECOND = 'N'; // (000000000 - 999999999)
4271
static final char MILLISECOND = 'L'; // jdk, not in gnu (000 - 999)
4272
static final char MILLISECOND_SINCE_EPOCH = 'Q'; // (0 - 99...?)
4273
static final char AM_PM = 'p'; // (am or pm)
4274
static final char SECONDS_SINCE_EPOCH = 's'; // (0 - 99...?)
4275
static final char SECOND = 'S'; // (00 - 60 - leap second)
4276
static final char TIME = 'T'; // (24 hour hh:mm:ss)
4277
static final char ZONE_NUMERIC = 'z'; // (-1200 - +1200) - ls minus?
4278
static final char ZONE = 'Z'; // (symbol)
4279

4280        // Date
4281
static final char NAME_OF_DAY_ABBREV = 'a'; // 'a'
4282
static final char NAME_OF_DAY = 'A'; // 'A'
4283
static final char NAME_OF_MONTH_ABBREV = 'b'; // 'b'
4284
static final char NAME_OF_MONTH = 'B'; // 'B'
4285
static final char CENTURY = 'C'; // (00 - 99)
4286
static final char DAY_OF_MONTH_0 = 'd'; // (01 - 31)
4287
static final char DAY_OF_MONTH = 'e'; // (1 - 31) -- like d
4288
// * static final char ISO_WEEK_OF_YEAR_2 = 'g'; // cross %y %V
4289
// * static final char ISO_WEEK_OF_YEAR_4 = 'G'; // cross %Y %V
4290
static final char NAME_OF_MONTH_ABBREV_X = 'h'; // -- same b
4291
static final char DAY_OF_YEAR = 'j'; // (001 - 366)
4292
static final char MONTH = 'm'; // (01 - 12)
4293
// * static final char DAY_OF_WEEK_1 = 'u'; // (1 - 7) Monday
4294
// * static final char WEEK_OF_YEAR_SUNDAY = 'U'; // (0 - 53) Sunday+
4295
// * static final char WEEK_OF_YEAR_MONDAY_01 = 'V'; // (01 - 53) Monday+
4296
// * static final char DAY_OF_WEEK_0 = 'w'; // (0 - 6) Sunday
4297
// * static final char WEEK_OF_YEAR_MONDAY = 'W'; // (00 - 53) Monday
4298
static final char YEAR_2 = 'y'; // (00 - 99)
4299
static final char YEAR_4 = 'Y'; // (0000 - 9999)
4300

4301    // Composites
4302
static final char TIME_12_HOUR = 'r'; // (hh:mm:ss [AP]M)
4303
static final char TIME_24_HOUR = 'R'; // (hh:mm same as %H:%M)
4304
// * static final char LOCALE_TIME = 'X'; // (%H:%M:%S) - parse format?
4305
static final char DATE_TIME = 'c';
4306                                            // (Sat Nov 04 12:02:33 EST 1999)
4307
static final char DATE = 'D'; // (mm/dd/yy)
4308
static final char ISO_STANDARD_DATE = 'F'; // (%Y-%m-%d)
4309
// * static final char LOCALE_DATE = 'x'; // (mm/dd/yy)
4310

4311    static boolean isValid(char c) {
4312        switch (c) {
4313        case HOUR_OF_DAY_0:
4314        case HOUR_0:
4315        case HOUR_OF_DAY:
4316        case HOUR:
4317        case MINUTE:
4318        case NANOSECOND:
4319        case MILLISECOND:
4320        case MILLISECOND_SINCE_EPOCH:
4321        case AM_PM:
4322        case SECONDS_SINCE_EPOCH:
4323        case SECOND:
4324        case TIME:
4325        case ZONE_NUMERIC:
4326        case ZONE:
4327
4328            // Date
4329
case NAME_OF_DAY_ABBREV:
4330        case NAME_OF_DAY:
4331        case NAME_OF_MONTH_ABBREV:
4332        case NAME_OF_MONTH:
4333        case CENTURY:
4334        case DAY_OF_MONTH_0:
4335        case DAY_OF_MONTH:
4336// * case ISO_WEEK_OF_YEAR_2:
4337
// * case ISO_WEEK_OF_YEAR_4:
4338
case NAME_OF_MONTH_ABBREV_X:
4339        case DAY_OF_YEAR:
4340        case MONTH:
4341// * case DAY_OF_WEEK_1:
4342
// * case WEEK_OF_YEAR_SUNDAY:
4343
// * case WEEK_OF_YEAR_MONDAY_01:
4344
// * case DAY_OF_WEEK_0:
4345
// * case WEEK_OF_YEAR_MONDAY:
4346
case YEAR_2:
4347        case YEAR_4:
4348
4349        // Composites
4350
case TIME_12_HOUR:
4351        case TIME_24_HOUR:
4352// * case LOCALE_TIME:
4353
case DATE_TIME:
4354        case DATE:
4355        case ISO_STANDARD_DATE:
4356// * case LOCALE_DATE:
4357
return true;
4358        default:
4359        return false;
4360        }
4361    }
4362    }
4363}
4364
Popular Tags