blob: ad4dca1d3e66e41da4d3a496feafcf70cc63dc16 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package java.util;
27
28import java.io.BufferedWriter;
29import java.io.Closeable;
30import java.io.IOException;
31import java.io.File;
32import java.io.FileOutputStream;
33import java.io.FileNotFoundException;
34import java.io.Flushable;
35import java.io.OutputStream;
36import java.io.OutputStreamWriter;
37import java.io.PrintStream;
38import java.io.UnsupportedEncodingException;
39import java.math.BigDecimal;
40import java.math.BigInteger;
41import java.math.MathContext;
42import java.nio.charset.Charset;
43import java.text.DateFormatSymbols;
44import java.text.DecimalFormat;
45import java.text.DecimalFormatSymbols;
46import java.text.NumberFormat;
47import java.util.Calendar;
48import java.util.Date;
49import java.util.Locale;
50import java.util.regex.Matcher;
51import java.util.regex.Pattern;
52
53import sun.misc.FpUtils;
54import sun.misc.DoubleConsts;
55import sun.misc.FormattedFloatingDecimal;
56
57/**
58 * An interpreter for printf-style format strings. This class provides support
59 * for layout justification and alignment, common formats for numeric, string,
60 * and date/time data, and locale-specific output. Common Java types such as
61 * <tt>byte</tt>, {@link java.math.BigDecimal BigDecimal}, and {@link Calendar}
62 * are supported. Limited formatting customization for arbitrary user types is
63 * provided through the {@link Formattable} interface.
64 *
65 * <p> Formatters are not necessarily safe for multithreaded access. Thread
66 * safety is optional and is the responsibility of users of methods in this
67 * class.
68 *
69 * <p> Formatted printing for the Java language is heavily inspired by C's
70 * <tt>printf</tt>. Although the format strings are similar to C, some
71 * customizations have been made to accommodate the Java language and exploit
72 * some of its features. Also, Java formatting is more strict than C's; for
73 * example, if a conversion is incompatible with a flag, an exception will be
74 * thrown. In C inapplicable flags are silently ignored. The format strings
75 * are thus intended to be recognizable to C programmers but not necessarily
76 * completely compatible with those in C.
77 *
78 * <p> Examples of expected usage:
79 *
80 * <blockquote><pre>
81 * StringBuilder sb = new StringBuilder();
82 * // Send all output to the Appendable object sb
83 * Formatter formatter = new Formatter(sb, Locale.US);
84 *
85 * // Explicit argument indices may be used to re-order output.
86 * formatter.format("%4$2s %3$2s %2$2s %1$2s", "a", "b", "c", "d")
87 * // -&gt; " d c b a"
88 *
89 * // Optional locale as the first argument can be used to get
90 * // locale-specific formatting of numbers. The precision and width can be
91 * // given to round and align the value.
92 * formatter.format(Locale.FRANCE, "e = %+10.4f", Math.E);
93 * // -&gt; "e = +2,7183"
94 *
95 * // The '(' numeric flag may be used to format negative numbers with
96 * // parentheses rather than a minus sign. Group separators are
97 * // automatically inserted.
98 * formatter.format("Amount gained or lost since last statement: $ %(,.2f",
99 * balanceDelta);
100 * // -&gt; "Amount gained or lost since last statement: $ (6,217.58)"
101 * </pre></blockquote>
102 *
103 * <p> Convenience methods for common formatting requests exist as illustrated
104 * by the following invocations:
105 *
106 * <blockquote><pre>
107 * // Writes a formatted string to System.out.
108 * System.out.format("Local time: %tT", Calendar.getInstance());
109 * // -&gt; "Local time: 13:34:18"
110 *
111 * // Writes formatted output to System.err.
112 * System.err.printf("Unable to open file '%1$s': %2$s",
113 * fileName, exception.getMessage());
114 * // -&gt; "Unable to open file 'food': No such file or directory"
115 * </pre></blockquote>
116 *
117 * <p> Like C's <tt>sprintf(3)</tt>, Strings may be formatted using the static
118 * method {@link String#format(String,Object...) String.format}:
119 *
120 * <blockquote><pre>
121 * // Format a string containing a date.
122 * import java.util.Calendar;
123 * import java.util.GregorianCalendar;
124 * import static java.util.Calendar.*;
125 *
126 * Calendar c = new GregorianCalendar(1995, MAY, 23);
127 * String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
128 * // -&gt; s == "Duke's Birthday: May 23, 1995"
129 * </pre></blockquote>
130 *
131 * <h3><a name="org">Organization</a></h3>
132 *
133 * <p> This specification is divided into two sections. The first section, <a
134 * href="#summary">Summary</a>, covers the basic formatting concepts. This
135 * section is intended for users who want to get started quickly and are
136 * familiar with formatted printing in other programming languages. The second
137 * section, <a href="#detail">Details</a>, covers the specific implementation
138 * details. It is intended for users who want more precise specification of
139 * formatting behavior.
140 *
141 * <h3><a name="summary">Summary</a></h3>
142 *
143 * <p> This section is intended to provide a brief overview of formatting
144 * concepts. For precise behavioral details, refer to the <a
145 * href="#detail">Details</a> section.
146 *
147 * <h4><a name="syntax">Format String Syntax</a></h4>
148 *
149 * <p> Every method which produces formatted output requires a <i>format
150 * string</i> and an <i>argument list</i>. The format string is a {@link
151 * String} which may contain fixed text and one or more embedded <i>format
152 * specifiers</i>. Consider the following example:
153 *
154 * <blockquote><pre>
155 * Calendar c = ...;
156 * String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
157 * </pre></blockquote>
158 *
159 * This format string is the first argument to the <tt>format</tt> method. It
160 * contains three format specifiers "<tt>%1$tm</tt>", "<tt>%1$te</tt>", and
161 * "<tt>%1$tY</tt>" which indicate how the arguments should be processed and
162 * where they should be inserted in the text. The remaining portions of the
163 * format string are fixed text including <tt>"Dukes Birthday: "</tt> and any
164 * other spaces or punctuation.
165 *
166 * The argument list consists of all arguments passed to the method after the
167 * format string. In the above example, the argument list is of size one and
168 * consists of the {@link java.util.Calendar Calendar} object <tt>c</tt>.
169 *
170 * <ul>
171 *
172 * <li> The format specifiers for general, character, and numeric types have
173 * the following syntax:
174 *
175 * <blockquote><pre>
176 * %[argument_index$][flags][width][.precision]conversion
177 * </pre></blockquote>
178 *
179 * <p> The optional <i>argument_index</i> is a decimal integer indicating the
180 * position of the argument in the argument list. The first argument is
181 * referenced by "<tt>1$</tt>", the second by "<tt>2$</tt>", etc.
182 *
183 * <p> The optional <i>flags</i> is a set of characters that modify the output
184 * format. The set of valid flags depends on the conversion.
185 *
186 * <p> The optional <i>width</i> is a non-negative decimal integer indicating
187 * the minimum number of characters to be written to the output.
188 *
189 * <p> The optional <i>precision</i> is a non-negative decimal integer usually
190 * used to restrict the number of characters. The specific behavior depends on
191 * the conversion.
192 *
193 * <p> The required <i>conversion</i> is a character indicating how the
194 * argument should be formatted. The set of valid conversions for a given
195 * argument depends on the argument's data type.
196 *
197 * <li> The format specifiers for types which are used to represents dates and
198 * times have the following syntax:
199 *
200 * <blockquote><pre>
201 * %[argument_index$][flags][width]conversion
202 * </pre></blockquote>
203 *
204 * <p> The optional <i>argument_index</i>, <i>flags</i> and <i>width</i> are
205 * defined as above.
206 *
207 * <p> The required <i>conversion</i> is a two character sequence. The first
208 * character is <tt>'t'</tt> or <tt>'T'</tt>. The second character indicates
209 * the format to be used. These characters are similar to but not completely
210 * identical to those defined by GNU <tt>date</tt> and POSIX
211 * <tt>strftime(3c)</tt>.
212 *
213 * <li> The format specifiers which do not correspond to arguments have the
214 * following syntax:
215 *
216 * <blockquote><pre>
217 * %[flags][width]conversion
218 * </pre></blockquote>
219 *
220 * <p> The optional <i>flags</i> and <i>width</i> is defined as above.
221 *
222 * <p> The required <i>conversion</i> is a character indicating content to be
223 * inserted in the output.
224 *
225 * </ul>
226 *
227 * <h4> Conversions </h4>
228 *
229 * <p> Conversions are divided into the following categories:
230 *
231 * <ol>
232 *
233 * <li> <b>General</b> - may be applied to any argument
234 * type
235 *
236 * <li> <b>Character</b> - may be applied to basic types which represent
237 * Unicode characters: <tt>char</tt>, {@link Character}, <tt>byte</tt>, {@link
238 * Byte}, <tt>short</tt>, and {@link Short}. This conversion may also be
239 * applied to the types <tt>int</tt> and {@link Integer} when {@link
240 * Character#isValidCodePoint} returns <tt>true</tt>
241 *
242 * <li> <b>Numeric</b>
243 *
244 * <ol>
245 *
246 * <li> <b>Integral</b> - may be applied to Java integral types: <tt>byte</tt>,
247 * {@link Byte}, <tt>short</tt>, {@link Short}, <tt>int</tt> and {@link
248 * Integer}, <tt>long</tt>, {@link Long}, and {@link java.math.BigInteger
249 * BigInteger}
250 *
251 * <li><b>Floating Point</b> - may be applied to Java floating-point types:
252 * <tt>float</tt>, {@link Float}, <tt>double</tt>, {@link Double}, and {@link
253 * java.math.BigDecimal BigDecimal}
254 *
255 * </ol>
256 *
257 * <li> <b>Date/Time</b> - may be applied to Java types which are capable of
258 * encoding a date or time: <tt>long</tt>, {@link Long}, {@link Calendar}, and
259 * {@link Date}.
260 *
261 * <li> <b>Percent</b> - produces a literal <tt>'%'</tt>
262 * (<tt>'&#92;u0025'</tt>)
263 *
264 * <li> <b>Line Separator</b> - produces the platform-specific line separator
265 *
266 * </ol>
267 *
268 * <p> The following table summarizes the supported conversions. Conversions
269 * denoted by an upper-case character (i.e. <tt>'B'</tt>, <tt>'H'</tt>,
270 * <tt>'S'</tt>, <tt>'C'</tt>, <tt>'X'</tt>, <tt>'E'</tt>, <tt>'G'</tt>,
271 * <tt>'A'</tt>, and <tt>'T'</tt>) are the same as those for the corresponding
272 * lower-case conversion characters except that the result is converted to
273 * upper case according to the rules of the prevailing {@link java.util.Locale
274 * Locale}. The result is equivalent to the following invocation of {@link
275 * String#toUpperCase()}
276 *
277 * <pre>
278 * out.toUpperCase() </pre>
279 *
280 * <table cellpadding=5 summary="genConv">
281 *
282 * <tr><th valign="bottom"> Conversion
283 * <th valign="bottom"> Argument Category
284 * <th valign="bottom"> Description
285 *
286 * <tr><td valign="top"> <tt>'b'</tt>, <tt>'B'</tt>
287 * <td valign="top"> general
288 * <td> If the argument <i>arg</i> is <tt>null</tt>, then the result is
289 * "<tt>false</tt>". If <i>arg</i> is a <tt>boolean</tt> or {@link
290 * Boolean}, then the result is the string returned by {@link
291 * String#valueOf(boolean) String.valueOf(arg)}. Otherwise, the result is
292 * "true".
293 *
294 * <tr><td valign="top"> <tt>'h'</tt>, <tt>'H'</tt>
295 * <td valign="top"> general
296 * <td> If the argument <i>arg</i> is <tt>null</tt>, then the result is
297 * "<tt>null</tt>". Otherwise, the result is obtained by invoking
298 * <tt>Integer.toHexString(arg.hashCode())</tt>.
299 *
300 * <tr><td valign="top"> <tt>'s'</tt>, <tt>'S'</tt>
301 * <td valign="top"> general
302 * <td> If the argument <i>arg</i> is <tt>null</tt>, then the result is
303 * "<tt>null</tt>". If <i>arg</i> implements {@link Formattable}, then
304 * {@link Formattable#formatTo arg.formatTo} is invoked. Otherwise, the
305 * result is obtained by invoking <tt>arg.toString()</tt>.
306 *
307 * <tr><td valign="top"><tt>'c'</tt>, <tt>'C'</tt>
308 * <td valign="top"> character
309 * <td> The result is a Unicode character
310 *
311 * <tr><td valign="top"><tt>'d'</tt>
312 * <td valign="top"> integral
313 * <td> The result is formatted as a decimal integer
314 *
315 * <tr><td valign="top"><tt>'o'</tt>
316 * <td valign="top"> integral
317 * <td> The result is formatted as an octal integer
318 *
319 * <tr><td valign="top"><tt>'x'</tt>, <tt>'X'</tt>
320 * <td valign="top"> integral
321 * <td> The result is formatted as a hexadecimal integer
322 *
323 * <tr><td valign="top"><tt>'e'</tt>, <tt>'E'</tt>
324 * <td valign="top"> floating point
325 * <td> The result is formatted as a decimal number in computerized
326 * scientific notation
327 *
328 * <tr><td valign="top"><tt>'f'</tt>
329 * <td valign="top"> floating point
330 * <td> The result is formatted as a decimal number
331 *
332 * <tr><td valign="top"><tt>'g'</tt>, <tt>'G'</tt>
333 * <td valign="top"> floating point
334 * <td> The result is formatted using computerized scientific notation or
335 * decimal format, depending on the precision and the value after rounding.
336 *
337 * <tr><td valign="top"><tt>'a'</tt>, <tt>'A'</tt>
338 * <td valign="top"> floating point
339 * <td> The result is formatted as a hexadecimal floating-point number with
340 * a significand and an exponent
341 *
342 * <tr><td valign="top"><tt>'t'</tt>, <tt>'T'</tt>
343 * <td valign="top"> date/time
344 * <td> Prefix for date and time conversion characters. See <a
345 * href="#dt">Date/Time Conversions</a>.
346 *
347 * <tr><td valign="top"><tt>'%'</tt>
348 * <td valign="top"> percent
349 * <td> The result is a literal <tt>'%'</tt> (<tt>'&#92;u0025'</tt>)
350 *
351 * <tr><td valign="top"><tt>'n'</tt>
352 * <td valign="top"> line separator
353 * <td> The result is the platform-specific line separator
354 *
355 * </table>
356 *
357 * <p> Any characters not explicitly defined as conversions are illegal and are
358 * reserved for future extensions.
359 *
360 * <h4><a name="dt">Date/Time Conversions</a></h4>
361 *
362 * <p> The following date and time conversion suffix characters are defined for
363 * the <tt>'t'</tt> and <tt>'T'</tt> conversions. The types are similar to but
364 * not completely identical to those defined by GNU <tt>date</tt> and POSIX
365 * <tt>strftime(3c)</tt>. Additional conversion types are provided to access
366 * Java-specific functionality (e.g. <tt>'L'</tt> for milliseconds within the
367 * second).
368 *
369 * <p> The following conversion characters are used for formatting times:
370 *
371 * <table cellpadding=5 summary="time">
372 *
373 * <tr><td valign="top"> <tt>'H'</tt>
374 * <td> Hour of the day for the 24-hour clock, formatted as two digits with
375 * a leading zero as necessary i.e. <tt>00 - 23</tt>.
376 *
377 * <tr><td valign="top"><tt>'I'</tt>
378 * <td> Hour for the 12-hour clock, formatted as two digits with a leading
379 * zero as necessary, i.e. <tt>01 - 12</tt>.
380 *
381 * <tr><td valign="top"><tt>'k'</tt>
382 * <td> Hour of the day for the 24-hour clock, i.e. <tt>0 - 23</tt>.
383 *
384 * <tr><td valign="top"><tt>'l'</tt>
385 * <td> Hour for the 12-hour clock, i.e. <tt>1 - 12</tt>.
386 *
387 * <tr><td valign="top"><tt>'M'</tt>
388 * <td> Minute within the hour formatted as two digits with a leading zero
389 * as necessary, i.e. <tt>00 - 59</tt>.
390 *
391 * <tr><td valign="top"><tt>'S'</tt>
392 * <td> Seconds within the minute, formatted as two digits with a leading
393 * zero as necessary, i.e. <tt>00 - 60</tt> ("<tt>60</tt>" is a special
394 * value required to support leap seconds).
395 *
396 * <tr><td valign="top"><tt>'L'</tt>
397 * <td> Millisecond within the second formatted as three digits with
398 * leading zeros as necessary, i.e. <tt>000 - 999</tt>.
399 *
400 * <tr><td valign="top"><tt>'N'</tt>
401 * <td> Nanosecond within the second, formatted as nine digits with leading
402 * zeros as necessary, i.e. <tt>000000000 - 999999999</tt>.
403 *
404 * <tr><td valign="top"><tt>'p'</tt>
405 * <td> Locale-specific {@linkplain
406 * java.text.DateFormatSymbols#getAmPmStrings morning or afternoon} marker
407 * in lower case, e.g."<tt>am</tt>" or "<tt>pm</tt>". Use of the conversion
408 * prefix <tt>'T'</tt> forces this output to upper case.
409 *
410 * <tr><td valign="top"><tt>'z'</tt>
411 * <td> <a href="http://www.ietf.org/rfc/rfc0822.txt">RFC&nbsp;822</a>
412 * style numeric time zone offset from GMT, e.g. <tt>-0800</tt>. This
413 * value will be adjusted as necessary for Daylight Saving Time. For
414 * <tt>long</tt>, {@link Long}, and {@link Date} the time zone used is
415 * the {@plainlink TimeZone#getDefault() default time zone} for this
416 * instance of the Java virtual machine.
417 *
418 * <tr><td valign="top"><tt>'Z'</tt>
419 * <td> A string representing the abbreviation for the time zone. This
420 * value will be adjusted as necessary for Daylight Saving Time. For
421 * <tt>long</tt>, {@link Long}, and {@link Date} the time zone used is
422 * the {@plainlink TimeZone#getDefault() default time zone} for this
423 * instance of the Java virtual machine. The Formatter's locale will
424 * supersede the locale of the argument (if any).
425 *
426 * <tr><td valign="top"><tt>'s'</tt>
427 * <td> Seconds since the beginning of the epoch starting at 1 January 1970
428 * <tt>00:00:00</tt> UTC, i.e. <tt>Long.MIN_VALUE/1000</tt> to
429 * <tt>Long.MAX_VALUE/1000</tt>.
430 *
431 * <tr><td valign="top"><tt>'Q'</tt>
432 * <td> Milliseconds since the beginning of the epoch starting at 1 January
433 * 1970 <tt>00:00:00</tt> UTC, i.e. <tt>Long.MIN_VALUE</tt> to
434 * <tt>Long.MAX_VALUE</tt>.
435 *
436 * </table>
437 *
438 * <p> The following conversion characters are used for formatting dates:
439 *
440 * <table cellpadding=5 summary="date">
441 *
442 * <tr><td valign="top"><tt>'B'</tt>
443 * <td> Locale-specific {@linkplain java.text.DateFormatSymbols#getMonths
444 * full month name}, e.g. <tt>"January"</tt>, <tt>"February"</tt>.
445 *
446 * <tr><td valign="top"><tt>'b'</tt>
447 * <td> Locale-specific {@linkplain
448 * java.text.DateFormatSymbols#getShortMonths abbreviated month name},
449 * e.g. <tt>"Jan"</tt>, <tt>"Feb"</tt>.
450 *
451 * <tr><td valign="top"><tt>'h'</tt>
452 * <td> Same as <tt>'b'</tt>.
453 *
454 * <tr><td valign="top"><tt>'A'</tt>
455 * <td> Locale-specific full name of the {@linkplain
456 * java.text.DateFormatSymbols#getWeekdays day of the week},
457 * e.g. <tt>"Sunday"</tt>, <tt>"Monday"</tt>
458 *
459 * <tr><td valign="top"><tt>'a'</tt>
460 * <td> Locale-specific short name of the {@linkplain
461 * java.text.DateFormatSymbols#getShortWeekdays day of the week},
462 * e.g. <tt>"Sun"</tt>, <tt>"Mon"</tt>
463 *
464 * <tr><td valign="top"><tt>'C'</tt>
465 * <td> Four-digit year divided by <tt>100</tt>, formatted as two digits
466 * with leading zero as necessary, i.e. <tt>00 - 99</tt>
467 *
468 * <tr><td valign="top"><tt>'Y'</tt>
469 * <td> Year, formatted as at least four digits with leading zeros as
470 * necessary, e.g. <tt>0092</tt> equals <tt>92</tt> CE for the Gregorian
471 * calendar.
472 *
473 * <tr><td valign="top"><tt>'y'</tt>
474 * <td> Last two digits of the year, formatted with leading zeros as
475 * necessary, i.e. <tt>00 - 99</tt>.
476 *
477 * <tr><td valign="top"><tt>'j'</tt>
478 * <td> Day of year, formatted as three digits with leading zeros as
479 * necessary, e.g. <tt>001 - 366</tt> for the Gregorian calendar.
480 *
481 * <tr><td valign="top"><tt>'m'</tt>
482 * <td> Month, formatted as two digits with leading zeros as necessary,
483 * i.e. <tt>01 - 13</tt>.
484 *
485 * <tr><td valign="top"><tt>'d'</tt>
486 * <td> Day of month, formatted as two digits with leading zeros as
487 * necessary, i.e. <tt>01 - 31</tt>
488 *
489 * <tr><td valign="top"><tt>'e'</tt>
490 * <td> Day of month, formatted as two digits, i.e. <tt>1 - 31</tt>.
491 *
492 * </table>
493 *
494 * <p> The following conversion characters are used for formatting common
495 * date/time compositions.
496 *
497 * <table cellpadding=5 summary="composites">
498 *
499 * <tr><td valign="top"><tt>'R'</tt>
500 * <td> Time formatted for the 24-hour clock as <tt>"%tH:%tM"</tt>
501 *
502 * <tr><td valign="top"><tt>'T'</tt>
503 * <td> Time formatted for the 24-hour clock as <tt>"%tH:%tM:%tS"</tt>.
504 *
505 * <tr><td valign="top"><tt>'r'</tt>
506 * <td> Time formatted for the 12-hour clock as <tt>"%tI:%tM:%tS %Tp"</tt>.
507 * The location of the morning or afternoon marker (<tt>'%Tp'</tt>) may be
508 * locale-dependent.
509 *
510 * <tr><td valign="top"><tt>'D'</tt>
511 * <td> Date formatted as <tt>"%tm/%td/%ty"</tt>.
512 *
513 * <tr><td valign="top"><tt>'F'</tt>
514 * <td> <a href="http://www.w3.org/TR/NOTE-datetime">ISO&nbsp;8601</a>
515 * complete date formatted as <tt>"%tY-%tm-%td"</tt>.
516 *
517 * <tr><td valign="top"><tt>'c'</tt>
518 * <td> Date and time formatted as <tt>"%ta %tb %td %tT %tZ %tY"</tt>,
519 * e.g. <tt>"Sun Jul 20 16:17:00 EDT 1969"</tt>.
520 *
521 * </table>
522 *
523 * <p> Any characters not explicitly defined as date/time conversion suffixes
524 * are illegal and are reserved for future extensions.
525 *
526 * <h4> Flags </h4>
527 *
528 * <p> The following table summarizes the supported flags. <i>y</i> means the
529 * flag is supported for the indicated argument types.
530 *
531 * <table cellpadding=5 summary="genConv">
532 *
533 * <tr><th valign="bottom"> Flag <th valign="bottom"> General
534 * <th valign="bottom"> Character <th valign="bottom"> Integral
535 * <th valign="bottom"> Floating Point
536 * <th valign="bottom"> Date/Time
537 * <th valign="bottom"> Description
538 *
539 * <tr><td> '-' <td align="center" valign="top"> y
540 * <td align="center" valign="top"> y
541 * <td align="center" valign="top"> y
542 * <td align="center" valign="top"> y
543 * <td align="center" valign="top"> y
544 * <td> The result will be left-justified.
545 *
546 * <tr><td> '#' <td align="center" valign="top"> y<sup>1</sup>
547 * <td align="center" valign="top"> -
548 * <td align="center" valign="top"> y<sup>3</sup>
549 * <td align="center" valign="top"> y
550 * <td align="center" valign="top"> -
551 * <td> The result should use a conversion-dependent alternate form
552 *
553 * <tr><td> '+' <td align="center" valign="top"> -
554 * <td align="center" valign="top"> -
555 * <td align="center" valign="top"> y<sup>4</sup>
556 * <td align="center" valign="top"> y
557 * <td align="center" valign="top"> -
558 * <td> The result will always include a sign
559 *
560 * <tr><td> '&nbsp;&nbsp;' <td align="center" valign="top"> -
561 * <td align="center" valign="top"> -
562 * <td align="center" valign="top"> y<sup>4</sup>
563 * <td align="center" valign="top"> y
564 * <td align="center" valign="top"> -
565 * <td> The result will include a leading space for positive values
566 *
567 * <tr><td> '0' <td align="center" valign="top"> -
568 * <td align="center" valign="top"> -
569 * <td align="center" valign="top"> y
570 * <td align="center" valign="top"> y
571 * <td align="center" valign="top"> -
572 * <td> The result will be zero-padded
573 *
574 * <tr><td> ',' <td align="center" valign="top"> -
575 * <td align="center" valign="top"> -
576 * <td align="center" valign="top"> y<sup>2</sup>
577 * <td align="center" valign="top"> y<sup>5</sup>
578 * <td align="center" valign="top"> -
579 * <td> The result will include locale-specific {@linkplain
580 * java.text.DecimalFormatSymbols#getGroupingSeparator grouping separators}
581 *
582 * <tr><td> '(' <td align="center" valign="top"> -
583 * <td align="center" valign="top"> -
584 * <td align="center" valign="top"> y<sup>4</sup>
585 * <td align="center" valign="top"> y<sup>5</sup>
586 * <td align="center"> -
587 * <td> The result will enclose negative numbers in parentheses
588 *
589 * </table>
590 *
591 * <p> <sup>1</sup> Depends on the definition of {@link Formattable}.
592 *
593 * <p> <sup>2</sup> For <tt>'d'</tt> conversion only.
594 *
595 * <p> <sup>3</sup> For <tt>'o'</tt>, <tt>'x'</tt>, and <tt>'X'</tt>
596 * conversions only.
597 *
598 * <p> <sup>4</sup> For <tt>'d'</tt>, <tt>'o'</tt>, <tt>'x'</tt>, and
599 * <tt>'X'</tt> conversions applied to {@link java.math.BigInteger BigInteger}
600 * or <tt>'d'</tt> applied to <tt>byte</tt>, {@link Byte}, <tt>short</tt>, {@link
601 * Short}, <tt>int</tt> and {@link Integer}, <tt>long</tt>, and {@link Long}.
602 *
603 * <p> <sup>5</sup> For <tt>'e'</tt>, <tt>'E'</tt>, <tt>'f'</tt>,
604 * <tt>'g'</tt>, and <tt>'G'</tt> conversions only.
605 *
606 * <p> Any characters not explicitly defined as flags are illegal and are
607 * reserved for future extensions.
608 *
609 * <h4> Width </h4>
610 *
611 * <p> The width is the minimum number of characters to be written to the
612 * output. For the line separator conversion, width is not applicable; if it
613 * is provided, an exception will be thrown.
614 *
615 * <h4> Precision </h4>
616 *
617 * <p> For general argument types, the precision is the maximum number of
618 * characters to be written to the output.
619 *
620 * <p> For the floating-point conversions <tt>'e'</tt>, <tt>'E'</tt>, and
621 * <tt>'f'</tt> the precision is the number of digits after the decimal
622 * separator. If the conversion is <tt>'g'</tt> or <tt>'G'</tt>, then the
623 * precision is the total number of digits in the resulting magnitude after
624 * rounding. If the conversion is <tt>'a'</tt> or <tt>'A'</tt>, then the
625 * precision must not be specified.
626 *
627 * <p> For character, integral, and date/time argument types and the percent
628 * and line separator conversions, the precision is not applicable; if a
629 * precision is provided, an exception will be thrown.
630 *
631 * <h4> Argument Index </h4>
632 *
633 * <p> The argument index is a decimal integer indicating the position of the
634 * argument in the argument list. The first argument is referenced by
635 * "<tt>1$</tt>", the second by "<tt>2$</tt>", etc.
636 *
637 * <p> Another way to reference arguments by position is to use the
638 * <tt>'&lt;'</tt> (<tt>'&#92;u003c'</tt>) flag, which causes the argument for
639 * the previous format specifier to be re-used. For example, the following two
640 * statements would produce identical strings:
641 *
642 * <blockquote><pre>
643 * Calendar c = ...;
644 * String s1 = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
645 *
646 * String s2 = String.format("Duke's Birthday: %1$tm %&lt;te,%&lt;tY", c);
647 * </pre></blockquote>
648 *
649 * <hr>
650 * <h3><a name="detail">Details</a></h3>
651 *
652 * <p> This section is intended to provide behavioral details for formatting,
653 * including conditions and exceptions, supported data types, localization, and
654 * interactions between flags, conversions, and data types. For an overview of
655 * formatting concepts, refer to the <a href="#summary">Summary</a>
656 *
657 * <p> Any characters not explicitly defined as conversions, date/time
658 * conversion suffixes, or flags are illegal and are reserved for
659 * future extensions. Use of such a character in a format string will
660 * cause an {@link UnknownFormatConversionException} or {@link
661 * UnknownFormatFlagsException} to be thrown.
662 *
663 * <p> If the format specifier contains a width or precision with an invalid
664 * value or which is otherwise unsupported, then a {@link
665 * IllegalFormatWidthException} or {@link IllegalFormatPrecisionException}
666 * respectively will be thrown.
667 *
668 * <p> If a format specifier contains a conversion character that is not
669 * applicable to the corresponding argument, then an {@link
670 * IllegalFormatConversionException} will be thrown.
671 *
672 * <p> All specified exceptions may be thrown by any of the <tt>format</tt>
673 * methods of <tt>Formatter</tt> as well as by any <tt>format</tt> convenience
674 * methods such as {@link String#format(String,Object...) String.format} and
675 * {@link java.io.PrintStream#printf(String,Object...) PrintStream.printf}.
676 *
677 * <p> Conversions denoted by an upper-case character (i.e. <tt>'B'</tt>,
678 * <tt>'H'</tt>, <tt>'S'</tt>, <tt>'C'</tt>, <tt>'X'</tt>, <tt>'E'</tt>,
679 * <tt>'G'</tt>, <tt>'A'</tt>, and <tt>'T'</tt>) are the same as those for the
680 * corresponding lower-case conversion characters except that the result is
681 * converted to upper case according to the rules of the prevailing {@link
682 * java.util.Locale Locale}. The result is equivalent to the following
683 * invocation of {@link String#toUpperCase()}
684 *
685 * <pre>
686 * out.toUpperCase() </pre>
687 *
688 * <h4><a name="dgen">General</a></h4>
689 *
690 * <p> The following general conversions may be applied to any argument type:
691 *
692 * <table cellpadding=5 summary="dgConv">
693 *
694 * <tr><td valign="top"> <tt>'b'</tt>
695 * <td valign="top"> <tt>'&#92;u0062'</tt>
696 * <td> Produces either "<tt>true</tt>" or "<tt>false</tt>" as returned by
697 * {@link Boolean#toString(boolean)}.
698 *
699 * <p> If the argument is <tt>null</tt>, then the result is
700 * "<tt>false</tt>". If the argument is a <tt>boolean</tt> or {@link
701 * Boolean}, then the result is the string returned by {@link
702 * String#valueOf(boolean) String.valueOf()}. Otherwise, the result is
703 * "<tt>true</tt>".
704 *
705 * <p> If the <tt>'#'</tt> flag is given, then a {@link
706 * FormatFlagsConversionMismatchException} will be thrown.
707 *
708 * <tr><td valign="top"> <tt>'B'</tt>
709 * <td valign="top"> <tt>'&#92;u0042'</tt>
710 * <td> The upper-case variant of <tt>'b'</tt>.
711 *
712 * <tr><td valign="top"> <tt>'h'</tt>
713 * <td valign="top"> <tt>'&#92;u0068'</tt>
714 * <td> Produces a string representing the hash code value of the object.
715 *
716 * <p> If the argument, <i>arg</i> is <tt>null</tt>, then the
717 * result is "<tt>null</tt>". Otherwise, the result is obtained
718 * by invoking <tt>Integer.toHexString(arg.hashCode())</tt>.
719 *
720 * <p> If the <tt>'#'</tt> flag is given, then a {@link
721 * FormatFlagsConversionMismatchException} will be thrown.
722 *
723 * <tr><td valign="top"> <tt>'H'</tt>
724 * <td valign="top"> <tt>'&#92;u0048'</tt>
725 * <td> The upper-case variant of <tt>'h'</tt>.
726 *
727 * <tr><td valign="top"> <tt>'s'</tt>
728 * <td valign="top"> <tt>'&#92;u0073'</tt>
729 * <td> Produces a string.
730 *
731 * <p> If the argument is <tt>null</tt>, then the result is
732 * "<tt>null</tt>". If the argument implements {@link Formattable}, then
733 * its {@link Formattable#formatTo formatTo} method is invoked.
734 * Otherwise, the result is obtained by invoking the argument's
735 * <tt>toString()</tt> method.
736 *
737 * <p> If the <tt>'#'</tt> flag is given and the argument is not a {@link
738 * Formattable} , then a {@link FormatFlagsConversionMismatchException}
739 * will be thrown.
740 *
741 * <tr><td valign="top"> <tt>'S'</tt>
742 * <td valign="top"> <tt>'&#92;u0053'</tt>
743 * <td> The upper-case variant of <tt>'s'</tt>.
744 *
745 * </table>
746 *
747 * <p> The following <a name="dFlags">flags</a> apply to general conversions:
748 *
749 * <table cellpadding=5 summary="dFlags">
750 *
751 * <tr><td valign="top"> <tt>'-'</tt>
752 * <td valign="top"> <tt>'&#92;u002d'</tt>
753 * <td> Left justifies the output. Spaces (<tt>'&#92;u0020'</tt>) will be
754 * added at the end of the converted value as required to fill the minimum
755 * width of the field. If the width is not provided, then a {@link
756 * MissingFormatWidthException} will be thrown. If this flag is not given
757 * then the output will be right-justified.
758 *
759 * <tr><td valign="top"> <tt>'#'</tt>
760 * <td valign="top"> <tt>'&#92;u0023'</tt>
761 * <td> Requires the output use an alternate form. The definition of the
762 * form is specified by the conversion.
763 *
764 * </table>
765 *
766 * <p> The <a name="genWidth">width</a> is the minimum number of characters to
767 * be written to the
768 * output. If the length of the converted value is less than the width then
769 * the output will be padded by <tt>'&nbsp;&nbsp;'</tt> (<tt>&#92;u0020'</tt>)
770 * until the total number of characters equals the width. The padding is on
771 * the left by default. If the <tt>'-'</tt> flag is given, then the padding
772 * will be on the right. If the width is not specified then there is no
773 * minimum.
774 *
775 * <p> The precision is the maximum number of characters to be written to the
776 * output. The precision is applied before the width, thus the output will be
777 * truncated to <tt>precision</tt> characters even if the width is greater than
778 * the precision. If the precision is not specified then there is no explicit
779 * limit on the number of characters.
780 *
781 * <h4><a name="dchar">Character</a></h4>
782 *
783 * This conversion may be applied to <tt>char</tt> and {@link Character}. It
784 * may also be applied to the types <tt>byte</tt>, {@link Byte},
785 * <tt>short</tt>, and {@link Short}, <tt>int</tt> and {@link Integer} when
786 * {@link Character#isValidCodePoint} returns <tt>true</tt>. If it returns
787 * <tt>false</tt> then an {@link IllegalFormatCodePointException} will be
788 * thrown.
789 *
790 * <table cellpadding=5 summary="charConv">
791 *
792 * <tr><td valign="top"> <tt>'c'</tt>
793 * <td valign="top"> <tt>'&#92;u0063'</tt>
794 * <td> Formats the argument as a Unicode character as described in <a
795 * href="../lang/Character.html#unicode">Unicode Character
796 * Representation</a>. This may be more than one 16-bit <tt>char</tt> in
797 * the case where the argument represents a supplementary character.
798 *
799 * <p> If the <tt>'#'</tt> flag is given, then a {@link
800 * FormatFlagsConversionMismatchException} will be thrown.
801 *
802 * <tr><td valign="top"> <tt>'C'</tt>
803 * <td valign="top"> <tt>'&#92;u0043'</tt>
804 * <td> The upper-case variant of <tt>'c'</tt>.
805 *
806 * </table>
807 *
808 * <p> The <tt>'-'</tt> flag defined for <a href="#dFlags">General
809 * conversions</a> applies. If the <tt>'#'</tt> flag is given, then a {@link
810 * FormatFlagsConversionMismatchException} will be thrown.
811 *
812 * <p> The width is defined as for <a href="#genWidth">General conversions</a>.
813 *
814 * <p> The precision is not applicable. If the precision is specified then an
815 * {@link IllegalFormatPrecisionException} will be thrown.
816 *
817 * <h4><a name="dnum">Numeric</a></h4>
818 *
819 * <p> Numeric conversions are divided into the following categories:
820 *
821 * <ol>
822 *
823 * <li> <a href="#dnint"><b>Byte, Short, Integer, and Long</b></a>
824 *
825 * <li> <a href="#dnbint"><b>BigInteger</b></a>
826 *
827 * <li> <a href="#dndec"><b>Float and Double</b></a>
828 *
829 * <li> <a href="#dndec"><b>BigDecimal</b></a>
830 *
831 * </ol>
832 *
833 * <p> Numeric types will be formatted according to the following algorithm:
834 *
835 * <p><b><a name="l10n algorithm"> Number Localization Algorithm</a></b>
836 *
837 * <p> After digits are obtained for the integer part, fractional part, and
838 * exponent (as appropriate for the data type), the following transformation
839 * is applied:
840 *
841 * <ol>
842 *
843 * <li> Each digit character <i>d</i> in the string is replaced by a
844 * locale-specific digit computed relative to the current locale's
845 * {@linkplain java.text.DecimalFormatSymbols#getZeroDigit() zero digit}
846 * <i>z</i>; that is <i>d&nbsp;-&nbsp;</i> <tt>'0'</tt>
847 * <i>&nbsp;+&nbsp;z</i>.
848 *
849 * <li> If a decimal separator is present, a locale-specific {@linkplain
850 * java.text.DecimalFormatSymbols#getDecimalSeparator decimal separator} is
851 * substituted.
852 *
853 * <li> If the <tt>','</tt> (<tt>'&#92;u002c'</tt>)
854 * <a name="l10n group">flag</a> is given, then the locale-specific {@linkplain
855 * java.text.DecimalFormatSymbols#getGroupingSeparator grouping separator} is
856 * inserted by scanning the integer part of the string from least significant
857 * to most significant digits and inserting a separator at intervals defined by
858 * the locale's {@linkplain java.text.DecimalFormat#getGroupingSize() grouping
859 * size}.
860 *
861 * <li> If the <tt>'0'</tt> flag is given, then the locale-specific {@linkplain
862 * java.text.DecimalFormatSymbols#getZeroDigit() zero digits} are inserted
863 * after the sign character, if any, and before the first non-zero digit, until
864 * the length of the string is equal to the requested field width.
865 *
866 * <li> If the value is negative and the <tt>'('</tt> flag is given, then a
867 * <tt>'('</tt> (<tt>'&#92;u0028'</tt>) is prepended and a <tt>')'</tt>
868 * (<tt>'&#92;u0029'</tt>) is appended.
869 *
870 * <li> If the value is negative (or floating-point negative zero) and
871 * <tt>'('</tt> flag is not given, then a <tt>'-'</tt> (<tt>'&#92;u002d'</tt>)
872 * is prepended.
873 *
874 * <li> If the <tt>'+'</tt> flag is given and the value is positive or zero (or
875 * floating-point positive zero), then a <tt>'+'</tt> (<tt>'&#92;u002b'</tt>)
876 * will be prepended.
877 *
878 * </ol>
879 *
880 * <p> If the value is NaN or positive infinity the literal strings "NaN" or
881 * "Infinity" respectively, will be output. If the value is negative infinity,
882 * then the output will be "(Infinity)" if the <tt>'('</tt> flag is given
883 * otherwise the output will be "-Infinity". These values are not localized.
884 *
885 * <p><a name="dnint"><b> Byte, Short, Integer, and Long </b></a>
886 *
887 * <p> The following conversions may be applied to <tt>byte</tt>, {@link Byte},
888 * <tt>short</tt>, {@link Short}, <tt>int</tt> and {@link Integer},
889 * <tt>long</tt>, and {@link Long}.
890 *
891 * <table cellpadding=5 summary="IntConv">
892 *
893 * <tr><td valign="top"> <tt>'d'</tt>
894 * <td valign="top"> <tt>'&#92;u0054'</tt>
895 * <td> Formats the argument as a decimal integer. The <a
896 * href="#l10n algorithm">localization algorithm</a> is applied.
897 *
898 * <p> If the <tt>'0'</tt> flag is given and the value is negative, then
899 * the zero padding will occur after the sign.
900 *
901 * <p> If the <tt>'#'</tt> flag is given then a {@link
902 * FormatFlagsConversionMismatchException} will be thrown.
903 *
904 * <tr><td valign="top"> <tt>'o'</tt>
905 * <td valign="top"> <tt>'&#92;u006f'</tt>
906 * <td> Formats the argument as an integer in base eight. No localization
907 * is applied.
908 *
909 * <p> If <i>x</i> is negative then the result will be an unsigned value
910 * generated by adding 2<sup>n</sup> to the value where <tt>n</tt> is the
911 * number of bits in the type as returned by the static <tt>SIZE</tt> field
912 * in the {@linkplain Byte#SIZE Byte}, {@linkplain Short#SIZE Short},
913 * {@linkplain Integer#SIZE Integer}, or {@linkplain Long#SIZE Long}
914 * classes as appropriate.
915 *
916 * <p> If the <tt>'#'</tt> flag is given then the output will always begin
917 * with the radix indicator <tt>'0'</tt>.
918 *
919 * <p> If the <tt>'0'</tt> flag is given then the output will be padded
920 * with leading zeros to the field width following any indication of sign.
921 *
922 * <p> If <tt>'('</tt>, <tt>'+'</tt>, '&nbsp&nbsp;', or <tt>','</tt> flags
923 * are given then a {@link FormatFlagsConversionMismatchException} will be
924 * thrown.
925 *
926 * <tr><td valign="top"> <tt>'x'</tt>
927 * <td valign="top"> <tt>'&#92;u0078'</tt>
928 * <td> Formats the argument as an integer in base sixteen. No
929 * localization is applied.
930 *
931 * <p> If <i>x</i> is negative then the result will be an unsigned value
932 * generated by adding 2<sup>n</sup> to the value where <tt>n</tt> is the
933 * number of bits in the type as returned by the static <tt>SIZE</tt> field
934 * in the {@linkplain Byte#SIZE Byte}, {@linkplain Short#SIZE Short},
935 * {@linkplain Integer#SIZE Integer}, or {@linkplain Long#SIZE Long}
936 * classes as appropriate.
937 *
938 * <p> If the <tt>'#'</tt> flag is given then the output will always begin
939 * with the radix indicator <tt>"0x"</tt>.
940 *
941 * <p> If the <tt>'0'</tt> flag is given then the output will be padded to
942 * the field width with leading zeros after the radix indicator or sign (if
943 * present).
944 *
945 * <p> If <tt>'('</tt>, <tt>'&nbsp;&nbsp;'</tt>, <tt>'+'</tt>, or
946 * <tt>','</tt> flags are given then a {@link
947 * FormatFlagsConversionMismatchException} will be thrown.
948 *
949 * <tr><td valign="top"> <tt>'X'</tt>
950 * <td valign="top"> <tt>'&#92;u0058'</tt>
951 * <td> The upper-case variant of <tt>'x'</tt>. The entire string
952 * representing the number will be converted to {@linkplain
953 * String#toUpperCase upper case} including the <tt>'x'</tt> (if any) and
954 * all hexadecimal digits <tt>'a'</tt> - <tt>'f'</tt>
955 * (<tt>'&#92;u0061'</tt> - <tt>'&#92;u0066'</tt>).
956 *
957 * </table>
958 *
959 * <p> If the conversion is <tt>'o'</tt>, <tt>'x'</tt>, or <tt>'X'</tt> and
960 * both the <tt>'#'</tt> and the <tt>'0'</tt> flags are given, then result will
961 * contain the radix indicator (<tt>'0'</tt> for octal and <tt>"0x"</tt> or
962 * <tt>"0X"</tt> for hexadecimal), some number of zeros (based on the width),
963 * and the value.
964 *
965 * <p> If the <tt>'-'</tt> flag is not given, then the space padding will occur
966 * before the sign.
967 *
968 * <p> The following <a name="intFlags">flags</a> apply to numeric integral
969 * conversions:
970 *
971 * <table cellpadding=5 summary="intFlags">
972 *
973 * <tr><td valign="top"> <tt>'+'</tt>
974 * <td valign="top"> <tt>'&#92;u002b'</tt>
975 * <td> Requires the output to include a positive sign for all positive
976 * numbers. If this flag is not given then only negative values will
977 * include a sign.
978 *
979 * <p> If both the <tt>'+'</tt> and <tt>'&nbsp;&nbsp;'</tt> flags are given
980 * then an {@link IllegalFormatFlagsException} will be thrown.
981 *
982 * <tr><td valign="top"> <tt>'&nbsp;&nbsp;'</tt>
983 * <td valign="top"> <tt>'&#92;u0020'</tt>
984 * <td> Requires the output to include a single extra space
985 * (<tt>'&#92;u0020'</tt>) for non-negative values.
986 *
987 * <p> If both the <tt>'+'</tt> and <tt>'&nbsp;&nbsp;'</tt> flags are given
988 * then an {@link IllegalFormatFlagsException} will be thrown.
989 *
990 * <tr><td valign="top"> <tt>'0'</tt>
991 * <td valign="top"> <tt>'&#92;u0030'</tt>
992 * <td> Requires the output to be padded with leading {@linkplain
993 * java.text.DecimalFormatSymbols#getZeroDigit zeros} to the minimum field
994 * width following any sign or radix indicator except when converting NaN
995 * or infinity. If the width is not provided, then a {@link
996 * MissingFormatWidthException} will be thrown.
997 *
998 * <p> If both the <tt>'-'</tt> and <tt>'0'</tt> flags are given then an
999 * {@link IllegalFormatFlagsException} will be thrown.
1000 *
1001 * <tr><td valign="top"> <tt>','</tt>
1002 * <td valign="top"> <tt>'&#92;u002c'</tt>
1003 * <td> Requires the output to include the locale-specific {@linkplain
1004 * java.text.DecimalFormatSymbols#getGroupingSeparator group separators} as
1005 * described in the <a href="#l10n group">"group" section</a> of the
1006 * localization algorithm.
1007 *
1008 * <tr><td valign="top"> <tt>'('</tt>
1009 * <td valign="top"> <tt>'&#92;u0028'</tt>
1010 * <td> Requires the output to prepend a <tt>'('</tt>
1011 * (<tt>'&#92;u0028'</tt>) and append a <tt>')'</tt>
1012 * (<tt>'&#92;u0029'</tt>) to negative values.
1013 *
1014 * </table>
1015 *
1016 * <p> If no <a name="intdFlags">flags</a> are given the default formatting is
1017 * as follows:
1018 *
1019 * <ul>
1020 *
1021 * <li> The output is right-justified within the <tt>width</tt>
1022 *
1023 * <li> Negative numbers begin with a <tt>'-'</tt> (<tt>'&#92;u002d'</tt>)
1024 *
1025 * <li> Positive numbers and zero do not include a sign or extra leading
1026 * space
1027 *
1028 * <li> No grouping separators are included
1029 *
1030 * </ul>
1031 *
1032 * <p> The <a name="intWidth">width</a> is the minimum number of characters to
1033 * be written to the output. This includes any signs, digits, grouping
1034 * separators, radix indicator, and parentheses. If the length of the
1035 * converted value is less than the width then the output will be padded by
1036 * spaces (<tt>'&#92;u0020'</tt>) until the total number of characters equals
1037 * width. The padding is on the left by default. If <tt>'-'</tt> flag is
1038 * given then the padding will be on the right. If width is not specified then
1039 * there is no minimum.
1040 *
1041 * <p> The precision is not applicable. If precision is specified then an
1042 * {@link IllegalFormatPrecisionException} will be thrown.
1043 *
1044 * <p><a name="dnbint"><b> BigInteger </b></a>
1045 *
1046 * <p> The following conversions may be applied to {@link
1047 * java.math.BigInteger}.
1048 *
1049 * <table cellpadding=5 summary="BIntConv">
1050 *
1051 * <tr><td valign="top"> <tt>'d'</tt>
1052 * <td valign="top"> <tt>'&#92;u0054'</tt>
1053 * <td> Requires the output to be formatted as a decimal integer. The <a
1054 * href="#l10n algorithm">localization algorithm</a> is applied.
1055 *
1056 * <p> If the <tt>'#'</tt> flag is given {@link
1057 * FormatFlagsConversionMismatchException} will be thrown.
1058 *
1059 * <tr><td valign="top"> <tt>'o'</tt>
1060 * <td valign="top"> <tt>'&#92;u006f'</tt>
1061 * <td> Requires the output to be formatted as an integer in base eight.
1062 * No localization is applied.
1063 *
1064 * <p> If <i>x</i> is negative then the result will be a signed value
1065 * beginning with <tt>'-'</tt> (<tt>'&#92;u002d'</tt>). Signed output is
1066 * allowed for this type because unlike the primitive types it is not
1067 * possible to create an unsigned equivalent without assuming an explicit
1068 * data-type size.
1069 *
1070 * <p> If <i>x</i> is positive or zero and the <tt>'+'</tt> flag is given
1071 * then the result will begin with <tt>'+'</tt> (<tt>'&#92;u002b'</tt>).
1072 *
1073 * <p> If the <tt>'#'</tt> flag is given then the output will always begin
1074 * with <tt>'0'</tt> prefix.
1075 *
1076 * <p> If the <tt>'0'</tt> flag is given then the output will be padded
1077 * with leading zeros to the field width following any indication of sign.
1078 *
1079 * <p> If the <tt>','</tt> flag is given then a {@link
1080 * FormatFlagsConversionMismatchException} will be thrown.
1081 *
1082 * <tr><td valign="top"> <tt>'x'</tt>
1083 * <td valign="top"> <tt>'&#92;u0078'</tt>
1084 * <td> Requires the output to be formatted as an integer in base
1085 * sixteen. No localization is applied.
1086 *
1087 * <p> If <i>x</i> is negative then the result will be a signed value
1088 * beginning with <tt>'-'</tt> (<tt>'&#92;u002d'</tt>). Signed output is
1089 * allowed for this type because unlike the primitive types it is not
1090 * possible to create an unsigned equivalent without assuming an explicit
1091 * data-type size.
1092 *
1093 * <p> If <i>x</i> is positive or zero and the <tt>'+'</tt> flag is given
1094 * then the result will begin with <tt>'+'</tt> (<tt>'&#92;u002b'</tt>).
1095 *
1096 * <p> If the <tt>'#'</tt> flag is given then the output will always begin
1097 * with the radix indicator <tt>"0x"</tt>.
1098 *
1099 * <p> If the <tt>'0'</tt> flag is given then the output will be padded to
1100 * the field width with leading zeros after the radix indicator or sign (if
1101 * present).
1102 *
1103 * <p> If the <tt>','</tt> flag is given then a {@link
1104 * FormatFlagsConversionMismatchException} will be thrown.
1105 *
1106 * <tr><td valign="top"> <tt>'X'</tt>
1107 * <td valign="top"> <tt>'&#92;u0058'</tt>
1108 * <td> The upper-case variant of <tt>'x'</tt>. The entire string
1109 * representing the number will be converted to {@linkplain
1110 * String#toUpperCase upper case} including the <tt>'x'</tt> (if any) and
1111 * all hexadecimal digits <tt>'a'</tt> - <tt>'f'</tt>
1112 * (<tt>'&#92;u0061'</tt> - <tt>'&#92;u0066'</tt>).
1113 *
1114 * </table>
1115 *
1116 * <p> If the conversion is <tt>'o'</tt>, <tt>'x'</tt>, or <tt>'X'</tt> and
1117 * both the <tt>'#'</tt> and the <tt>'0'</tt> flags are given, then result will
1118 * contain the base indicator (<tt>'0'</tt> for octal and <tt>"0x"</tt> or
1119 * <tt>"0X"</tt> for hexadecimal), some number of zeros (based on the width),
1120 * and the value.
1121 *
1122 * <p> If the <tt>'0'</tt> flag is given and the value is negative, then the
1123 * zero padding will occur after the sign.
1124 *
1125 * <p> If the <tt>'-'</tt> flag is not given, then the space padding will occur
1126 * before the sign.
1127 *
1128 * <p> All <a href="#intFlags">flags</a> defined for Byte, Short, Integer, and
1129 * Long apply. The <a href="#intdFlags">default behavior</a> when no flags are
1130 * given is the same as for Byte, Short, Integer, and Long.
1131 *
1132 * <p> The specification of <a href="#intWidth">width</a> is the same as
1133 * defined for Byte, Short, Integer, and Long.
1134 *
1135 * <p> The precision is not applicable. If precision is specified then an
1136 * {@link IllegalFormatPrecisionException} will be thrown.
1137 *
1138 * <p><a name="dndec"><b> Float and Double</b></a>
1139 *
1140 * <p> The following conversions may be applied to <tt>float</tt>, {@link
1141 * Float}, <tt>double</tt> and {@link Double}.
1142 *
1143 * <table cellpadding=5 summary="floatConv">
1144 *
1145 * <tr><td valign="top"> <tt>'e'</tt>
1146 * <td valign="top"> <tt>'&#92;u0065'</tt>
1147 * <td> Requires the output to be formatted using <a
1148 * name="scientific">computerized scientific notation</a>. The <a
1149 * href="#l10n algorithm">localization algorithm</a> is applied.
1150 *
1151 * <p> The formatting of the magnitude <i>m</i> depends upon its value.
1152 *
1153 * <p> If <i>m</i> is NaN or infinite, the literal strings "NaN" or
1154 * "Infinity", respectively, will be output. These values are not
1155 * localized.
1156 *
1157 * <p> If <i>m</i> is positive-zero or negative-zero, then the exponent
1158 * will be <tt>"+00"</tt>.
1159 *
1160 * <p> Otherwise, the result is a string that represents the sign and
1161 * magnitude (absolute value) of the argument. The formatting of the sign
1162 * is described in the <a href="#l10n algorithm">localization
1163 * algorithm</a>. The formatting of the magnitude <i>m</i> depends upon its
1164 * value.
1165 *
1166 * <p> Let <i>n</i> be the unique integer such that 10<sup><i>n</i></sup>
1167 * &lt;= <i>m</i> &lt; 10<sup><i>n</i>+1</sup>; then let <i>a</i> be the
1168 * mathematically exact quotient of <i>m</i> and 10<sup><i>n</i></sup> so
1169 * that 1 &lt;= <i>a</i> &lt; 10. The magnitude is then represented as the
1170 * integer part of <i>a</i>, as a single decimal digit, followed by the
1171 * decimal separator followed by decimal digits representing the fractional
1172 * part of <i>a</i>, followed by the exponent symbol <tt>'e'</tt>
1173 * (<tt>'&#92;u0065'</tt>), followed by the sign of the exponent, followed
1174 * by a representation of <i>n</i> as a decimal integer, as produced by the
1175 * method {@link Long#toString(long, int)}, and zero-padded to include at
1176 * least two digits.
1177 *
1178 * <p> The number of digits in the result for the fractional part of
1179 * <i>m</i> or <i>a</i> is equal to the precision. If the precision is not
1180 * specified then the default value is <tt>6</tt>. If the precision is less
1181 * than the number of digits which would appear after the decimal point in
1182 * the string returned by {@link Float#toString(float)} or {@link
1183 * Double#toString(double)} respectively, then the value will be rounded
1184 * using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
1185 * algorithm}. Otherwise, zeros may be appended to reach the precision.
1186 * For a canonical representation of the value, use {@link
1187 * Float#toString(float)} or {@link Double#toString(double)} as
1188 * appropriate.
1189 *
1190 * <p>If the <tt>','</tt> flag is given, then an {@link
1191 * FormatFlagsConversionMismatchException} will be thrown.
1192 *
1193 * <tr><td valign="top"> <tt>'E'</tt>
1194 * <td valign="top"> <tt>'&#92;u0045'</tt>
1195 * <td> The upper-case variant of <tt>'e'</tt>. The exponent symbol
1196 * will be <tt>'E'</tt> (<tt>'&#92;u0045'</tt>).
1197 *
1198 * <tr><td valign="top"> <tt>'g'</tt>
1199 * <td valign="top"> <tt>'&#92;u0067'</tt>
1200 * <td> Requires the output to be formatted in general scientific notation
1201 * as described below. The <a href="#l10n algorithm">localization
1202 * algorithm</a> is applied.
1203 *
1204 * <p> After rounding for the precision, the formatting of the resulting
1205 * magnitude <i>m</i> depends on its value.
1206 *
1207 * <p> If <i>m</i> is greater than or equal to 10<sup>-4</sup> but less
1208 * than 10<sup>precision</sup> then it is represented in <i><a
1209 * href="#decimal">decimal format</a></i>.
1210 *
1211 * <p> If <i>m</i> is less than 10<sup>-4</sup> or greater than or equal to
1212 * 10<sup>precision</sup>, then it is represented in <i><a
1213 * href="#scientific">computerized scientific notation</a></i>.
1214 *
1215 * <p> The total number of significant digits in <i>m</i> is equal to the
1216 * precision. If the precision is not specified, then the default value is
1217 * <tt>6</tt>. If the precision is <tt>0</tt>, then it is taken to be
1218 * <tt>1</tt>.
1219 *
1220 * <p> If the <tt>'#'</tt> flag is given then an {@link
1221 * FormatFlagsConversionMismatchException} will be thrown.
1222 *
1223 * <tr><td valign="top"> <tt>'G'</tt>
1224 * <td valign="top"> <tt>'&#92;u0047'</tt>
1225 * <td> The upper-case variant of <tt>'g'</tt>.
1226 *
1227 * <tr><td valign="top"> <tt>'f'</tt>
1228 * <td valign="top"> <tt>'&#92;u0066'</tt>
1229 * <td> Requires the output to be formatted using <a name="decimal">decimal
1230 * format</a>. The <a href="#l10n algorithm">localization algorithm</a> is
1231 * applied.
1232 *
1233 * <p> The result is a string that represents the sign and magnitude
1234 * (absolute value) of the argument. The formatting of the sign is
1235 * described in the <a href="#l10n algorithm">localization
1236 * algorithm</a>. The formatting of the magnitude <i>m</i> depends upon its
1237 * value.
1238 *
1239 * <p> If <i>m</i> NaN or infinite, the literal strings "NaN" or
1240 * "Infinity", respectively, will be output. These values are not
1241 * localized.
1242 *
1243 * <p> The magnitude is formatted as the integer part of <i>m</i>, with no
1244 * leading zeroes, followed by the decimal separator followed by one or
1245 * more decimal digits representing the fractional part of <i>m</i>.
1246 *
1247 * <p> The number of digits in the result for the fractional part of
1248 * <i>m</i> or <i>a</i> is equal to the precision. If the precision is not
1249 * specified then the default value is <tt>6</tt>. If the precision is less
1250 * than the number of digits which would appear after the decimal point in
1251 * the string returned by {@link Float#toString(float)} or {@link
1252 * Double#toString(double)} respectively, then the value will be rounded
1253 * using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
1254 * algorithm}. Otherwise, zeros may be appended to reach the precision.
1255 * For a canonical representation of the value,use {@link
1256 * Float#toString(float)} or {@link Double#toString(double)} as
1257 * appropriate.
1258 *
1259 * <tr><td valign="top"> <tt>'a'</tt>
1260 * <td valign="top"> <tt>'&#92;u0061'</tt>
1261 * <td> Requires the output to be formatted in hexadecimal exponential
1262 * form. No localization is applied.
1263 *
1264 * <p> The result is a string that represents the sign and magnitude
1265 * (absolute value) of the argument <i>x</i>.
1266 *
1267 * <p> If <i>x</i> is negative or a negative-zero value then the result
1268 * will begin with <tt>'-'</tt> (<tt>'&#92;u002d'</tt>).
1269 *
1270 * <p> If <i>x</i> is positive or a positive-zero value and the
1271 * <tt>'+'</tt> flag is given then the result will begin with <tt>'+'</tt>
1272 * (<tt>'&#92;u002b'</tt>).
1273 *
1274 * <p> The formatting of the magnitude <i>m</i> depends upon its value.
1275 *
1276 * <ul>
1277 *
1278 * <li> If the value is NaN or infinite, the literal strings "NaN" or
1279 * "Infinity", respectively, will be output.
1280 *
1281 * <li> If <i>m</i> is zero then it is represented by the string
1282 * <tt>"0x0.0p0"</tt>.
1283 *
1284 * <li> If <i>m</i> is a <tt>double</tt> value with a normalized
1285 * representation then substrings are used to represent the significand and
1286 * exponent fields. The significand is represented by the characters
1287 * <tt>"0x1."</tt> followed by the hexadecimal representation of the rest
1288 * of the significand as a fraction. The exponent is represented by
1289 * <tt>'p'</tt> (<tt>'&#92;u0070'</tt>) followed by a decimal string of the
1290 * unbiased exponent as if produced by invoking {@link
1291 * Integer#toString(int) Integer.toString} on the exponent value.
1292 *
1293 * <li> If <i>m</i> is a <tt>double</tt> value with a subnormal
1294 * representation then the significand is represented by the characters
1295 * <tt>'0x0.'</tt> followed by the hexadecimal representation of the rest
1296 * of the significand as a fraction. The exponent is represented by
1297 * <tt>'p-1022'</tt>. Note that there must be at least one nonzero digit
1298 * in a subnormal significand.
1299 *
1300 * </ul>
1301 *
1302 * <p> If the <tt>'('</tt> or <tt>','</tt> flags are given, then a {@link
1303 * FormatFlagsConversionMismatchException} will be thrown.
1304 *
1305 * <tr><td valign="top"> <tt>'A'</tt>
1306 * <td valign="top"> <tt>'&#92;u0041'</tt>
1307 * <td> The upper-case variant of <tt>'a'</tt>. The entire string
1308 * representing the number will be converted to upper case including the
1309 * <tt>'x'</tt> (<tt>'&#92;u0078'</tt>) and <tt>'p'</tt>
1310 * (<tt>'&#92;u0070'</tt> and all hexadecimal digits <tt>'a'</tt> -
1311 * <tt>'f'</tt> (<tt>'&#92;u0061'</tt> - <tt>'&#92;u0066'</tt>).
1312 *
1313 * </table>
1314 *
1315 * <p> All <a href="#intFlags">flags</a> defined for Byte, Short, Integer, and
1316 * Long apply.
1317 *
1318 * <p> If the <tt>'#'</tt> flag is given, then the decimal separator will
1319 * always be present.
1320 *
1321 * <p> If no <a name="floatdFlags">flags</a> are given the default formatting
1322 * is as follows:
1323 *
1324 * <ul>
1325 *
1326 * <li> The output is right-justified within the <tt>width</tt>
1327 *
1328 * <li> Negative numbers begin with a <tt>'-'</tt>
1329 *
1330 * <li> Positive numbers and positive zero do not include a sign or extra
1331 * leading space
1332 *
1333 * <li> No grouping separators are included
1334 *
1335 * <li> The decimal separator will only appear if a digit follows it
1336 *
1337 * </ul>
1338 *
1339 * <p> The <a name="floatDWidth">width</a> is the minimum number of characters
1340 * to be written to the output. This includes any signs, digits, grouping
1341 * separators, decimal separators, exponential symbol, radix indicator,
1342 * parentheses, and strings representing infinity and NaN as applicable. If
1343 * the length of the converted value is less than the width then the output
1344 * will be padded by spaces (<tt>'&#92;u0020'</tt>) until the total number of
1345 * characters equals width. The padding is on the left by default. If the
1346 * <tt>'-'</tt> flag is given then the padding will be on the right. If width
1347 * is not specified then there is no minimum.
1348 *
1349 * <p> If the <a name="floatDPrec">conversion</a> is <tt>'e'</tt>,
1350 * <tt>'E'</tt> or <tt>'f'</tt>, then the precision is the number of digits
1351 * after the decimal separator. If the precision is not specified, then it is
1352 * assumed to be <tt>6</tt>.
1353 *
1354 * <p> If the conversion is <tt>'g'</tt> or <tt>'G'</tt>, then the precision is
1355 * the total number of significant digits in the resulting magnitude after
1356 * rounding. If the precision is not specified, then the default value is
1357 * <tt>6</tt>. If the precision is <tt>0</tt>, then it is taken to be
1358 * <tt>1</tt>.
1359 *
1360 * <p> If the conversion is <tt>'a'</tt> or <tt>'A'</tt>, then the precision
1361 * is the number of hexadecimal digits after the decimal separator. If the
1362 * precision is not provided, then all of the digits as returned by {@link
1363 * Double#toHexString(double)} will be output.
1364 *
1365 * <p><a name="dndec"><b> BigDecimal </b></a>
1366 *
1367 * <p> The following conversions may be applied {@link java.math.BigDecimal
1368 * BigDecimal}.
1369 *
1370 * <table cellpadding=5 summary="floatConv">
1371 *
1372 * <tr><td valign="top"> <tt>'e'</tt>
1373 * <td valign="top"> <tt>'&#92;u0065'</tt>
1374 * <td> Requires the output to be formatted using <a
1375 * name="scientific">computerized scientific notation</a>. The <a
1376 * href="#l10n algorithm">localization algorithm</a> is applied.
1377 *
1378 * <p> The formatting of the magnitude <i>m</i> depends upon its value.
1379 *
1380 * <p> If <i>m</i> is positive-zero or negative-zero, then the exponent
1381 * will be <tt>"+00"</tt>.
1382 *
1383 * <p> Otherwise, the result is a string that represents the sign and
1384 * magnitude (absolute value) of the argument. The formatting of the sign
1385 * is described in the <a href="#l10n algorithm">localization
1386 * algorithm</a>. The formatting of the magnitude <i>m</i> depends upon its
1387 * value.
1388 *
1389 * <p> Let <i>n</i> be the unique integer such that 10<sup><i>n</i></sup>
1390 * &lt;= <i>m</i> &lt; 10<sup><i>n</i>+1</sup>; then let <i>a</i> be the
1391 * mathematically exact quotient of <i>m</i> and 10<sup><i>n</i></sup> so
1392 * that 1 &lt;= <i>a</i> &lt; 10. The magnitude is then represented as the
1393 * integer part of <i>a</i>, as a single decimal digit, followed by the
1394 * decimal separator followed by decimal digits representing the fractional
1395 * part of <i>a</i>, followed by the exponent symbol <tt>'e'</tt>
1396 * (<tt>'&#92;u0065'</tt>), followed by the sign of the exponent, followed
1397 * by a representation of <i>n</i> as a decimal integer, as produced by the
1398 * method {@link Long#toString(long, int)}, and zero-padded to include at
1399 * least two digits.
1400 *
1401 * <p> The number of digits in the result for the fractional part of
1402 * <i>m</i> or <i>a</i> is equal to the precision. If the precision is not
1403 * specified then the default value is <tt>6</tt>. If the precision is
1404 * less than the number of digits which would appear after the decimal
1405 * point in the string returned by {@link Float#toString(float)} or {@link
1406 * Double#toString(double)} respectively, then the value will be rounded
1407 * using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
1408 * algorithm}. Otherwise, zeros may be appended to reach the precision.
1409 * For a canonical representation of the value, use {@link
1410 * BigDecimal#toString()}.
1411 *
1412 * <p> If the <tt>','</tt> flag is given, then an {@link
1413 * FormatFlagsConversionMismatchException} will be thrown.
1414 *
1415 * <tr><td valign="top"> <tt>'E'</tt>
1416 * <td valign="top"> <tt>'&#92;u0045'</tt>
1417 * <td> The upper-case variant of <tt>'e'</tt>. The exponent symbol
1418 * will be <tt>'E'</tt> (<tt>'&#92;u0045'</tt>).
1419 *
1420 * <tr><td valign="top"> <tt>'g'</tt>
1421 * <td valign="top"> <tt>'&#92;u0067'</tt>
1422 * <td> Requires the output to be formatted in general scientific notation
1423 * as described below. The <a href="#l10n algorithm">localization
1424 * algorithm</a> is applied.
1425 *
1426 * <p> After rounding for the precision, the formatting of the resulting
1427 * magnitude <i>m</i> depends on its value.
1428 *
1429 * <p> If <i>m</i> is greater than or equal to 10<sup>-4</sup> but less
1430 * than 10<sup>precision</sup> then it is represented in <i><a
1431 * href="#decimal">decimal format</a></i>.
1432 *
1433 * <p> If <i>m</i> is less than 10<sup>-4</sup> or greater than or equal to
1434 * 10<sup>precision</sup>, then it is represented in <i><a
1435 * href="#scientific">computerized scientific notation</a></i>.
1436 *
1437 * <p> The total number of significant digits in <i>m</i> is equal to the
1438 * precision. If the precision is not specified, then the default value is
1439 * <tt>6</tt>. If the precision is <tt>0</tt>, then it is taken to be
1440 * <tt>1</tt>.
1441 *
1442 * <p> If the <tt>'#'</tt> flag is given then an {@link
1443 * FormatFlagsConversionMismatchException} will be thrown.
1444 *
1445 * <tr><td valign="top"> <tt>'G'</tt>
1446 * <td valign="top"> <tt>'&#92;u0047'</tt>
1447 * <td> The upper-case variant of <tt>'g'</tt>.
1448 *
1449 * <tr><td valign="top"> <tt>'f'</tt>
1450 * <td valign="top"> <tt>'&#92;u0066'</tt>
1451 * <td> Requires the output to be formatted using <a name="decimal">decimal
1452 * format</a>. The <a href="#l10n algorithm">localization algorithm</a> is
1453 * applied.
1454 *
1455 * <p> The result is a string that represents the sign and magnitude
1456 * (absolute value) of the argument. The formatting of the sign is
1457 * described in the <a href="#l10n algorithm">localization
1458 * algorithm</a>. The formatting of the magnitude <i>m</i> depends upon its
1459 * value.
1460 *
1461 * <p> The magnitude is formatted as the integer part of <i>m</i>, with no
1462 * leading zeroes, followed by the decimal separator followed by one or
1463 * more decimal digits representing the fractional part of <i>m</i>.
1464 *
1465 * <p> The number of digits in the result for the fractional part of
1466 * <i>m</i> or <i>a</i> is equal to the precision. If the precision is not
1467 * specified then the default value is <tt>6</tt>. If the precision is
1468 * less than the number of digits which would appear after the decimal
1469 * point in the string returned by {@link Float#toString(float)} or {@link
1470 * Double#toString(double)} respectively, then the value will be rounded
1471 * using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
1472 * algorithm}. Otherwise, zeros may be appended to reach the precision.
1473 * For a canonical representation of the value, use {@link
1474 * BigDecimal#toString()}.
1475 *
1476 * </table>
1477 *
1478 * <p> All <a href="#intFlags">flags</a> defined for Byte, Short, Integer, and
1479 * Long apply.
1480 *
1481 * <p> If the <tt>'#'</tt> flag is given, then the decimal separator will
1482 * always be present.
1483 *
1484 * <p> The <a href="#floatdFlags">default behavior</a> when no flags are
1485 * given is the same as for Float and Double.
1486 *
1487 * <p> The specification of <a href="#floatDWidth">width</a> and <a
1488 * href="#floatDPrec">precision</a> is the same as defined for Float and
1489 * Double.
1490 *
1491 * <h4><a name="ddt">Date/Time</a></h4>
1492 *
1493 * <p> This conversion may be applied to <tt>long</tt>, {@link Long}, {@link
1494 * Calendar}, and {@link Date}.
1495 *
1496 * <table cellpadding=5 summary="DTConv">
1497 *
1498 * <tr><td valign="top"> <tt>'t'</tt>
1499 * <td valign="top"> <tt>'&#92;u0074'</tt>
1500 * <td> Prefix for date and time conversion characters.
1501 * <tr><td valign="top"> <tt>'T'</tt>
1502 * <td valign="top"> <tt>'&#92;u0054'</tt>
1503 * <td> The upper-case variant of <tt>'t'</tt>.
1504 *
1505 * </table>
1506 *
1507 * <p> The following date and time conversion character suffixes are defined
1508 * for the <tt>'t'</tt> and <tt>'T'</tt> conversions. The types are similar to
1509 * but not completely identical to those defined by GNU <tt>date</tt> and
1510 * POSIX <tt>strftime(3c)</tt>. Additional conversion types are provided to
1511 * access Java-specific functionality (e.g. <tt>'L'</tt> for milliseconds
1512 * within the second).
1513 *
1514 * <p> The following conversion characters are used for formatting times:
1515 *
1516 * <table cellpadding=5 summary="time">
1517 *
1518 * <tr><td valign="top"> <tt>'H'</tt>
1519 * <td valign="top"> <tt>'&#92;u0048'</tt>
1520 * <td> Hour of the day for the 24-hour clock, formatted as two digits with
1521 * a leading zero as necessary i.e. <tt>00 - 23</tt>. <tt>00</tt>
1522 * corresponds to midnight.
1523 *
1524 * <tr><td valign="top"><tt>'I'</tt>
1525 * <td valign="top"> <tt>'&#92;u0049'</tt>
1526 * <td> Hour for the 12-hour clock, formatted as two digits with a leading
1527 * zero as necessary, i.e. <tt>01 - 12</tt>. <tt>01</tt> corresponds to
1528 * one o'clock (either morning or afternoon).
1529 *
1530 * <tr><td valign="top"><tt>'k'</tt>
1531 * <td valign="top"> <tt>'&#92;u006b'</tt>
1532 * <td> Hour of the day for the 24-hour clock, i.e. <tt>0 - 23</tt>.
1533 * <tt>0</tt> corresponds to midnight.
1534 *
1535 * <tr><td valign="top"><tt>'l'</tt>
1536 * <td valign="top"> <tt>'&#92;u006c'</tt>
1537 * <td> Hour for the 12-hour clock, i.e. <tt>1 - 12</tt>. <tt>1</tt>
1538 * corresponds to one o'clock (either morning or afternoon).
1539 *
1540 * <tr><td valign="top"><tt>'M'</tt>
1541 * <td valign="top"> <tt>'&#92;u004d'</tt>
1542 * <td> Minute within the hour formatted as two digits with a leading zero
1543 * as necessary, i.e. <tt>00 - 59</tt>.
1544 *
1545 * <tr><td valign="top"><tt>'S'</tt>
1546 * <td valign="top"> <tt>'&#92;u0053'</tt>
1547 * <td> Seconds within the minute, formatted as two digits with a leading
1548 * zero as necessary, i.e. <tt>00 - 60</tt> ("<tt>60</tt>" is a special
1549 * value required to support leap seconds).
1550 *
1551 * <tr><td valign="top"><tt>'L'</tt>
1552 * <td valign="top"> <tt>'&#92;u004c'</tt>
1553 * <td> Millisecond within the second formatted as three digits with
1554 * leading zeros as necessary, i.e. <tt>000 - 999</tt>.
1555 *
1556 * <tr><td valign="top"><tt>'N'</tt>
1557 * <td valign="top"> <tt>'&#92;u004e'</tt>
1558 * <td> Nanosecond within the second, formatted as nine digits with leading
1559 * zeros as necessary, i.e. <tt>000000000 - 999999999</tt>. The precision
1560 * of this value is limited by the resolution of the underlying operating
1561 * system or hardware.
1562 *
1563 * <tr><td valign="top"><tt>'p'</tt>
1564 * <td valign="top"> <tt>'&#92;u0070'</tt>
1565 * <td> Locale-specific {@linkplain
1566 * java.text.DateFormatSymbols#getAmPmStrings morning or afternoon} marker
1567 * in lower case, e.g."<tt>am</tt>" or "<tt>pm</tt>". Use of the
1568 * conversion prefix <tt>'T'</tt> forces this output to upper case. (Note
1569 * that <tt>'p'</tt> produces lower-case output. This is different from
1570 * GNU <tt>date</tt> and POSIX <tt>strftime(3c)</tt> which produce
1571 * upper-case output.)
1572 *
1573 * <tr><td valign="top"><tt>'z'</tt>
1574 * <td valign="top"> <tt>'&#92;u007a'</tt>
1575 * <td> <a href="http://www.ietf.org/rfc/rfc0822.txt">RFC&nbsp;822</a>
1576 * style numeric time zone offset from GMT, e.g. <tt>-0800</tt>. This
1577 * value will be adjusted as necessary for Daylight Saving Time. For
1578 * <tt>long</tt>, {@link Long}, and {@link Date} the time zone used is
1579 * the {@plainlink TimeZone#getDefault() default time zone} for this
1580 * instance of the Java virtual machine.
1581 *
1582 * <tr><td valign="top"><tt>'Z'</tt>
1583 * <td> A string representing the abbreviation for the time zone. This
1584 * value will be adjusted as necessary for Daylight Saving Time. For
1585 * <tt>long</tt>, {@link Long}, and {@link Date} the time zone used is
1586 * the {@plainlink TimeZone#getDefault() default time zone} for this
1587 * instance of the Java virtual machine. The Formatter's locale will
1588 * supersede the locale of the argument (if any).
1589 *
1590 * <tr><td valign="top"><tt>'s'</tt>
1591 * <td valign="top"> <tt>'&#92;u0073'</tt>
1592 * <td> Seconds since the beginning of the epoch starting at 1 January 1970
1593 * <tt>00:00:00</tt> UTC, i.e. <tt>Long.MIN_VALUE/1000</tt> to
1594 * <tt>Long.MAX_VALUE/1000</tt>.
1595 *
1596 * <tr><td valign="top"><tt>'Q'</tt>
1597 * <td valign="top"> <tt>'&#92;u004f'</tt>
1598 * <td> Milliseconds since the beginning of the epoch starting at 1 January
1599 * 1970 <tt>00:00:00</tt> UTC, i.e. <tt>Long.MIN_VALUE</tt> to
1600 * <tt>Long.MAX_VALUE</tt>. The precision of this value is limited by
1601 * the resolution of the underlying operating system or hardware.
1602 *
1603 * </table>
1604 *
1605 * <p> The following conversion characters are used for formatting dates:
1606 *
1607 * <table cellpadding=5 summary="date">
1608 *
1609 * <tr><td valign="top"><tt>'B'</tt>
1610 * <td valign="top"> <tt>'&#92;u0042'</tt>
1611 * <td> Locale-specific {@linkplain java.text.DateFormatSymbols#getMonths
1612 * full month name}, e.g. <tt>"January"</tt>, <tt>"February"</tt>.
1613 *
1614 * <tr><td valign="top"><tt>'b'</tt>
1615 * <td valign="top"> <tt>'&#92;u0062'</tt>
1616 * <td> Locale-specific {@linkplain
1617 * java.text.DateFormatSymbols#getShortMonths abbreviated month name},
1618 * e.g. <tt>"Jan"</tt>, <tt>"Feb"</tt>.
1619 *
1620 * <tr><td valign="top"><tt>'h'</tt>
1621 * <td valign="top"> <tt>'&#92;u0068'</tt>
1622 * <td> Same as <tt>'b'</tt>.
1623 *
1624 * <tr><td valign="top"><tt>'A'</tt>
1625 * <td valign="top"> <tt>'&#92;u0041'</tt>
1626 * <td> Locale-specific full name of the {@linkplain
1627 * java.text.DateFormatSymbols#getWeekdays day of the week},
1628 * e.g. <tt>"Sunday"</tt>, <tt>"Monday"</tt>
1629 *
1630 * <tr><td valign="top"><tt>'a'</tt>
1631 * <td valign="top"> <tt>'&#92;u0061'</tt>
1632 * <td> Locale-specific short name of the {@linkplain
1633 * java.text.DateFormatSymbols#getShortWeekdays day of the week},
1634 * e.g. <tt>"Sun"</tt>, <tt>"Mon"</tt>
1635 *
1636 * <tr><td valign="top"><tt>'C'</tt>
1637 * <td valign="top"> <tt>'&#92;u0043'</tt>
1638 * <td> Four-digit year divided by <tt>100</tt>, formatted as two digits
1639 * with leading zero as necessary, i.e. <tt>00 - 99</tt>
1640 *
1641 * <tr><td valign="top"><tt>'Y'</tt>
1642 * <td valign="top"> <tt>'&#92;u0059'</tt> <td> Year, formatted to at least
1643 * four digits with leading zeros as necessary, e.g. <tt>0092</tt> equals
1644 * <tt>92</tt> CE for the Gregorian calendar.
1645 *
1646 * <tr><td valign="top"><tt>'y'</tt>
1647 * <td valign="top"> <tt>'&#92;u0079'</tt>
1648 * <td> Last two digits of the year, formatted with leading zeros as
1649 * necessary, i.e. <tt>00 - 99</tt>.
1650 *
1651 * <tr><td valign="top"><tt>'j'</tt>
1652 * <td valign="top"> <tt>'&#92;u006a'</tt>
1653 * <td> Day of year, formatted as three digits with leading zeros as
1654 * necessary, e.g. <tt>001 - 366</tt> for the Gregorian calendar.
1655 * <tt>001</tt> corresponds to the first day of the year.
1656 *
1657 * <tr><td valign="top"><tt>'m'</tt>
1658 * <td valign="top"> <tt>'&#92;u006d'</tt>
1659 * <td> Month, formatted as two digits with leading zeros as necessary,
1660 * i.e. <tt>01 - 13</tt>, where "<tt>01</tt>" is the first month of the
1661 * year and ("<tt>13</tt>" is a special value required to support lunar
1662 * calendars).
1663 *
1664 * <tr><td valign="top"><tt>'d'</tt>
1665 * <td valign="top"> <tt>'&#92;u0064'</tt>
1666 * <td> Day of month, formatted as two digits with leading zeros as
1667 * necessary, i.e. <tt>01 - 31</tt>, where "<tt>01</tt>" is the first day
1668 * of the month.
1669 *
1670 * <tr><td valign="top"><tt>'e'</tt>
1671 * <td valign="top"> <tt>'&#92;u0065'</tt>
1672 * <td> Day of month, formatted as two digits, i.e. <tt>1 - 31</tt> where
1673 * "<tt>1</tt>" is the first day of the month.
1674 *
1675 * </table>
1676 *
1677 * <p> The following conversion characters are used for formatting common
1678 * date/time compositions.
1679 *
1680 * <table cellpadding=5 summary="composites">
1681 *
1682 * <tr><td valign="top"><tt>'R'</tt>
1683 * <td valign="top"> <tt>'&#92;u0052'</tt>
1684 * <td> Time formatted for the 24-hour clock as <tt>"%tH:%tM"</tt>
1685 *
1686 * <tr><td valign="top"><tt>'T'</tt>
1687 * <td valign="top"> <tt>'&#92;u0054'</tt>
1688 * <td> Time formatted for the 24-hour clock as <tt>"%tH:%tM:%tS"</tt>.
1689 *
1690 * <tr><td valign="top"><tt>'r'</tt>
1691 * <td valign="top"> <tt>'&#92;u0072'</tt>
1692 * <td> Time formatted for the 12-hour clock as <tt>"%tI:%tM:%tS
1693 * %Tp"</tt>. The location of the morning or afternoon marker
1694 * (<tt>'%Tp'</tt>) may be locale-dependent.
1695 *
1696 * <tr><td valign="top"><tt>'D'</tt>
1697 * <td valign="top"> <tt>'&#92;u0044'</tt>
1698 * <td> Date formatted as <tt>"%tm/%td/%ty"</tt>.
1699 *
1700 * <tr><td valign="top"><tt>'F'</tt>
1701 * <td valign="top"> <tt>'&#92;u0046'</tt>
1702 * <td> <a href="http://www.w3.org/TR/NOTE-datetime">ISO&nbsp;8601</a>
1703 * complete date formatted as <tt>"%tY-%tm-%td"</tt>.
1704 *
1705 * <tr><td valign="top"><tt>'c'</tt>
1706 * <td valign="top"> <tt>'&#92;u0063'</tt>
1707 * <td> Date and time formatted as <tt>"%ta %tb %td %tT %tZ %tY"</tt>,
1708 * e.g. <tt>"Sun Jul 20 16:17:00 EDT 1969"</tt>.
1709 *
1710 * </table>
1711 *
1712 * <p> The <tt>'-'</tt> flag defined for <a href="#dFlags">General
1713 * conversions</a> applies. If the <tt>'#'</tt> flag is given, then a {@link
1714 * FormatFlagsConversionMismatchException} will be thrown.
1715 *
1716 * <p> The <a name="dtWidth">width</a> is the minimum number of characters to
1717 * be written to the output. If the length of the converted value is less than
1718 * the <tt>width</tt> then the output will be padded by spaces
1719 * (<tt>'&#92;u0020'</tt>) until the total number of characters equals width.
1720 * The padding is on the left by default. If the <tt>'-'</tt> flag is given
1721 * then the padding will be on the right. If width is not specified then there
1722 * is no minimum.
1723 *
1724 * <p> The precision is not applicable. If the precision is specified then an
1725 * {@link IllegalFormatPrecisionException} will be thrown.
1726 *
1727 * <h4><a name="dper">Percent</a></h4>
1728 *
1729 * <p> The conversion does not correspond to any argument.
1730 *
1731 * <table cellpadding=5 summary="DTConv">
1732 *
1733 * <tr><td valign="top"><tt>'%'</tt>
1734 * <td> The result is a literal <tt>'%'</tt> (<tt>'&#92;u0025'</tt>)
1735 *
1736 * <p> The <a name="dtWidth">width</a> is the minimum number of characters to
1737 * be written to the output including the <tt>'%'</tt>. If the length of the
1738 * converted value is less than the <tt>width</tt> then the output will be
1739 * padded by spaces (<tt>'&#92;u0020'</tt>) until the total number of
1740 * characters equals width. The padding is on the left. If width is not
1741 * specified then just the <tt>'%'</tt> is output.
1742 *
1743 * <p> The <tt>'-'</tt> flag defined for <a href="#dFlags">General
1744 * conversions</a> applies. If any other flags are provided, then a
1745 * {@link FormatFlagsConversionMismatchException} will be thrown.
1746 *
1747 * <p> The precision is not applicable. If the precision is specified an
1748 * {@link IllegalFormatPrecisionException} will be thrown.
1749 *
1750 * </table>
1751 *
1752 * <h4><a name="dls">Line Separator</a></h4>
1753 *
1754 * <p> The conversion does not correspond to any argument.
1755 *
1756 * <table cellpadding=5 summary="DTConv">
1757 *
1758 * <tr><td valign="top"><tt>'n'</tt>
1759 * <td> the platform-specific line separator as returned by {@link
1760 * System#getProperty System.getProperty("line.separator")}.
1761 *
1762 * </table>
1763 *
1764 * <p> Flags, width, and precision are not applicable. If any are provided an
1765 * {@link IllegalFormatFlagsException}, {@link IllegalFormatWidthException},
1766 * and {@link IllegalFormatPrecisionException}, respectively will be thrown.
1767 *
1768 * <h4><a name="dpos">Argument Index</a></h4>
1769 *
1770 * <p> Format specifiers can reference arguments in three ways:
1771 *
1772 * <ul>
1773 *
1774 * <li> <i>Explicit indexing</i> is used when the format specifier contains an
1775 * argument index. The argument index is a decimal integer indicating the
1776 * position of the argument in the argument list. The first argument is
1777 * referenced by "<tt>1$</tt>", the second by "<tt>2$</tt>", etc. An argument
1778 * may be referenced more than once.
1779 *
1780 * <p> For example:
1781 *
1782 * <blockquote><pre>
1783 * formatter.format("%4$s %3$s %2$s %1$s %4$s %3$s %2$s %1$s",
1784 * "a", "b", "c", "d")
1785 * // -&gt; "d c b a d c b a"
1786 * </pre></blockquote>
1787 *
1788 * <li> <i>Relative indexing</i> is used when the format specifier contains a
1789 * <tt>'&lt;'</tt> (<tt>'&#92;u003c'</tt>) flag which causes the argument for
1790 * the previous format specifier to be re-used. If there is no previous
1791 * argument, then a {@link MissingFormatArgumentException} is thrown.
1792 *
1793 * <blockquote><pre>
1794 * formatter.format("%s %s %&lt;s %&lt;s", "a", "b", "c", "d")
1795 * // -&gt; "a b b b"
1796 * // "c" and "d" are ignored because they are not referenced
1797 * </pre></blockquote>
1798 *
1799 * <li> <i>Ordinary indexing</i> is used when the format specifier contains
1800 * neither an argument index nor a <tt>'&lt;'</tt> flag. Each format specifier
1801 * which uses ordinary indexing is assigned a sequential implicit index into
1802 * argument list which is independent of the indices used by explicit or
1803 * relative indexing.
1804 *
1805 * <blockquote><pre>
1806 * formatter.format("%s %s %s %s", "a", "b", "c", "d")
1807 * // -&gt; "a b c d"
1808 * </pre></blockquote>
1809 *
1810 * </ul>
1811 *
1812 * <p> It is possible to have a format string which uses all forms of indexing,
1813 * for example:
1814 *
1815 * <blockquote><pre>
1816 * formatter.format("%2$s %s %&lt;s %s", "a", "b", "c", "d")
1817 * // -&gt; "b a a b"
1818 * // "c" and "d" are ignored because they are not referenced
1819 * </pre></blockquote>
1820 *
1821 * <p> The maximum number of arguments is limited by the maximum dimension of a
1822 * Java array as defined by the <a
1823 * href="http://java.sun.com/docs/books/vmspec/">Java Virtual Machine
1824 * Specification</a>. If the argument index is does not correspond to an
1825 * available argument, then a {@link MissingFormatArgumentException} is thrown.
1826 *
1827 * <p> If there are more arguments than format specifiers, the extra arguments
1828 * are ignored.
1829 *
1830 * <p> Unless otherwise specified, passing a <tt>null</tt> argument to any
1831 * method or constructor in this class will cause a {@link
1832 * NullPointerException} to be thrown.
1833 *
1834 * @author Iris Clark
1835 * @since 1.5
1836 */
1837public final class Formatter implements Closeable, Flushable {
1838 private Appendable a;
1839 private Locale l;
1840
1841 private IOException lastException;
1842
1843 private char zero = '0';
1844 private static double scaleUp;
1845
1846 // 1 (sign) + 19 (max # sig digits) + 1 ('.') + 1 ('e') + 1 (sign)
1847 // + 3 (max # exp digits) + 4 (error) = 30
1848 private static final int MAX_FD_CHARS = 30;
1849
1850 // Initialize internal data.
1851 private void init(Appendable a, Locale l) {
1852 this.a = a;
1853 this.l = l;
1854 setZero();
1855 }
1856
1857 /**
1858 * Constructs a new formatter.
1859 *
1860 * <p> The destination of the formatted output is a {@link StringBuilder}
1861 * which may be retrieved by invoking {@link #out out()} and whose
1862 * current content may be converted into a string by invoking {@link
1863 * #toString toString()}. The locale used is the {@linkplain
1864 * Locale#getDefault() default locale} for this instance of the Java
1865 * virtual machine.
1866 */
1867 public Formatter() {
1868 init(new StringBuilder(), Locale.getDefault());
1869 }
1870
1871 /**
1872 * Constructs a new formatter with the specified destination.
1873 *
1874 * <p> The locale used is the {@linkplain Locale#getDefault() default
1875 * locale} for this instance of the Java virtual machine.
1876 *
1877 * @param a
1878 * Destination for the formatted output. If <tt>a</tt> is
1879 * <tt>null</tt> then a {@link StringBuilder} will be created.
1880 */
1881 public Formatter(Appendable a) {
1882 if (a == null)
1883 a = new StringBuilder();
1884 init(a, Locale.getDefault());
1885 }
1886
1887 /**
1888 * Constructs a new formatter with the specified locale.
1889 *
1890 * <p> The destination of the formatted output is a {@link StringBuilder}
1891 * which may be retrieved by invoking {@link #out out()} and whose current
1892 * content may be converted into a string by invoking {@link #toString
1893 * toString()}.
1894 *
1895 * @param l
1896 * The {@linkplain java.util.Locale locale} to apply during
1897 * formatting. If <tt>l</tt> is <tt>null</tt> then no localization
1898 * is applied.
1899 */
1900 public Formatter(Locale l) {
1901 init(new StringBuilder(), l);
1902 }
1903
1904 /**
1905 * Constructs a new formatter with the specified destination and locale.
1906 *
1907 * @param a
1908 * Destination for the formatted output. If <tt>a</tt> is
1909 * <tt>null</tt> then a {@link StringBuilder} will be created.
1910 *
1911 * @param l
1912 * The {@linkplain java.util.Locale locale} to apply during
1913 * formatting. If <tt>l</tt> is <tt>null</tt> then no localization
1914 * is applied.
1915 */
1916 public Formatter(Appendable a, Locale l) {
1917 if (a == null)
1918 a = new StringBuilder();
1919 init(a, l);
1920 }
1921
1922 /**
1923 * Constructs a new formatter with the specified file name.
1924 *
1925 * <p> The charset used is the {@linkplain
1926 * java.nio.charset.Charset#defaultCharset() default charset} for this
1927 * instance of the Java virtual machine.
1928 *
1929 * <p> The locale used is the {@linkplain Locale#getDefault() default
1930 * locale} for this instance of the Java virtual machine.
1931 *
1932 * @param fileName
1933 * The name of the file to use as the destination of this
1934 * formatter. If the file exists then it will be truncated to
1935 * zero size; otherwise, a new file will be created. The output
1936 * will be written to the file and is buffered.
1937 *
1938 * @throws SecurityException
1939 * If a security manager is present and {@link
1940 * SecurityManager#checkWrite checkWrite(fileName)} denies write
1941 * access to the file
1942 *
1943 * @throws FileNotFoundException
1944 * If the given file name does not denote an existing, writable
1945 * regular file and a new regular file of that name cannot be
1946 * created, or if some other error occurs while opening or
1947 * creating the file
1948 */
1949 public Formatter(String fileName) throws FileNotFoundException {
1950 init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))),
1951 Locale.getDefault());
1952 }
1953
1954 /**
1955 * Constructs a new formatter with the specified file name and charset.
1956 *
1957 * <p> The locale used is the {@linkplain Locale#getDefault default
1958 * locale} for this instance of the Java virtual machine.
1959 *
1960 * @param fileName
1961 * The name of the file to use as the destination of this
1962 * formatter. If the file exists then it will be truncated to
1963 * zero size; otherwise, a new file will be created. The output
1964 * will be written to the file and is buffered.
1965 *
1966 * @param csn
1967 * The name of a supported {@linkplain java.nio.charset.Charset
1968 * charset}
1969 *
1970 * @throws FileNotFoundException
1971 * If the given file name does not denote an existing, writable
1972 * regular file and a new regular file of that name cannot be
1973 * created, or if some other error occurs while opening or
1974 * creating the file
1975 *
1976 * @throws SecurityException
1977 * If a security manager is present and {@link
1978 * SecurityManager#checkWrite checkWrite(fileName)} denies write
1979 * access to the file
1980 *
1981 * @throws UnsupportedEncodingException
1982 * If the named charset is not supported
1983 */
1984 public Formatter(String fileName, String csn)
1985 throws FileNotFoundException, UnsupportedEncodingException
1986 {
1987 this(fileName, csn, Locale.getDefault());
1988 }
1989
1990 /**
1991 * Constructs a new formatter with the specified file name, charset, and
1992 * locale.
1993 *
1994 * @param fileName
1995 * The name of the file to use as the destination of this
1996 * formatter. If the file exists then it will be truncated to
1997 * zero size; otherwise, a new file will be created. The output
1998 * will be written to the file and is buffered.
1999 *
2000 * @param csn
2001 * The name of a supported {@linkplain java.nio.charset.Charset
2002 * charset}
2003 *
2004 * @param l
2005 * The {@linkplain java.util.Locale locale} to apply during
2006 * formatting. If <tt>l</tt> is <tt>null</tt> then no localization
2007 * is applied.
2008 *
2009 * @throws FileNotFoundException
2010 * If the given file name does not denote an existing, writable
2011 * regular file and a new regular file of that name cannot be
2012 * created, or if some other error occurs while opening or
2013 * creating the file
2014 *
2015 * @throws SecurityException
2016 * If a security manager is present and {@link
2017 * SecurityManager#checkWrite checkWrite(fileName)} denies write
2018 * access to the file
2019 *
2020 * @throws UnsupportedEncodingException
2021 * If the named charset is not supported
2022 */
2023 public Formatter(String fileName, String csn, Locale l)
2024 throws FileNotFoundException, UnsupportedEncodingException
2025 {
2026 init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName), csn)),
2027 l);
2028 }
2029
2030 /**
2031 * Constructs a new formatter with the specified file.
2032 *
2033 * <p> The charset used is the {@linkplain
2034 * java.nio.charset.Charset#defaultCharset() default charset} for this
2035 * instance of the Java virtual machine.
2036 *
2037 * <p> The locale used is the {@linkplain Locale#getDefault() default
2038 * locale} for this instance of the Java virtual machine.
2039 *
2040 * @param file
2041 * The file to use as the destination of this formatter. If the
2042 * file exists then it will be truncated to zero size; otherwise,
2043 * a new file will be created. The output will be written to the
2044 * file and is buffered.
2045 *
2046 * @throws SecurityException
2047 * If a security manager is present and {@link
2048 * SecurityManager#checkWrite checkWrite(file.getPath())} denies
2049 * write access to the file
2050 *
2051 * @throws FileNotFoundException
2052 * If the given file object does not denote an existing, writable
2053 * regular file and a new regular file of that name cannot be
2054 * created, or if some other error occurs while opening or
2055 * creating the file
2056 */
2057 public Formatter(File file) throws FileNotFoundException {
2058 init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))),
2059 Locale.getDefault());
2060 }
2061
2062 /**
2063 * Constructs a new formatter with the specified file and charset.
2064 *
2065 * <p> The locale used is the {@linkplain Locale#getDefault default
2066 * locale} for this instance of the Java virtual machine.
2067 *
2068 * @param file
2069 * The file to use as the destination of this formatter. If the
2070 * file exists then it will be truncated to zero size; otherwise,
2071 * a new file will be created. The output will be written to the
2072 * file and is buffered.
2073 *
2074 * @param csn
2075 * The name of a supported {@linkplain java.nio.charset.Charset
2076 * charset}
2077 *
2078 * @throws FileNotFoundException
2079 * If the given file object does not denote an existing, writable
2080 * regular file and a new regular file of that name cannot be
2081 * created, or if some other error occurs while opening or
2082 * creating the file
2083 *
2084 * @throws SecurityException
2085 * If a security manager is present and {@link
2086 * SecurityManager#checkWrite checkWrite(file.getPath())} denies
2087 * write access to the file
2088 *
2089 * @throws UnsupportedEncodingException
2090 * If the named charset is not supported
2091 */
2092 public Formatter(File file, String csn)
2093 throws FileNotFoundException, UnsupportedEncodingException
2094 {
2095 this(file, csn, Locale.getDefault());
2096 }
2097
2098 /**
2099 * Constructs a new formatter with the specified file, charset, and
2100 * locale.
2101 *
2102 * @param file
2103 * The file to use as the destination of this formatter. If the
2104 * file exists then it will be truncated to zero size; otherwise,
2105 * a new file will be created. The output will be written to the
2106 * file and is buffered.
2107 *
2108 * @param csn
2109 * The name of a supported {@linkplain java.nio.charset.Charset
2110 * charset}
2111 *
2112 * @param l
2113 * The {@linkplain java.util.Locale locale} to apply during
2114 * formatting. If <tt>l</tt> is <tt>null</tt> then no localization
2115 * is applied.
2116 *
2117 * @throws FileNotFoundException
2118 * If the given file object does not denote an existing, writable
2119 * regular file and a new regular file of that name cannot be
2120 * created, or if some other error occurs while opening or
2121 * creating the file
2122 *
2123 * @throws SecurityException
2124 * If a security manager is present and {@link
2125 * SecurityManager#checkWrite checkWrite(file.getPath())} denies
2126 * write access to the file
2127 *
2128 * @throws UnsupportedEncodingException
2129 * If the named charset is not supported
2130 */
2131 public Formatter(File file, String csn, Locale l)
2132 throws FileNotFoundException, UnsupportedEncodingException
2133 {
2134 init(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), csn)),
2135 l);
2136 }
2137
2138 /**
2139 * Constructs a new formatter with the specified print stream.
2140 *
2141 * <p> The locale used is the {@linkplain Locale#getDefault() default
2142 * locale} for this instance of the Java virtual machine.
2143 *
2144 * <p> Characters are written to the given {@link java.io.PrintStream
2145 * PrintStream} object and are therefore encoded using that object's
2146 * charset.
2147 *
2148 * @param ps
2149 * The stream to use as the destination of this formatter.
2150 */
2151 public Formatter(PrintStream ps) {
2152 if (ps == null)
2153 throw new NullPointerException();
2154 init((Appendable)ps, Locale.getDefault());
2155 }
2156
2157 /**
2158 * Constructs a new formatter with the specified output stream.
2159 *
2160 * <p> The charset used is the {@linkplain
2161 * java.nio.charset.Charset#defaultCharset() default charset} for this
2162 * instance of the Java virtual machine.
2163 *
2164 * <p> The locale used is the {@linkplain Locale#getDefault() default
2165 * locale} for this instance of the Java virtual machine.
2166 *
2167 * @param os
2168 * The output stream to use as the destination of this formatter.
2169 * The output will be buffered.
2170 */
2171 public Formatter(OutputStream os) {
2172 init(new BufferedWriter(new OutputStreamWriter(os)),
2173 Locale.getDefault());
2174 }
2175
2176 /**
2177 * Constructs a new formatter with the specified output stream and
2178 * charset.
2179 *
2180 * <p> The locale used is the {@linkplain Locale#getDefault default
2181 * locale} for this instance of the Java virtual machine.
2182 *
2183 * @param os
2184 * The output stream to use as the destination of this formatter.
2185 * The output will be buffered.
2186 *
2187 * @param csn
2188 * The name of a supported {@linkplain java.nio.charset.Charset
2189 * charset}
2190 *
2191 * @throws UnsupportedEncodingException
2192 * If the named charset is not supported
2193 */
2194 public Formatter(OutputStream os, String csn)
2195 throws UnsupportedEncodingException
2196 {
2197 this(os, csn, Locale.getDefault());
2198 }
2199
2200 /**
2201 * Constructs a new formatter with the specified output stream, charset,
2202 * and locale.
2203 *
2204 * @param os
2205 * The output stream to use as the destination of this formatter.
2206 * The output will be buffered.
2207 *
2208 * @param csn
2209 * The name of a supported {@linkplain java.nio.charset.Charset
2210 * charset}
2211 *
2212 * @param l
2213 * The {@linkplain java.util.Locale locale} to apply during
2214 * formatting. If <tt>l</tt> is <tt>null</tt> then no localization
2215 * is applied.
2216 *
2217 * @throws UnsupportedEncodingException
2218 * If the named charset is not supported
2219 */
2220 public Formatter(OutputStream os, String csn, Locale l)
2221 throws UnsupportedEncodingException
2222 {
2223 init(new BufferedWriter(new OutputStreamWriter(os, csn)), l);
2224 }
2225
2226 private void setZero() {
2227 if ((l != null) && !l.equals(Locale.US)) {
2228 DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(l);
2229 zero = dfs.getZeroDigit();
2230 }
2231 }
2232
2233 /**
2234 * Returns the locale set by the construction of this formatter.
2235 *
2236 * <p> The {@link #format(java.util.Locale,String,Object...) format} method
2237 * for this object which has a locale argument does not change this value.
2238 *
2239 * @return <tt>null</tt> if no localization is applied, otherwise a
2240 * locale
2241 *
2242 * @throws FormatterClosedException
2243 * If this formatter has been closed by invoking its {@link
2244 * #close()} method
2245 */
2246 public Locale locale() {
2247 ensureOpen();
2248 return l;
2249 }
2250
2251 /**
2252 * Returns the destination for the output.
2253 *
2254 * @return The destination for the output
2255 *
2256 * @throws FormatterClosedException
2257 * If this formatter has been closed by invoking its {@link
2258 * #close()} method
2259 */
2260 public Appendable out() {
2261 ensureOpen();
2262 return a;
2263 }
2264
2265 /**
2266 * Returns the result of invoking <tt>toString()</tt> on the destination
2267 * for the output. For example, the following code formats text into a
2268 * {@link StringBuilder} then retrieves the resultant string:
2269 *
2270 * <blockquote><pre>
2271 * Formatter f = new Formatter();
2272 * f.format("Last reboot at %tc", lastRebootDate);
2273 * String s = f.toString();
2274 * // -&gt; s == "Last reboot at Sat Jan 01 00:00:00 PST 2000"
2275 * </pre></blockquote>
2276 *
2277 * <p> An invocation of this method behaves in exactly the same way as the
2278 * invocation
2279 *
2280 * <pre>
2281 * out().toString() </pre>
2282 *
2283 * <p> Depending on the specification of <tt>toString</tt> for the {@link
2284 * Appendable}, the returned string may or may not contain the characters
2285 * written to the destination. For instance, buffers typically return
2286 * their contents in <tt>toString()</tt>, but streams cannot since the
2287 * data is discarded.
2288 *
2289 * @return The result of invoking <tt>toString()</tt> on the destination
2290 * for the output
2291 *
2292 * @throws FormatterClosedException
2293 * If this formatter has been closed by invoking its {@link
2294 * #close()} method
2295 */
2296 public String toString() {
2297 ensureOpen();
2298 return a.toString();
2299 }
2300
2301 /**
2302 * Flushes this formatter. If the destination implements the {@link
2303 * java.io.Flushable} interface, its <tt>flush</tt> method will be invoked.
2304 *
2305 * <p> Flushing a formatter writes any buffered output in the destination
2306 * to the underlying stream.
2307 *
2308 * @throws FormatterClosedException
2309 * If this formatter has been closed by invoking its {@link
2310 * #close()} method
2311 */
2312 public void flush() {
2313 ensureOpen();
2314 if (a instanceof Flushable) {
2315 try {
2316 ((Flushable)a).flush();
2317 } catch (IOException ioe) {
2318 lastException = ioe;
2319 }
2320 }
2321 }
2322
2323 /**
2324 * Closes this formatter. If the destination implements the {@link
2325 * java.io.Closeable} interface, its <tt>close</tt> method will be invoked.
2326 *
2327 * <p> Closing a formatter allows it to release resources it may be holding
2328 * (such as open files). If the formatter is already closed, then invoking
2329 * this method has no effect.
2330 *
2331 * <p> Attempting to invoke any methods except {@link #ioException()} in
2332 * this formatter after it has been closed will result in a {@link
2333 * FormatterClosedException}.
2334 */
2335 public void close() {
2336 if (a == null)
2337 return;
2338 try {
2339 if (a instanceof Closeable)
2340 ((Closeable)a).close();
2341 } catch (IOException ioe) {
2342 lastException = ioe;
2343 } finally {
2344 a = null;
2345 }
2346 }
2347
2348 private void ensureOpen() {
2349 if (a == null)
2350 throw new FormatterClosedException();
2351 }
2352
2353 /**
2354 * Returns the <tt>IOException</tt> last thrown by this formatter's {@link
2355 * Appendable}.
2356 *
2357 * <p> If the destination's <tt>append()</tt> method never throws
2358 * <tt>IOException</tt>, then this method will always return <tt>null</tt>.
2359 *
2360 * @return The last exception thrown by the Appendable or <tt>null</tt> if
2361 * no such exception exists.
2362 */
2363 public IOException ioException() {
2364 return lastException;
2365 }
2366
2367 /**
2368 * Writes a formatted string to this object's destination using the
2369 * specified format string and arguments. The locale used is the one
2370 * defined during the construction of this formatter.
2371 *
2372 * @param format
2373 * A format string as described in <a href="#syntax">Format string
2374 * syntax</a>.
2375 *
2376 * @param args
2377 * Arguments referenced by the format specifiers in the format
2378 * string. If there are more arguments than format specifiers, the
2379 * extra arguments are ignored. The maximum number of arguments is
2380 * limited by the maximum dimension of a Java array as defined by
2381 * the <a href="http://java.sun.com/docs/books/vmspec/">Java
2382 * Virtual Machine Specification</a>.
2383 *
2384 * @throws IllegalFormatException
2385 * If a format string contains an illegal syntax, a format
2386 * specifier that is incompatible with the given arguments,
2387 * insufficient arguments given the format string, or other
2388 * illegal conditions. For specification of all possible
2389 * formatting errors, see the <a href="#detail">Details</a>
2390 * section of the formatter class specification.
2391 *
2392 * @throws FormatterClosedException
2393 * If this formatter has been closed by invoking its {@link
2394 * #close()} method
2395 *
2396 * @return This formatter
2397 */
2398 public Formatter format(String format, Object ... args) {
2399 return format(l, format, args);
2400 }
2401
2402 /**
2403 * Writes a formatted string to this object's destination using the
2404 * specified locale, format string, and arguments.
2405 *
2406 * @param l
2407 * The {@linkplain java.util.Locale locale} to apply during
2408 * formatting. If <tt>l</tt> is <tt>null</tt> then no localization
2409 * is applied. This does not change this object's locale that was
2410 * set during construction.
2411 *
2412 * @param format
2413 * A format string as described in <a href="#syntax">Format string
2414 * syntax</a>
2415 *
2416 * @param args
2417 * Arguments referenced by the format specifiers in the format
2418 * string. If there are more arguments than format specifiers, the
2419 * extra arguments are ignored. The maximum number of arguments is
2420 * limited by the maximum dimension of a Java array as defined by
2421 * the <a href="http://java.sun.com/docs/books/vmspec/">Java
2422 * Virtual Machine Specification</a>
2423 *
2424 * @throws IllegalFormatException
2425 * If a format string contains an illegal syntax, a format
2426 * specifier that is incompatible with the given arguments,
2427 * insufficient arguments given the format string, or other
2428 * illegal conditions. For specification of all possible
2429 * formatting errors, see the <a href="#detail">Details</a>
2430 * section of the formatter class specification.
2431 *
2432 * @throws FormatterClosedException
2433 * If this formatter has been closed by invoking its {@link
2434 * #close()} method
2435 *
2436 * @return This formatter
2437 */
2438 public Formatter format(Locale l, String format, Object ... args) {
2439 ensureOpen();
2440
2441 // index of last argument referenced
2442 int last = -1;
2443 // last ordinary index
2444 int lasto = -1;
2445
2446 FormatString[] fsa = parse(format);
2447 for (int i = 0; i < fsa.length; i++) {
2448 FormatString fs = fsa[i];
2449 int index = fs.index();
2450 try {
2451 switch (index) {
2452 case -2: // fixed string, "%n", or "%%"
2453 fs.print(null, l);
2454 break;
2455 case -1: // relative index
2456 if (last < 0 || (args != null && last > args.length - 1))
2457 throw new MissingFormatArgumentException(fs.toString());
2458 fs.print((args == null ? null : args[last]), l);
2459 break;
2460 case 0: // ordinary index
2461 lasto++;
2462 last = lasto;
2463 if (args != null && lasto > args.length - 1)
2464 throw new MissingFormatArgumentException(fs.toString());
2465 fs.print((args == null ? null : args[lasto]), l);
2466 break;
2467 default: // explicit index
2468 last = index - 1;
2469 if (args != null && last > args.length - 1)
2470 throw new MissingFormatArgumentException(fs.toString());
2471 fs.print((args == null ? null : args[last]), l);
2472 break;
2473 }
2474 } catch (IOException x) {
2475 lastException = x;
2476 }
2477 }
2478 return this;
2479 }
2480
2481 // %[argument_index$][flags][width][.precision][t]conversion
2482 private static final String formatSpecifier
2483 = "%(\\d+\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])";
2484
2485 private static Pattern fsPattern = Pattern.compile(formatSpecifier);
2486
2487 // Look for format specifiers in the format string.
2488 private FormatString[] parse(String s) {
2489 ArrayList al = new ArrayList();
2490 Matcher m = fsPattern.matcher(s);
2491 int i = 0;
2492 while (i < s.length()) {
2493 if (m.find(i)) {
2494 // Anything between the start of the string and the beginning
2495 // of the format specifier is either fixed text or contains
2496 // an invalid format string.
2497 if (m.start() != i) {
2498 // Make sure we didn't miss any invalid format specifiers
2499 checkText(s.substring(i, m.start()));
2500 // Assume previous characters were fixed text
2501 al.add(new FixedString(s.substring(i, m.start())));
2502 }
2503
2504 // Expect 6 groups in regular expression
2505 String[] sa = new String[6];
2506 for (int j = 0; j < m.groupCount(); j++)
2507 {
2508 sa[j] = m.group(j + 1);
2509// System.out.print(sa[j] + " ");
2510 }
2511// System.out.println();
2512 al.add(new FormatSpecifier(this, sa));
2513 i = m.end();
2514 } else {
2515 // No more valid format specifiers. Check for possible invalid
2516 // format specifiers.
2517 checkText(s.substring(i));
2518 // The rest of the string is fixed text
2519 al.add(new FixedString(s.substring(i)));
2520 break;
2521 }
2522 }
2523// FormatString[] fs = new FormatString[al.size()];
2524// for (int j = 0; j < al.size(); j++)
2525// System.out.println(((FormatString) al.get(j)).toString());
2526 return (FormatString[]) al.toArray(new FormatString[0]);
2527 }
2528
2529 private void checkText(String s) {
2530 int idx;
2531 // If there are any '%' in the given string, we got a bad format
2532 // specifier.
2533 if ((idx = s.indexOf('%')) != -1) {
2534 char c = (idx > s.length() - 2 ? '%' : s.charAt(idx + 1));
2535 throw new UnknownFormatConversionException(String.valueOf(c));
2536 }
2537 }
2538
2539 private interface FormatString {
2540 int index();
2541 void print(Object arg, Locale l) throws IOException;
2542 String toString();
2543 }
2544
2545 private class FixedString implements FormatString {
2546 private String s;
2547 FixedString(String s) { this.s = s; }
2548 public int index() { return -2; }
2549 public void print(Object arg, Locale l)
2550 throws IOException { a.append(s); }
2551 public String toString() { return s; }
2552 }
2553
2554 public enum BigDecimalLayoutForm { SCIENTIFIC, DECIMAL_FLOAT };
2555
2556 private class FormatSpecifier implements FormatString {
2557 private int index = -1;
2558 private Flags f = Flags.NONE;
2559 private int width;
2560 private int precision;
2561 private boolean dt = false;
2562 private char c;
2563
2564 private Formatter formatter;
2565
2566 // cache the line separator
2567 private String ls;
2568
2569 private int index(String s) {
2570 if (s != null) {
2571 try {
2572 index = Integer.parseInt(s.substring(0, s.length() - 1));
2573 } catch (NumberFormatException x) {
2574 assert(false);
2575 }
2576 } else {
2577 index = 0;
2578 }
2579 return index;
2580 }
2581
2582 public int index() {
2583 return index;
2584 }
2585
2586 private Flags flags(String s) {
2587 f = Flags.parse(s);
2588 if (f.contains(Flags.PREVIOUS))
2589 index = -1;
2590 return f;
2591 }
2592
2593 Flags flags() {
2594 return f;
2595 }
2596
2597 private int width(String s) {
2598 width = -1;
2599 if (s != null) {
2600 try {
2601 width = Integer.parseInt(s);
2602 if (width < 0)
2603 throw new IllegalFormatWidthException(width);
2604 } catch (NumberFormatException x) {
2605 assert(false);
2606 }
2607 }
2608 return width;
2609 }
2610
2611 int width() {
2612 return width;
2613 }
2614
2615 private int precision(String s) {
2616 precision = -1;
2617 if (s != null) {
2618 try {
2619 // remove the '.'
2620 precision = Integer.parseInt(s.substring(1));
2621 if (precision < 0)
2622 throw new IllegalFormatPrecisionException(precision);
2623 } catch (NumberFormatException x) {
2624 assert(false);
2625 }
2626 }
2627 return precision;
2628 }
2629
2630 int precision() {
2631 return precision;
2632 }
2633
2634 private char conversion(String s) {
2635 c = s.charAt(0);
2636 if (!dt) {
2637 if (!Conversion.isValid(c))
2638 throw new UnknownFormatConversionException(String.valueOf(c));
2639 if (Character.isUpperCase(c))
2640 f.add(Flags.UPPERCASE);
2641 c = Character.toLowerCase(c);
2642 if (Conversion.isText(c))
2643 index = -2;
2644 }
2645 return c;
2646 }
2647
2648 private char conversion() {
2649 return c;
2650 }
2651
2652 FormatSpecifier(Formatter formatter, String[] sa) {
2653 this.formatter = formatter;
2654 int idx = 0;
2655
2656 index(sa[idx++]);
2657 flags(sa[idx++]);
2658 width(sa[idx++]);
2659 precision(sa[idx++]);
2660
2661 if (sa[idx] != null) {
2662 dt = true;
2663 if (sa[idx].equals("T"))
2664 f.add(Flags.UPPERCASE);
2665 }
2666 conversion(sa[++idx]);
2667
2668 if (dt)
2669 checkDateTime();
2670 else if (Conversion.isGeneral(c))
2671 checkGeneral();
2672 else if (Conversion.isCharacter(c))
2673 checkCharacter();
2674 else if (Conversion.isInteger(c))
2675 checkInteger();
2676 else if (Conversion.isFloat(c))
2677 checkFloat();
2678 else if (Conversion.isText(c))
2679 checkText();
2680 else
2681 throw new UnknownFormatConversionException(String.valueOf(c));
2682 }
2683
2684 public void print(Object arg, Locale l) throws IOException {
2685 if (dt) {
2686 printDateTime(arg, l);
2687 return;
2688 }
2689 switch(c) {
2690 case Conversion.DECIMAL_INTEGER:
2691 case Conversion.OCTAL_INTEGER:
2692 case Conversion.HEXADECIMAL_INTEGER:
2693 printInteger(arg, l);
2694 break;
2695 case Conversion.SCIENTIFIC:
2696 case Conversion.GENERAL:
2697 case Conversion.DECIMAL_FLOAT:
2698 case Conversion.HEXADECIMAL_FLOAT:
2699 printFloat(arg, l);
2700 break;
2701 case Conversion.CHARACTER:
2702 case Conversion.CHARACTER_UPPER:
2703 printCharacter(arg);
2704 break;
2705 case Conversion.BOOLEAN:
2706 printBoolean(arg);
2707 break;
2708 case Conversion.STRING:
2709 printString(arg, l);
2710 break;
2711 case Conversion.HASHCODE:
2712 printHashCode(arg);
2713 break;
2714 case Conversion.LINE_SEPARATOR:
2715 if (ls == null)
2716 ls = System.getProperty("line.separator");
2717 a.append(ls);
2718 break;
2719 case Conversion.PERCENT_SIGN:
2720 a.append('%');
2721 break;
2722 default:
2723 assert false;
2724 }
2725 }
2726
2727 private void printInteger(Object arg, Locale l) throws IOException {
2728 if (arg == null)
2729 print("null");
2730 else if (arg instanceof Byte)
2731 print(((Byte)arg).byteValue(), l);
2732 else if (arg instanceof Short)
2733 print(((Short)arg).shortValue(), l);
2734 else if (arg instanceof Integer)
2735 print(((Integer)arg).intValue(), l);
2736 else if (arg instanceof Long)
2737 print(((Long)arg).longValue(), l);
2738 else if (arg instanceof BigInteger)
2739 print(((BigInteger)arg), l);
2740 else
2741 failConversion(c, arg);
2742 }
2743
2744 private void printFloat(Object arg, Locale l) throws IOException {
2745 if (arg == null)
2746 print("null");
2747 else if (arg instanceof Float)
2748 print(((Float)arg).floatValue(), l);
2749 else if (arg instanceof Double)
2750 print(((Double)arg).doubleValue(), l);
2751 else if (arg instanceof BigDecimal)
2752 print(((BigDecimal)arg), l);
2753 else
2754 failConversion(c, arg);
2755 }
2756
2757 private void printDateTime(Object arg, Locale l) throws IOException {
2758 if (arg == null) {
2759 print("null");
2760 return;
2761 }
2762 Calendar cal = null;
2763
2764 // Instead of Calendar.setLenient(true), perhaps we should
2765 // wrap the IllegalArgumentException that might be thrown?
2766 if (arg instanceof Long) {
2767 // Note that the following method uses an instance of the
2768 // default time zone (TimeZone.getDefaultRef().
2769 cal = Calendar.getInstance(l == null ? Locale.US : l);
2770 cal.setTimeInMillis((Long)arg);
2771 } else if (arg instanceof Date) {
2772 // Note that the following method uses an instance of the
2773 // default time zone (TimeZone.getDefaultRef().
2774 cal = Calendar.getInstance(l == null ? Locale.US : l);
2775 cal.setTime((Date)arg);
2776 } else if (arg instanceof Calendar) {
2777 cal = (Calendar) ((Calendar)arg).clone();
2778 cal.setLenient(true);
2779 } else {
2780 failConversion(c, arg);
2781 }
2782 // Use the provided locale so that invocations of
2783 // localizedMagnitude() use optimizations for null.
2784 print(cal, c, l);
2785 }
2786
2787 private void printCharacter(Object arg) throws IOException {
2788 if (arg == null) {
2789 print("null");
2790 return;
2791 }
2792 String s = null;
2793 if (arg instanceof Character) {
2794 s = ((Character)arg).toString();
2795 } else if (arg instanceof Byte) {
2796 byte i = ((Byte)arg).byteValue();
2797 if (Character.isValidCodePoint(i))
2798 s = new String(Character.toChars(i));
2799 else
2800 throw new IllegalFormatCodePointException(i);
2801 } else if (arg instanceof Short) {
2802 short i = ((Short)arg).shortValue();
2803 if (Character.isValidCodePoint(i))
2804 s = new String(Character.toChars(i));
2805 else
2806 throw new IllegalFormatCodePointException(i);
2807 } else if (arg instanceof Integer) {
2808 int i = ((Integer)arg).intValue();
2809 if (Character.isValidCodePoint(i))
2810 s = new String(Character.toChars(i));
2811 else
2812 throw new IllegalFormatCodePointException(i);
2813 } else {
2814 failConversion(c, arg);
2815 }
2816 print(s);
2817 }
2818
2819 private void printString(Object arg, Locale l) throws IOException {
2820 if (arg == null) {
2821 print("null");
2822 } else if (arg instanceof Formattable) {
2823 Formatter fmt = formatter;
2824 if (formatter.locale() != l)
2825 fmt = new Formatter(formatter.out(), l);
2826 ((Formattable)arg).formatTo(fmt, f.valueOf(), width, precision);
2827 } else {
2828 print(arg.toString());
2829 }
2830 }
2831
2832 private void printBoolean(Object arg) throws IOException {
2833 String s;
2834 if (arg != null)
2835 s = ((arg instanceof Boolean)
2836 ? ((Boolean)arg).toString()
2837 : Boolean.toString(true));
2838 else
2839 s = Boolean.toString(false);
2840 print(s);
2841 }
2842
2843 private void printHashCode(Object arg) throws IOException {
2844 String s = (arg == null
2845 ? "null"
2846 : Integer.toHexString(arg.hashCode()));
2847 print(s);
2848 }
2849
2850 private void print(String s) throws IOException {
2851 if (precision != -1 && precision < s.length())
2852 s = s.substring(0, precision);
2853 if (f.contains(Flags.UPPERCASE))
2854 s = s.toUpperCase();
2855 a.append(justify(s));
2856 }
2857
2858 private String justify(String s) {
2859 if (width == -1)
2860 return s;
2861 StringBuilder sb = new StringBuilder();
2862 boolean pad = f.contains(Flags.LEFT_JUSTIFY);
2863 int sp = width - s.length();
2864 if (!pad)
2865 for (int i = 0; i < sp; i++) sb.append(' ');
2866 sb.append(s);
2867 if (pad)
2868 for (int i = 0; i < sp; i++) sb.append(' ');
2869 return sb.toString();
2870 }
2871
2872 public String toString() {
2873 StringBuilder sb = new StringBuilder('%');
2874 // Flags.UPPERCASE is set internally for legal conversions.
2875 Flags dupf = f.dup().remove(Flags.UPPERCASE);
2876 sb.append(dupf.toString());
2877 if (index > 0)
2878 sb.append(index).append('$');
2879 if (width != -1)
2880 sb.append(width);
2881 if (precision != -1)
2882 sb.append('.').append(precision);
2883 if (dt)
2884 sb.append(f.contains(Flags.UPPERCASE) ? 'T' : 't');
2885 sb.append(f.contains(Flags.UPPERCASE)
2886 ? Character.toUpperCase(c) : c);
2887 return sb.toString();
2888 }
2889
2890 private void checkGeneral() {
2891 if ((c == Conversion.BOOLEAN || c == Conversion.HASHCODE)
2892 && f.contains(Flags.ALTERNATE))
2893 failMismatch(Flags.ALTERNATE, c);
2894 // '-' requires a width
2895 if (width == -1 && f.contains(Flags.LEFT_JUSTIFY))
2896 throw new MissingFormatWidthException(toString());
2897 checkBadFlags(Flags.PLUS, Flags.LEADING_SPACE, Flags.ZERO_PAD,
2898 Flags.GROUP, Flags.PARENTHESES);
2899 }
2900
2901 private void checkDateTime() {
2902 if (precision != -1)
2903 throw new IllegalFormatPrecisionException(precision);
2904 if (!DateTime.isValid(c))
2905 throw new UnknownFormatConversionException("t" + c);
2906 checkBadFlags(Flags.ALTERNATE, Flags.PLUS, Flags.LEADING_SPACE,
2907 Flags.ZERO_PAD, Flags.GROUP, Flags.PARENTHESES);
2908 // '-' requires a width
2909 if (width == -1 && f.contains(Flags.LEFT_JUSTIFY))
2910 throw new MissingFormatWidthException(toString());
2911 }
2912
2913 private void checkCharacter() {
2914 if (precision != -1)
2915 throw new IllegalFormatPrecisionException(precision);
2916 checkBadFlags(Flags.ALTERNATE, Flags.PLUS, Flags.LEADING_SPACE,
2917 Flags.ZERO_PAD, Flags.GROUP, Flags.PARENTHESES);
2918 // '-' requires a width
2919 if (width == -1 && f.contains(Flags.LEFT_JUSTIFY))
2920 throw new MissingFormatWidthException(toString());
2921 }
2922
2923 private void checkInteger() {
2924 checkNumeric();
2925 if (precision != -1)
2926 throw new IllegalFormatPrecisionException(precision);
2927
2928 if (c == Conversion.DECIMAL_INTEGER)
2929 checkBadFlags(Flags.ALTERNATE);
2930 else if (c == Conversion.OCTAL_INTEGER)
2931 checkBadFlags(Flags.GROUP);
2932 else
2933 checkBadFlags(Flags.GROUP);
2934 }
2935
2936 private void checkBadFlags(Flags ... badFlags) {
2937 for (int i = 0; i < badFlags.length; i++)
2938 if (f.contains(badFlags[i]))
2939 failMismatch(badFlags[i], c);
2940 }
2941
2942 private void checkFloat() {
2943 checkNumeric();
2944 if (c == Conversion.DECIMAL_FLOAT) {
2945 } else if (c == Conversion.HEXADECIMAL_FLOAT) {
2946 checkBadFlags(Flags.PARENTHESES, Flags.GROUP);
2947 } else if (c == Conversion.SCIENTIFIC) {
2948 checkBadFlags(Flags.GROUP);
2949 } else if (c == Conversion.GENERAL) {
2950 checkBadFlags(Flags.ALTERNATE);
2951 }
2952 }
2953
2954 private void checkNumeric() {
2955 if (width != -1 && width < 0)
2956 throw new IllegalFormatWidthException(width);
2957
2958 if (precision != -1 && precision < 0)
2959 throw new IllegalFormatPrecisionException(precision);
2960
2961 // '-' and '0' require a width
2962 if (width == -1
2963 && (f.contains(Flags.LEFT_JUSTIFY) || f.contains(Flags.ZERO_PAD)))
2964 throw new MissingFormatWidthException(toString());
2965
2966 // bad combination
2967 if ((f.contains(Flags.PLUS) && f.contains(Flags.LEADING_SPACE))
2968 || (f.contains(Flags.LEFT_JUSTIFY) && f.contains(Flags.ZERO_PAD)))
2969 throw new IllegalFormatFlagsException(f.toString());
2970 }
2971
2972 private void checkText() {
2973 if (precision != -1)
2974 throw new IllegalFormatPrecisionException(precision);
2975 switch (c) {
2976 case Conversion.PERCENT_SIGN:
2977 if (f.valueOf() != Flags.LEFT_JUSTIFY.valueOf()
2978 && f.valueOf() != Flags.NONE.valueOf())
2979 throw new IllegalFormatFlagsException(f.toString());
2980 // '-' requires a width
2981 if (width == -1 && f.contains(Flags.LEFT_JUSTIFY))
2982 throw new MissingFormatWidthException(toString());
2983 break;
2984 case Conversion.LINE_SEPARATOR:
2985 if (width != -1)
2986 throw new IllegalFormatWidthException(width);
2987 if (f.valueOf() != Flags.NONE.valueOf())
2988 throw new IllegalFormatFlagsException(f.toString());
2989 break;
2990 default:
2991 assert false;
2992 }
2993 }
2994
2995 private void print(byte value, Locale l) throws IOException {
2996 long v = value;
2997 if (value < 0
2998 && (c == Conversion.OCTAL_INTEGER
2999 || c == Conversion.HEXADECIMAL_INTEGER)) {
3000 v += (1L << 8);
3001 assert v >= 0 : v;
3002 }
3003 print(v, l);
3004 }
3005
3006 private void print(short value, Locale l) throws IOException {
3007 long v = value;
3008 if (value < 0
3009 && (c == Conversion.OCTAL_INTEGER
3010 || c == Conversion.HEXADECIMAL_INTEGER)) {
3011 v += (1L << 16);
3012 assert v >= 0 : v;
3013 }
3014 print(v, l);
3015 }
3016
3017 private void print(int value, Locale l) throws IOException {
3018 long v = value;
3019 if (value < 0
3020 && (c == Conversion.OCTAL_INTEGER
3021 || c == Conversion.HEXADECIMAL_INTEGER)) {
3022 v += (1L << 32);
3023 assert v >= 0 : v;
3024 }
3025 print(v, l);
3026 }
3027
3028 private void print(long value, Locale l) throws IOException {
3029
3030 StringBuilder sb = new StringBuilder();
3031
3032 if (c == Conversion.DECIMAL_INTEGER) {
3033 boolean neg = value < 0;
3034 char[] va;
3035 if (value < 0)
3036 va = Long.toString(value, 10).substring(1).toCharArray();
3037 else
3038 va = Long.toString(value, 10).toCharArray();
3039
3040 // leading sign indicator
3041 leadingSign(sb, neg);
3042
3043 // the value
3044 localizedMagnitude(sb, va, f, adjustWidth(width, f, neg), l);
3045
3046 // trailing sign indicator
3047 trailingSign(sb, neg);
3048 } else if (c == Conversion.OCTAL_INTEGER) {
3049 checkBadFlags(Flags.PARENTHESES, Flags.LEADING_SPACE,
3050 Flags.PLUS);
3051 String s = Long.toOctalString(value);
3052 int len = (f.contains(Flags.ALTERNATE)
3053 ? s.length() + 1
3054 : s.length());
3055
3056 // apply ALTERNATE (radix indicator for octal) before ZERO_PAD
3057 if (f.contains(Flags.ALTERNATE))
3058 sb.append('0');
3059 if (f.contains(Flags.ZERO_PAD))
3060 for (int i = 0; i < width - len; i++) sb.append('0');
3061 sb.append(s);
3062 } else if (c == Conversion.HEXADECIMAL_INTEGER) {
3063 checkBadFlags(Flags.PARENTHESES, Flags.LEADING_SPACE,
3064 Flags.PLUS);
3065 String s = Long.toHexString(value);
3066 int len = (f.contains(Flags.ALTERNATE)
3067 ? s.length() + 2
3068 : s.length());
3069
3070 // apply ALTERNATE (radix indicator for hex) before ZERO_PAD
3071 if (f.contains(Flags.ALTERNATE))
3072 sb.append(f.contains(Flags.UPPERCASE) ? "0X" : "0x");
3073 if (f.contains(Flags.ZERO_PAD))
3074 for (int i = 0; i < width - len; i++) sb.append('0');
3075 if (f.contains(Flags.UPPERCASE))
3076 s = s.toUpperCase();
3077 sb.append(s);
3078 }
3079
3080 // justify based on width
3081 a.append(justify(sb.toString()));
3082 }
3083
3084 // neg := val < 0
3085 private StringBuilder leadingSign(StringBuilder sb, boolean neg) {
3086 if (!neg) {
3087 if (f.contains(Flags.PLUS)) {
3088 sb.append('+');
3089 } else if (f.contains(Flags.LEADING_SPACE)) {
3090 sb.append(' ');
3091 }
3092 } else {
3093 if (f.contains(Flags.PARENTHESES))
3094 sb.append('(');
3095 else
3096 sb.append('-');
3097 }
3098 return sb;
3099 }
3100
3101 // neg := val < 0
3102 private StringBuilder trailingSign(StringBuilder sb, boolean neg) {
3103 if (neg && f.contains(Flags.PARENTHESES))
3104 sb.append(')');
3105 return sb;
3106 }
3107
3108 private void print(BigInteger value, Locale l) throws IOException {
3109 StringBuilder sb = new StringBuilder();
3110 boolean neg = value.signum() == -1;
3111 BigInteger v = value.abs();
3112
3113 // leading sign indicator
3114 leadingSign(sb, neg);
3115
3116 // the value
3117 if (c == Conversion.DECIMAL_INTEGER) {
3118 char[] va = v.toString().toCharArray();
3119 localizedMagnitude(sb, va, f, adjustWidth(width, f, neg), l);
3120 } else if (c == Conversion.OCTAL_INTEGER) {
3121 String s = v.toString(8);
3122
3123 int len = s.length() + sb.length();
3124 if (neg && f.contains(Flags.PARENTHESES))
3125 len++;
3126
3127 // apply ALTERNATE (radix indicator for octal) before ZERO_PAD
3128 if (f.contains(Flags.ALTERNATE)) {
3129 len++;
3130 sb.append('0');
3131 }
3132 if (f.contains(Flags.ZERO_PAD)) {
3133 for (int i = 0; i < width - len; i++)
3134 sb.append('0');
3135 }
3136 sb.append(s);
3137 } else if (c == Conversion.HEXADECIMAL_INTEGER) {
3138 String s = v.toString(16);
3139
3140 int len = s.length() + sb.length();
3141 if (neg && f.contains(Flags.PARENTHESES))
3142 len++;
3143
3144 // apply ALTERNATE (radix indicator for hex) before ZERO_PAD
3145 if (f.contains(Flags.ALTERNATE)) {
3146 len += 2;
3147 sb.append(f.contains(Flags.UPPERCASE) ? "0X" : "0x");
3148 }
3149 if (f.contains(Flags.ZERO_PAD))
3150 for (int i = 0; i < width - len; i++)
3151 sb.append('0');
3152 if (f.contains(Flags.UPPERCASE))
3153 s = s.toUpperCase();
3154 sb.append(s);
3155 }
3156
3157 // trailing sign indicator
3158 trailingSign(sb, (value.signum() == -1));
3159
3160 // justify based on width
3161 a.append(justify(sb.toString()));
3162 }
3163
3164 private void print(float value, Locale l) throws IOException {
3165 print((double) value, l);
3166 }
3167
3168 private void print(double value, Locale l) throws IOException {
3169 StringBuilder sb = new StringBuilder();
3170 boolean neg = Double.compare(value, 0.0) == -1;
3171
3172 if (!Double.isNaN(value)) {
3173 double v = Math.abs(value);
3174
3175 // leading sign indicator
3176 leadingSign(sb, neg);
3177
3178 // the value
3179 if (!Double.isInfinite(v))
3180 print(sb, v, l, f, c, precision, neg);
3181 else
3182 sb.append(f.contains(Flags.UPPERCASE)
3183 ? "INFINITY" : "Infinity");
3184
3185 // trailing sign indicator
3186 trailingSign(sb, neg);
3187 } else {
3188 sb.append(f.contains(Flags.UPPERCASE) ? "NAN" : "NaN");
3189 }
3190
3191 // justify based on width
3192 a.append(justify(sb.toString()));
3193 }
3194
3195 // !Double.isInfinite(value) && !Double.isNaN(value)
3196 private void print(StringBuilder sb, double value, Locale l,
3197 Flags f, char c, int precision, boolean neg)
3198 throws IOException
3199 {
3200 if (c == Conversion.SCIENTIFIC) {
3201 // Create a new FormattedFloatingDecimal with the desired
3202 // precision.
3203 int prec = (precision == -1 ? 6 : precision);
3204
3205 FormattedFloatingDecimal fd
3206 = new FormattedFloatingDecimal(value, prec,
3207 FormattedFloatingDecimal.Form.SCIENTIFIC);
3208
3209 char[] v = new char[MAX_FD_CHARS];
3210 int len = fd.getChars(v);
3211
3212 char[] mant = addZeros(mantissa(v, len), prec);
3213
3214 // If the precision is zero and the '#' flag is set, add the
3215 // requested decimal point.
3216 if (f.contains(Flags.ALTERNATE) && (prec == 0))
3217 mant = addDot(mant);
3218
3219 char[] exp = (value == 0.0)
3220 ? new char[] {'+','0','0'} : exponent(v, len);
3221
3222 int newW = width;
3223 if (width != -1)
3224 newW = adjustWidth(width - exp.length - 1, f, neg);
3225 localizedMagnitude(sb, mant, f, newW, l);
3226
3227 sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e');
3228
3229 Flags flags = f.dup().remove(Flags.GROUP);
3230 char sign = exp[0];
3231 assert(sign == '+' || sign == '-');
3232 sb.append(sign);
3233
3234 char[] tmp = new char[exp.length - 1];
3235 System.arraycopy(exp, 1, tmp, 0, exp.length - 1);
3236 sb.append(localizedMagnitude(null, tmp, flags, -1, l));
3237 } else if (c == Conversion.DECIMAL_FLOAT) {
3238 // Create a new FormattedFloatingDecimal with the desired
3239 // precision.
3240 int prec = (precision == -1 ? 6 : precision);
3241
3242 FormattedFloatingDecimal fd
3243 = new FormattedFloatingDecimal(value, prec,
3244 FormattedFloatingDecimal.Form.DECIMAL_FLOAT);
3245
3246 // MAX_FD_CHARS + 1 (round?)
3247 char[] v = new char[MAX_FD_CHARS + 1
3248 + Math.abs(fd.getExponent())];
3249 int len = fd.getChars(v);
3250
3251 char[] mant = addZeros(mantissa(v, len), prec);
3252
3253 // If the precision is zero and the '#' flag is set, add the
3254 // requested decimal point.
3255 if (f.contains(Flags.ALTERNATE) && (prec == 0))
3256 mant = addDot(mant);
3257
3258 int newW = width;
3259 if (width != -1)
3260 newW = adjustWidth(width, f, neg);
3261 localizedMagnitude(sb, mant, f, newW, l);
3262 } else if (c == Conversion.GENERAL) {
3263 int prec = precision;
3264 if (precision == -1)
3265 prec = 6;
3266 else if (precision == 0)
3267 prec = 1;
3268
3269 FormattedFloatingDecimal fd
3270 = new FormattedFloatingDecimal(value, prec,
3271 FormattedFloatingDecimal.Form.GENERAL);
3272
3273 // MAX_FD_CHARS + 1 (round?)
3274 char[] v = new char[MAX_FD_CHARS + 1
3275 + Math.abs(fd.getExponent())];
3276 int len = fd.getChars(v);
3277
3278 char[] exp = exponent(v, len);
3279 if (exp != null) {
3280 prec -= 1;
3281 } else {
3282 prec = prec - (value == 0 ? 0 : fd.getExponentRounded()) - 1;
3283 }
3284
3285 char[] mant = addZeros(mantissa(v, len), prec);
3286 // If the precision is zero and the '#' flag is set, add the
3287 // requested decimal point.
3288 if (f.contains(Flags.ALTERNATE) && (prec == 0))
3289 mant = addDot(mant);
3290
3291 int newW = width;
3292 if (width != -1) {
3293 if (exp != null)
3294 newW = adjustWidth(width - exp.length - 1, f, neg);
3295 else
3296 newW = adjustWidth(width, f, neg);
3297 }
3298 localizedMagnitude(sb, mant, f, newW, l);
3299
3300 if (exp != null) {
3301 sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e');
3302
3303 Flags flags = f.dup().remove(Flags.GROUP);
3304 char sign = exp[0];
3305 assert(sign == '+' || sign == '-');
3306 sb.append(sign);
3307
3308 char[] tmp = new char[exp.length - 1];
3309 System.arraycopy(exp, 1, tmp, 0, exp.length - 1);
3310 sb.append(localizedMagnitude(null, tmp, flags, -1, l));
3311 }
3312 } else if (c == Conversion.HEXADECIMAL_FLOAT) {
3313 int prec = precision;
3314 if (precision == -1)
3315 // assume that we want all of the digits
3316 prec = 0;
3317 else if (precision == 0)
3318 prec = 1;
3319
3320 String s = hexDouble(value, prec);
3321
3322 char[] va;
3323 boolean upper = f.contains(Flags.UPPERCASE);
3324 sb.append(upper ? "0X" : "0x");
3325
3326 if (f.contains(Flags.ZERO_PAD))
3327 for (int i = 0; i < width - s.length() - 2; i++)
3328 sb.append('0');
3329
3330 int idx = s.indexOf('p');
3331 va = s.substring(0, idx).toCharArray();
3332 if (upper) {
3333 String tmp = new String(va);
3334 // don't localize hex
3335 tmp = tmp.toUpperCase(Locale.US);
3336 va = tmp.toCharArray();
3337 }
3338 sb.append(prec != 0 ? addZeros(va, prec) : va);
3339 sb.append(upper ? 'P' : 'p');
3340 sb.append(s.substring(idx+1));
3341 }
3342 }
3343
3344 private char[] mantissa(char[] v, int len) {
3345 int i;
3346 for (i = 0; i < len; i++) {
3347 if (v[i] == 'e')
3348 break;
3349 }
3350 char[] tmp = new char[i];
3351 System.arraycopy(v, 0, tmp, 0, i);
3352 return tmp;
3353 }
3354
3355 private char[] exponent(char[] v, int len) {
3356 int i;
3357 for (i = len - 1; i >= 0; i--) {
3358 if (v[i] == 'e')
3359 break;
3360 }
3361 if (i == -1)
3362 return null;
3363 char[] tmp = new char[len - i - 1];
3364 System.arraycopy(v, i + 1, tmp, 0, len - i - 1);
3365 return tmp;
3366 }
3367
3368 // Add zeros to the requested precision.
3369 private char[] addZeros(char[] v, int prec) {
3370 // Look for the dot. If we don't find one, the we'll need to add
3371 // it before we add the zeros.
3372 int i;
3373 for (i = 0; i < v.length; i++) {
3374 if (v[i] == '.')
3375 break;
3376 }
3377 boolean needDot = false;
3378 if (i == v.length) {
3379 needDot = true;
3380 }
3381
3382 // Determine existing precision.
3383 int outPrec = v.length - i - (needDot ? 0 : 1);
3384 assert (outPrec <= prec);
3385 if (outPrec == prec)
3386 return v;
3387
3388 // Create new array with existing contents.
3389 char[] tmp
3390 = new char[v.length + prec - outPrec + (needDot ? 1 : 0)];
3391 System.arraycopy(v, 0, tmp, 0, v.length);
3392
3393 // Add dot if previously determined to be necessary.
3394 int start = v.length;
3395 if (needDot) {
3396 tmp[v.length] = '.';
3397 start++;
3398 }
3399
3400 // Add zeros.
3401 for (int j = start; j < tmp.length; j++)
3402 tmp[j] = '0';
3403
3404 return tmp;
3405 }
3406
3407 // Method assumes that d > 0.
3408 private String hexDouble(double d, int prec) {
3409 // Let Double.toHexString handle simple cases
3410 if(!FpUtils.isFinite(d) || d == 0.0 || prec == 0 || prec >= 13)
3411 // remove "0x"
3412 return Double.toHexString(d).substring(2);
3413 else {
3414 assert(prec >= 1 && prec <= 12);
3415
3416 int exponent = FpUtils.getExponent(d);
3417 boolean subnormal
3418 = (exponent == DoubleConsts.MIN_EXPONENT - 1);
3419
3420 // If this is subnormal input so normalize (could be faster to
3421 // do as integer operation).
3422 if (subnormal) {
3423 scaleUp = FpUtils.scalb(1.0, 54);
3424 d *= scaleUp;
3425 // Calculate the exponent. This is not just exponent + 54
3426 // since the former is not the normalized exponent.
3427 exponent = FpUtils.getExponent(d);
3428 assert exponent >= DoubleConsts.MIN_EXPONENT &&
3429 exponent <= DoubleConsts.MAX_EXPONENT: exponent;
3430 }
3431
3432 int precision = 1 + prec*4;
3433 int shiftDistance
3434 = DoubleConsts.SIGNIFICAND_WIDTH - precision;
3435 assert(shiftDistance >= 1 && shiftDistance < DoubleConsts.SIGNIFICAND_WIDTH);
3436
3437 long doppel = Double.doubleToLongBits(d);
3438 // Deterime the number of bits to keep.
3439 long newSignif
3440 = (doppel & (DoubleConsts.EXP_BIT_MASK
3441 | DoubleConsts.SIGNIF_BIT_MASK))
3442 >> shiftDistance;
3443 // Bits to round away.
3444 long roundingBits = doppel & ~(~0L << shiftDistance);
3445
3446 // To decide how to round, look at the low-order bit of the
3447 // working significand, the highest order discarded bit (the
3448 // round bit) and whether any of the lower order discarded bits
3449 // are nonzero (the sticky bit).
3450
3451 boolean leastZero = (newSignif & 0x1L) == 0L;
3452 boolean round
3453 = ((1L << (shiftDistance - 1) ) & roundingBits) != 0L;
3454 boolean sticky = shiftDistance > 1 &&
3455 (~(1L<< (shiftDistance - 1)) & roundingBits) != 0;
3456 if((leastZero && round && sticky) || (!leastZero && round)) {
3457 newSignif++;
3458 }
3459
3460 long signBit = doppel & DoubleConsts.SIGN_BIT_MASK;
3461 newSignif = signBit | (newSignif << shiftDistance);
3462 double result = Double.longBitsToDouble(newSignif);
3463
3464 if (Double.isInfinite(result) ) {
3465 // Infinite result generated by rounding
3466 return "1.0p1024";
3467 } else {
3468 String res = Double.toHexString(result).substring(2);
3469 if (!subnormal)
3470 return res;
3471 else {
3472 // Create a normalized subnormal string.
3473 int idx = res.indexOf('p');
3474 if (idx == -1) {
3475 // No 'p' character in hex string.
3476 assert false;
3477 return null;
3478 } else {
3479 // Get exponent and append at the end.
3480 String exp = res.substring(idx + 1);
3481 int iexp = Integer.parseInt(exp) -54;
3482 return res.substring(0, idx) + "p"
3483 + Integer.toString(iexp);
3484 }
3485 }
3486 }
3487 }
3488 }
3489
3490 private void print(BigDecimal value, Locale l) throws IOException {
3491 if (c == Conversion.HEXADECIMAL_FLOAT)
3492 failConversion(c, value);
3493 StringBuilder sb = new StringBuilder();
3494 boolean neg = value.signum() == -1;
3495 BigDecimal v = value.abs();
3496 // leading sign indicator
3497 leadingSign(sb, neg);
3498
3499 // the value
3500 print(sb, v, l, f, c, precision, neg);
3501
3502 // trailing sign indicator
3503 trailingSign(sb, neg);
3504
3505 // justify based on width
3506 a.append(justify(sb.toString()));
3507 }
3508
3509 // value > 0
3510 private void print(StringBuilder sb, BigDecimal value, Locale l,
3511 Flags f, char c, int precision, boolean neg)
3512 throws IOException
3513 {
3514 if (c == Conversion.SCIENTIFIC) {
3515 // Create a new BigDecimal with the desired precision.
3516 int prec = (precision == -1 ? 6 : precision);
3517 int scale = value.scale();
3518 int origPrec = value.precision();
3519 int nzeros = 0;
3520 int compPrec;
3521
3522 if (prec > origPrec - 1) {
3523 compPrec = origPrec;
3524 nzeros = prec - (origPrec - 1);
3525 } else {
3526 compPrec = prec + 1;
3527 }
3528
3529 MathContext mc = new MathContext(compPrec);
3530 BigDecimal v
3531 = new BigDecimal(value.unscaledValue(), scale, mc);
3532
3533 BigDecimalLayout bdl
3534 = new BigDecimalLayout(v.unscaledValue(), v.scale(),
3535 BigDecimalLayoutForm.SCIENTIFIC);
3536
3537 char[] mant = bdl.mantissa();
3538
3539 // Add a decimal point if necessary. The mantissa may not
3540 // contain a decimal point if the scale is zero (the internal
3541 // representation has no fractional part) or the original
3542 // precision is one. Append a decimal point if '#' is set or if
3543 // we require zero padding to get to the requested precision.
3544 if ((origPrec == 1 || !bdl.hasDot())
3545 && (nzeros > 0 || (f.contains(Flags.ALTERNATE))))
3546 mant = addDot(mant);
3547
3548 // Add trailing zeros in the case precision is greater than
3549 // the number of available digits after the decimal separator.
3550 mant = trailingZeros(mant, nzeros);
3551
3552 char[] exp = bdl.exponent();
3553 int newW = width;
3554 if (width != -1)
3555 newW = adjustWidth(width - exp.length - 1, f, neg);
3556 localizedMagnitude(sb, mant, f, newW, l);
3557
3558 sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e');
3559
3560 Flags flags = f.dup().remove(Flags.GROUP);
3561 char sign = exp[0];
3562 assert(sign == '+' || sign == '-');
3563 sb.append(exp[0]);
3564
3565 char[] tmp = new char[exp.length - 1];
3566 System.arraycopy(exp, 1, tmp, 0, exp.length - 1);
3567 sb.append(localizedMagnitude(null, tmp, flags, -1, l));
3568 } else if (c == Conversion.DECIMAL_FLOAT) {
3569 // Create a new BigDecimal with the desired precision.
3570 int prec = (precision == -1 ? 6 : precision);
3571 int scale = value.scale();
3572 int compPrec = value.precision();
3573 if (scale > prec)
3574 compPrec -= (scale - prec);
3575 MathContext mc = new MathContext(compPrec);
3576 BigDecimal v
3577 = new BigDecimal(value.unscaledValue(), scale, mc);
3578
3579 BigDecimalLayout bdl
3580 = new BigDecimalLayout(v.unscaledValue(), v.scale(),
3581 BigDecimalLayoutForm.DECIMAL_FLOAT);
3582
3583 char mant[] = bdl.mantissa();
3584 int nzeros = (bdl.scale() < prec ? prec - bdl.scale() : 0);
3585
3586 // Add a decimal point if necessary. The mantissa may not
3587 // contain a decimal point if the scale is zero (the internal
3588 // representation has no fractional part). Append a decimal
3589 // point if '#' is set or we require zero padding to get to the
3590 // requested precision.
3591 if (bdl.scale() == 0 && (f.contains(Flags.ALTERNATE) || nzeros > 0))
3592 mant = addDot(bdl.mantissa());
3593
3594 // Add trailing zeros if the precision is greater than the
3595 // number of available digits after the decimal separator.
3596 mant = trailingZeros(mant, nzeros);
3597
3598 localizedMagnitude(sb, mant, f, adjustWidth(width, f, neg), l);
3599 } else if (c == Conversion.GENERAL) {
3600 int prec = precision;
3601 if (precision == -1)
3602 prec = 6;
3603 else if (precision == 0)
3604 prec = 1;
3605
3606 BigDecimal tenToTheNegFour = BigDecimal.valueOf(1, 4);
3607 BigDecimal tenToThePrec = BigDecimal.valueOf(1, -prec);
3608 if ((value.equals(BigDecimal.ZERO))
3609 || ((value.compareTo(tenToTheNegFour) != -1)
3610 && (value.compareTo(tenToThePrec) == -1))) {
3611
3612 int e = - value.scale()
3613 + (value.unscaledValue().toString().length() - 1);
3614
3615 // xxx.yyy
3616 // g precision (# sig digits) = #x + #y
3617 // f precision = #y
3618 // exponent = #x - 1
3619 // => f precision = g precision - exponent - 1
3620 // 0.000zzz
3621 // g precision (# sig digits) = #z
3622 // f precision = #0 (after '.') + #z
3623 // exponent = - #0 (after '.') - 1
3624 // => f precision = g precision - exponent - 1
3625 prec = prec - e - 1;
3626
3627 print(sb, value, l, f, Conversion.DECIMAL_FLOAT, prec,
3628 neg);
3629 } else {
3630 print(sb, value, l, f, Conversion.SCIENTIFIC, prec - 1, neg);
3631 }
3632 } else if (c == Conversion.HEXADECIMAL_FLOAT) {
3633 // This conversion isn't supported. The error should be
3634 // reported earlier.
3635 assert false;
3636 }
3637 }
3638
3639 private class BigDecimalLayout {
3640 private StringBuilder mant;
3641 private StringBuilder exp;
3642 private boolean dot = false;
3643 private int scale;
3644
3645 public BigDecimalLayout(BigInteger intVal, int scale, BigDecimalLayoutForm form) {
3646 layout(intVal, scale, form);
3647 }
3648
3649 public boolean hasDot() {
3650 return dot;
3651 }
3652
3653 public int scale() {
3654 return scale;
3655 }
3656
3657 // char[] with canonical string representation
3658 public char[] layoutChars() {
3659 StringBuilder sb = new StringBuilder(mant);
3660 if (exp != null) {
3661 sb.append('E');
3662 sb.append(exp);
3663 }
3664 return toCharArray(sb);
3665 }
3666
3667 public char[] mantissa() {
3668 return toCharArray(mant);
3669 }
3670
3671 // The exponent will be formatted as a sign ('+' or '-') followed
3672 // by the exponent zero-padded to include at least two digits.
3673 public char[] exponent() {
3674 return toCharArray(exp);
3675 }
3676
3677 private char[] toCharArray(StringBuilder sb) {
3678 if (sb == null)
3679 return null;
3680 char[] result = new char[sb.length()];
3681 sb.getChars(0, result.length, result, 0);
3682 return result;
3683 }
3684
3685 private void layout(BigInteger intVal, int scale, BigDecimalLayoutForm form) {
3686 char coeff[] = intVal.toString().toCharArray();
3687 this.scale = scale;
3688
3689 // Construct a buffer, with sufficient capacity for all cases.
3690 // If E-notation is needed, length will be: +1 if negative, +1
3691 // if '.' needed, +2 for "E+", + up to 10 for adjusted
3692 // exponent. Otherwise it could have +1 if negative, plus
3693 // leading "0.00000"
3694 mant = new StringBuilder(coeff.length + 14);
3695
3696 if (scale == 0) {
3697 int len = coeff.length;
3698 if (len > 1) {
3699 mant.append(coeff[0]);
3700 if (form == BigDecimalLayoutForm.SCIENTIFIC) {
3701 mant.append('.');
3702 dot = true;
3703 mant.append(coeff, 1, len - 1);
3704 exp = new StringBuilder("+");
3705 if (len < 10)
3706 exp.append("0").append(len - 1);
3707 else
3708 exp.append(len - 1);
3709 } else {
3710 mant.append(coeff, 1, len - 1);
3711 }
3712 } else {
3713 mant.append(coeff);
3714 if (form == BigDecimalLayoutForm.SCIENTIFIC)
3715 exp = new StringBuilder("+00");
3716 }
3717 return;
3718 }
3719 long adjusted = -(long) scale + (coeff.length - 1);
3720 if (form == BigDecimalLayoutForm.DECIMAL_FLOAT) {
3721 // count of padding zeros
3722 int pad = scale - coeff.length;
3723 if (pad >= 0) {
3724 // 0.xxx form
3725 mant.append("0.");
3726 dot = true;
3727 for (; pad > 0 ; pad--) mant.append('0');
3728 mant.append(coeff);
3729 } else {
3730 if (-pad < coeff.length) {
3731 // xx.xx form
3732 mant.append(coeff, 0, -pad);
3733 mant.append('.');
3734 dot = true;
3735 mant.append(coeff, -pad, scale);
3736 } else {
3737 // xx form
3738 mant.append(coeff, 0, coeff.length);
3739 for (int i = 0; i < -scale; i++)
3740 mant.append('0');
3741 this.scale = 0;
3742 }
3743 }
3744 } else {
3745 // x.xxx form
3746 mant.append(coeff[0]);
3747 if (coeff.length > 1) {
3748 mant.append('.');
3749 dot = true;
3750 mant.append(coeff, 1, coeff.length-1);
3751 }
3752 exp = new StringBuilder();
3753 if (adjusted != 0) {
3754 long abs = Math.abs(adjusted);
3755 // require sign
3756 exp.append(adjusted < 0 ? '-' : '+');
3757 if (abs < 10)
3758 exp.append('0');
3759 exp.append(abs);
3760 } else {
3761 exp.append("+00");
3762 }
3763 }
3764 }
3765 }
3766
3767 private int adjustWidth(int width, Flags f, boolean neg) {
3768 int newW = width;
3769 if (newW != -1 && neg && f.contains(Flags.PARENTHESES))
3770 newW--;
3771 return newW;
3772 }
3773
3774 // Add a '.' to th mantissa if required
3775 private char[] addDot(char[] mant) {
3776 char[] tmp = mant;
3777 tmp = new char[mant.length + 1];
3778 System.arraycopy(mant, 0, tmp, 0, mant.length);
3779 tmp[tmp.length - 1] = '.';
3780 return tmp;
3781 }
3782
3783 // Add trailing zeros in the case precision is greater than the number
3784 // of available digits after the decimal separator.
3785 private char[] trailingZeros(char[] mant, int nzeros) {
3786 char[] tmp = mant;
3787 if (nzeros > 0) {
3788 tmp = new char[mant.length + nzeros];
3789 System.arraycopy(mant, 0, tmp, 0, mant.length);
3790 for (int i = mant.length; i < tmp.length; i++)
3791 tmp[i] = '0';
3792 }
3793 return tmp;
3794 }
3795
3796 private void print(Calendar t, char c, Locale l) throws IOException
3797 {
3798 StringBuilder sb = new StringBuilder();
3799 print(sb, t, c, l);
3800
3801 // justify based on width
3802 String s = justify(sb.toString());
3803 if (f.contains(Flags.UPPERCASE))
3804 s = s.toUpperCase();
3805
3806 a.append(s);
3807 }
3808
3809 private Appendable print(StringBuilder sb, Calendar t, char c,
3810 Locale l)
3811 throws IOException
3812 {
3813 assert(width == -1);
3814 if (sb == null)
3815 sb = new StringBuilder();
3816 switch (c) {
3817 case DateTime.HOUR_OF_DAY_0: // 'H' (00 - 23)
3818 case DateTime.HOUR_0: // 'I' (01 - 12)
3819 case DateTime.HOUR_OF_DAY: // 'k' (0 - 23) -- like H
3820 case DateTime.HOUR: { // 'l' (1 - 12) -- like I
3821 int i = t.get(Calendar.HOUR_OF_DAY);
3822 if (c == DateTime.HOUR_0 || c == DateTime.HOUR)
3823 i = (i == 0 || i == 12 ? 12 : i % 12);
3824 Flags flags = (c == DateTime.HOUR_OF_DAY_0
3825 || c == DateTime.HOUR_0
3826 ? Flags.ZERO_PAD
3827 : Flags.NONE);
3828 sb.append(localizedMagnitude(null, i, flags, 2, l));
3829 break;
3830 }
3831 case DateTime.MINUTE: { // 'M' (00 - 59)
3832 int i = t.get(Calendar.MINUTE);
3833 Flags flags = Flags.ZERO_PAD;
3834 sb.append(localizedMagnitude(null, i, flags, 2, l));
3835 break;
3836 }
3837 case DateTime.NANOSECOND: { // 'N' (000000000 - 999999999)
3838 int i = t.get(Calendar.MILLISECOND) * 1000000;
3839 Flags flags = Flags.ZERO_PAD;
3840 sb.append(localizedMagnitude(null, i, flags, 9, l));
3841 break;
3842 }
3843 case DateTime.MILLISECOND: { // 'L' (000 - 999)
3844 int i = t.get(Calendar.MILLISECOND);
3845 Flags flags = Flags.ZERO_PAD;
3846 sb.append(localizedMagnitude(null, i, flags, 3, l));
3847 break;
3848 }
3849 case DateTime.MILLISECOND_SINCE_EPOCH: { // 'Q' (0 - 99...?)
3850 long i = t.getTimeInMillis();
3851 Flags flags = Flags.NONE;
3852 sb.append(localizedMagnitude(null, i, flags, width, l));
3853 break;
3854 }
3855 case DateTime.AM_PM: { // 'p' (am or pm)
3856 // Calendar.AM = 0, Calendar.PM = 1, LocaleElements defines upper
3857 String[] ampm = { "AM", "PM" };
3858 if (l != null && l != Locale.US) {
3859 DateFormatSymbols dfs = DateFormatSymbols.getInstance(l);
3860 ampm = dfs.getAmPmStrings();
3861 }
3862 String s = ampm[t.get(Calendar.AM_PM)];
3863 sb.append(s.toLowerCase(l != null ? l : Locale.US));
3864 break;
3865 }
3866 case DateTime.SECONDS_SINCE_EPOCH: { // 's' (0 - 99...?)
3867 long i = t.getTimeInMillis() / 1000;
3868 Flags flags = Flags.NONE;
3869 sb.append(localizedMagnitude(null, i, flags, width, l));
3870 break;
3871 }
3872 case DateTime.SECOND: { // 'S' (00 - 60 - leap second)
3873 int i = t.get(Calendar.SECOND);
3874 Flags flags = Flags.ZERO_PAD;
3875 sb.append(localizedMagnitude(null, i, flags, 2, l));
3876 break;
3877 }
3878 case DateTime.ZONE_NUMERIC: { // 'z' ({-|+}####) - ls minus?
3879 int i = t.get(Calendar.ZONE_OFFSET) + t.get(Calendar.DST_OFFSET);
3880 boolean neg = i < 0;
3881 sb.append(neg ? '-' : '+');
3882 if (neg)
3883 i = -i;
3884 int min = i / 60000;
3885 // combine minute and hour into a single integer
3886 int offset = (min / 60) * 100 + (min % 60);
3887 Flags flags = Flags.ZERO_PAD;
3888
3889 sb.append(localizedMagnitude(null, offset, flags, 4, l));
3890 break;
3891 }
3892 case DateTime.ZONE: { // 'Z' (symbol)
3893 TimeZone tz = t.getTimeZone();
3894 sb.append(tz.getDisplayName((t.get(Calendar.DST_OFFSET) != 0),
3895 TimeZone.SHORT,
3896 (l == null) ? Locale.US : l));
3897 break;
3898 }
3899
3900 // Date
3901 case DateTime.NAME_OF_DAY_ABBREV: // 'a'
3902 case DateTime.NAME_OF_DAY: { // 'A'
3903 int i = t.get(Calendar.DAY_OF_WEEK);
3904 Locale lt = ((l == null) ? Locale.US : l);
3905 DateFormatSymbols dfs = DateFormatSymbols.getInstance(lt);
3906 if (c == DateTime.NAME_OF_DAY)
3907 sb.append(dfs.getWeekdays()[i]);
3908 else
3909 sb.append(dfs.getShortWeekdays()[i]);
3910 break;
3911 }
3912 case DateTime.NAME_OF_MONTH_ABBREV: // 'b'
3913 case DateTime.NAME_OF_MONTH_ABBREV_X: // 'h' -- same b
3914 case DateTime.NAME_OF_MONTH: { // 'B'
3915 int i = t.get(Calendar.MONTH);
3916 Locale lt = ((l == null) ? Locale.US : l);
3917 DateFormatSymbols dfs = DateFormatSymbols.getInstance(lt);
3918 if (c == DateTime.NAME_OF_MONTH)
3919 sb.append(dfs.getMonths()[i]);
3920 else
3921 sb.append(dfs.getShortMonths()[i]);
3922 break;
3923 }
3924 case DateTime.CENTURY: // 'C' (00 - 99)
3925 case DateTime.YEAR_2: // 'y' (00 - 99)
3926 case DateTime.YEAR_4: { // 'Y' (0000 - 9999)
3927 int i = t.get(Calendar.YEAR);
3928 int size = 2;
3929 switch (c) {
3930 case DateTime.CENTURY:
3931 i /= 100;
3932 break;
3933 case DateTime.YEAR_2:
3934 i %= 100;
3935 break;
3936 case DateTime.YEAR_4:
3937 size = 4;
3938 break;
3939 }
3940 Flags flags = Flags.ZERO_PAD;
3941 sb.append(localizedMagnitude(null, i, flags, size, l));
3942 break;
3943 }
3944 case DateTime.DAY_OF_MONTH_0: // 'd' (01 - 31)
3945 case DateTime.DAY_OF_MONTH: { // 'e' (1 - 31) -- like d
3946 int i = t.get(Calendar.DATE);
3947 Flags flags = (c == DateTime.DAY_OF_MONTH_0
3948 ? Flags.ZERO_PAD
3949 : Flags.NONE);
3950 sb.append(localizedMagnitude(null, i, flags, 2, l));
3951 break;
3952 }
3953 case DateTime.DAY_OF_YEAR: { // 'j' (001 - 366)
3954 int i = t.get(Calendar.DAY_OF_YEAR);
3955 Flags flags = Flags.ZERO_PAD;
3956 sb.append(localizedMagnitude(null, i, flags, 3, l));
3957 break;
3958 }
3959 case DateTime.MONTH: { // 'm' (01 - 12)
3960 int i = t.get(Calendar.MONTH) + 1;
3961 Flags flags = Flags.ZERO_PAD;
3962 sb.append(localizedMagnitude(null, i, flags, 2, l));
3963 break;
3964 }
3965
3966 // Composites
3967 case DateTime.TIME: // 'T' (24 hour hh:mm:ss - %tH:%tM:%tS)
3968 case DateTime.TIME_24_HOUR: { // 'R' (hh:mm same as %H:%M)
3969 char sep = ':';
3970 print(sb, t, DateTime.HOUR_OF_DAY_0, l).append(sep);
3971 print(sb, t, DateTime.MINUTE, l);
3972 if (c == DateTime.TIME) {
3973 sb.append(sep);
3974 print(sb, t, DateTime.SECOND, l);
3975 }
3976 break;
3977 }
3978 case DateTime.TIME_12_HOUR: { // 'r' (hh:mm:ss [AP]M)
3979 char sep = ':';
3980 print(sb, t, DateTime.HOUR_0, l).append(sep);
3981 print(sb, t, DateTime.MINUTE, l).append(sep);
3982 print(sb, t, DateTime.SECOND, l).append(' ');
3983 // this may be in wrong place for some locales
3984 StringBuilder tsb = new StringBuilder();
3985 print(tsb, t, DateTime.AM_PM, l);
3986 sb.append(tsb.toString().toUpperCase(l != null ? l : Locale.US));
3987 break;
3988 }
3989 case DateTime.DATE_TIME: { // 'c' (Sat Nov 04 12:02:33 EST 1999)
3990 char sep = ' ';
3991 print(sb, t, DateTime.NAME_OF_DAY_ABBREV, l).append(sep);
3992 print(sb, t, DateTime.NAME_OF_MONTH_ABBREV, l).append(sep);
3993 print(sb, t, DateTime.DAY_OF_MONTH_0, l).append(sep);
3994 print(sb, t, DateTime.TIME, l).append(sep);
3995 print(sb, t, DateTime.ZONE, l).append(sep);
3996 print(sb, t, DateTime.YEAR_4, l);
3997 break;
3998 }
3999 case DateTime.DATE: { // 'D' (mm/dd/yy)
4000 char sep = '/';
4001 print(sb, t, DateTime.MONTH, l).append(sep);
4002 print(sb, t, DateTime.DAY_OF_MONTH_0, l).append(sep);
4003 print(sb, t, DateTime.YEAR_2, l);
4004 break;
4005 }
4006 case DateTime.ISO_STANDARD_DATE: { // 'F' (%Y-%m-%d)
4007 char sep = '-';
4008 print(sb, t, DateTime.YEAR_4, l).append(sep);
4009 print(sb, t, DateTime.MONTH, l).append(sep);
4010 print(sb, t, DateTime.DAY_OF_MONTH_0, l);
4011 break;
4012 }
4013 default:
4014 assert false;
4015 }
4016 return sb;
4017 }
4018
4019 // -- Methods to support throwing exceptions --
4020
4021 private void failMismatch(Flags f, char c) {
4022 String fs = f.toString();
4023 throw new FormatFlagsConversionMismatchException(fs, c);
4024 }
4025
4026 private void failConversion(char c, Object arg) {
4027 throw new IllegalFormatConversionException(c, arg.getClass());
4028 }
4029
4030 private char getZero(Locale l) {
4031 if ((l != null) && !l.equals(locale())) {
4032 DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(l);
4033 return dfs.getZeroDigit();
4034 }
4035 return zero;
4036 }
4037
4038 private StringBuilder
4039 localizedMagnitude(StringBuilder sb, long value, Flags f,
4040 int width, Locale l)
4041 {
4042 char[] va = Long.toString(value, 10).toCharArray();
4043 return localizedMagnitude(sb, va, f, width, l);
4044 }
4045
4046 private StringBuilder
4047 localizedMagnitude(StringBuilder sb, char[] value, Flags f,
4048 int width, Locale l)
4049 {
4050 if (sb == null)
4051 sb = new StringBuilder();
4052 int begin = sb.length();
4053
4054 char zero = getZero(l);
4055
4056 // determine localized grouping separator and size
4057 char grpSep = '\0';
4058 int grpSize = -1;
4059 char decSep = '\0';
4060
4061 int len = value.length;
4062 int dot = len;
4063 for (int j = 0; j < len; j++) {
4064 if (value[j] == '.') {
4065 dot = j;
4066 break;
4067 }
4068 }
4069
4070 if (dot < len) {
4071 if (l == null || l.equals(Locale.US)) {
4072 decSep = '.';
4073 } else {
4074 DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(l);
4075 decSep = dfs.getDecimalSeparator();
4076 }
4077 }
4078
4079 if (f.contains(Flags.GROUP)) {
4080 if (l == null || l.equals(Locale.US)) {
4081 grpSep = ',';
4082 grpSize = 3;
4083 } else {
4084 DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(l);
4085 grpSep = dfs.getGroupingSeparator();
4086 DecimalFormat df = (DecimalFormat) NumberFormat.getIntegerInstance(l);
4087 grpSize = df.getGroupingSize();
4088 }
4089 }
4090
4091 // localize the digits inserting group separators as necessary
4092 for (int j = 0; j < len; j++) {
4093 if (j == dot) {
4094 sb.append(decSep);
4095 // no more group separators after the decimal separator
4096 grpSep = '\0';
4097 continue;
4098 }
4099
4100 char c = value[j];
4101 sb.append((char) ((c - '0') + zero));
4102 if (grpSep != '\0' && j != dot - 1 && ((dot - j) % grpSize == 1))
4103 sb.append(grpSep);
4104 }
4105
4106 // apply zero padding
4107 len = sb.length();
4108 if (width != -1 && f.contains(Flags.ZERO_PAD))
4109 for (int k = 0; k < width - len; k++)
4110 sb.insert(begin, zero);
4111
4112 return sb;
4113 }
4114 }
4115
4116 private static class Flags {
4117 private int flags;
4118
4119 static final Flags NONE = new Flags(0); // ''
4120
4121 // duplicate declarations from Formattable.java
4122 static final Flags LEFT_JUSTIFY = new Flags(1<<0); // '-'
4123 static final Flags UPPERCASE = new Flags(1<<1); // '^'
4124 static final Flags ALTERNATE = new Flags(1<<2); // '#'
4125
4126 // numerics
4127 static final Flags PLUS = new Flags(1<<3); // '+'
4128 static final Flags LEADING_SPACE = new Flags(1<<4); // ' '
4129 static final Flags ZERO_PAD = new Flags(1<<5); // '0'
4130 static final Flags GROUP = new Flags(1<<6); // ','
4131 static final Flags PARENTHESES = new Flags(1<<7); // '('
4132
4133 // indexing
4134 static final Flags PREVIOUS = new Flags(1<<8); // '<'
4135
4136 private Flags(int f) {
4137 flags = f;
4138 }
4139
4140 public int valueOf() {
4141 return flags;
4142 }
4143
4144 public boolean contains(Flags f) {
4145 return (flags & f.valueOf()) == f.valueOf();
4146 }
4147
4148 public Flags dup() {
4149 return new Flags(flags);
4150 }
4151
4152 private Flags add(Flags f) {
4153 flags |= f.valueOf();
4154 return this;
4155 }
4156
4157 public Flags remove(Flags f) {
4158 flags &= ~f.valueOf();
4159 return this;
4160 }
4161
4162 public static Flags parse(String s) {
4163 char[] ca = s.toCharArray();
4164 Flags f = new Flags(0);
4165 for (int i = 0; i < ca.length; i++) {
4166 Flags v = parse(ca[i]);
4167 if (f.contains(v))
4168 throw new DuplicateFormatFlagsException(v.toString());
4169 f.add(v);
4170 }
4171 return f;
4172 }
4173
4174 // parse those flags which may be provided by users
4175 private static Flags parse(char c) {
4176 switch (c) {
4177 case '-': return LEFT_JUSTIFY;
4178 case '#': return ALTERNATE;
4179 case '+': return PLUS;
4180 case ' ': return LEADING_SPACE;
4181 case '0': return ZERO_PAD;
4182 case ',': return GROUP;
4183 case '(': return PARENTHESES;
4184 case '<': return PREVIOUS;
4185 default:
4186 throw new UnknownFormatFlagsException(String.valueOf(c));
4187 }
4188 }
4189
4190 // Returns a string representation of the current <tt>Flags</tt>.
4191 public static String toString(Flags f) {
4192 return f.toString();
4193 }
4194
4195 public String toString() {
4196 StringBuilder sb = new StringBuilder();
4197 if (contains(LEFT_JUSTIFY)) sb.append('-');
4198 if (contains(UPPERCASE)) sb.append('^');
4199 if (contains(ALTERNATE)) sb.append('#');
4200 if (contains(PLUS)) sb.append('+');
4201 if (contains(LEADING_SPACE)) sb.append(' ');
4202 if (contains(ZERO_PAD)) sb.append('0');
4203 if (contains(GROUP)) sb.append(',');
4204 if (contains(PARENTHESES)) sb.append('(');
4205 if (contains(PREVIOUS)) sb.append('<');
4206 return sb.toString();
4207 }
4208 }
4209
4210 private static class Conversion {
4211 // Byte, Short, Integer, Long, BigInteger
4212 // (and associated primitives due to autoboxing)
4213 static final char DECIMAL_INTEGER = 'd';
4214 static final char OCTAL_INTEGER = 'o';
4215 static final char HEXADECIMAL_INTEGER = 'x';
4216 static final char HEXADECIMAL_INTEGER_UPPER = 'X';
4217
4218 // Float, Double, BigDecimal
4219 // (and associated primitives due to autoboxing)
4220 static final char SCIENTIFIC = 'e';
4221 static final char SCIENTIFIC_UPPER = 'E';
4222 static final char GENERAL = 'g';
4223 static final char GENERAL_UPPER = 'G';
4224 static final char DECIMAL_FLOAT = 'f';
4225 static final char HEXADECIMAL_FLOAT = 'a';
4226 static final char HEXADECIMAL_FLOAT_UPPER = 'A';
4227
4228 // Character, Byte, Short, Integer
4229 // (and associated primitives due to autoboxing)
4230 static final char CHARACTER = 'c';
4231 static final char CHARACTER_UPPER = 'C';
4232
4233 // java.util.Date, java.util.Calendar, long
4234 static final char DATE_TIME = 't';
4235 static final char DATE_TIME_UPPER = 'T';
4236
4237 // if (arg.TYPE != boolean) return boolean
4238 // if (arg != null) return true; else return false;
4239 static final char BOOLEAN = 'b';
4240 static final char BOOLEAN_UPPER = 'B';
4241 // if (arg instanceof Formattable) arg.formatTo()
4242 // else arg.toString();
4243 static final char STRING = 's';
4244 static final char STRING_UPPER = 'S';
4245 // arg.hashCode()
4246 static final char HASHCODE = 'h';
4247 static final char HASHCODE_UPPER = 'H';
4248
4249 static final char LINE_SEPARATOR = 'n';
4250 static final char PERCENT_SIGN = '%';
4251
4252 static boolean isValid(char c) {
4253 return (isGeneral(c) || isInteger(c) || isFloat(c) || isText(c)
4254 || c == 't' || isCharacter(c));
4255 }
4256
4257 // Returns true iff the Conversion is applicable to all objects.
4258 static boolean isGeneral(char c) {
4259 switch (c) {
4260 case BOOLEAN:
4261 case BOOLEAN_UPPER:
4262 case STRING:
4263 case STRING_UPPER:
4264 case HASHCODE:
4265 case HASHCODE_UPPER:
4266 return true;
4267 default:
4268 return false;
4269 }
4270 }
4271
4272 // Returns true iff the Conversion is applicable to character.
4273 static boolean isCharacter(char c) {
4274 switch (c) {
4275 case CHARACTER:
4276 case CHARACTER_UPPER:
4277 return true;
4278 default:
4279 return false;
4280 }
4281 }
4282
4283 // Returns true iff the Conversion is an integer type.
4284 static boolean isInteger(char c) {
4285 switch (c) {
4286 case DECIMAL_INTEGER:
4287 case OCTAL_INTEGER:
4288 case HEXADECIMAL_INTEGER:
4289 case HEXADECIMAL_INTEGER_UPPER:
4290 return true;
4291 default:
4292 return false;
4293 }
4294 }
4295
4296 // Returns true iff the Conversion is a floating-point type.
4297 static boolean isFloat(char c) {
4298 switch (c) {
4299 case SCIENTIFIC:
4300 case SCIENTIFIC_UPPER:
4301 case GENERAL:
4302 case GENERAL_UPPER:
4303 case DECIMAL_FLOAT:
4304 case HEXADECIMAL_FLOAT:
4305 case HEXADECIMAL_FLOAT_UPPER:
4306 return true;
4307 default:
4308 return false;
4309 }
4310 }
4311
4312 // Returns true iff the Conversion does not require an argument
4313 static boolean isText(char c) {
4314 switch (c) {
4315 case LINE_SEPARATOR:
4316 case PERCENT_SIGN:
4317 return true;
4318 default:
4319 return false;
4320 }
4321 }
4322 }
4323
4324 private static class DateTime {
4325 static final char HOUR_OF_DAY_0 = 'H'; // (00 - 23)
4326 static final char HOUR_0 = 'I'; // (01 - 12)
4327 static final char HOUR_OF_DAY = 'k'; // (0 - 23) -- like H
4328 static final char HOUR = 'l'; // (1 - 12) -- like I
4329 static final char MINUTE = 'M'; // (00 - 59)
4330 static final char NANOSECOND = 'N'; // (000000000 - 999999999)
4331 static final char MILLISECOND = 'L'; // jdk, not in gnu (000 - 999)
4332 static final char MILLISECOND_SINCE_EPOCH = 'Q'; // (0 - 99...?)
4333 static final char AM_PM = 'p'; // (am or pm)
4334 static final char SECONDS_SINCE_EPOCH = 's'; // (0 - 99...?)
4335 static final char SECOND = 'S'; // (00 - 60 - leap second)
4336 static final char TIME = 'T'; // (24 hour hh:mm:ss)
4337 static final char ZONE_NUMERIC = 'z'; // (-1200 - +1200) - ls minus?
4338 static final char ZONE = 'Z'; // (symbol)
4339
4340 // Date
4341 static final char NAME_OF_DAY_ABBREV = 'a'; // 'a'
4342 static final char NAME_OF_DAY = 'A'; // 'A'
4343 static final char NAME_OF_MONTH_ABBREV = 'b'; // 'b'
4344 static final char NAME_OF_MONTH = 'B'; // 'B'
4345 static final char CENTURY = 'C'; // (00 - 99)
4346 static final char DAY_OF_MONTH_0 = 'd'; // (01 - 31)
4347 static final char DAY_OF_MONTH = 'e'; // (1 - 31) -- like d
4348// * static final char ISO_WEEK_OF_YEAR_2 = 'g'; // cross %y %V
4349// * static final char ISO_WEEK_OF_YEAR_4 = 'G'; // cross %Y %V
4350 static final char NAME_OF_MONTH_ABBREV_X = 'h'; // -- same b
4351 static final char DAY_OF_YEAR = 'j'; // (001 - 366)
4352 static final char MONTH = 'm'; // (01 - 12)
4353// * static final char DAY_OF_WEEK_1 = 'u'; // (1 - 7) Monday
4354// * static final char WEEK_OF_YEAR_SUNDAY = 'U'; // (0 - 53) Sunday+
4355// * static final char WEEK_OF_YEAR_MONDAY_01 = 'V'; // (01 - 53) Monday+
4356// * static final char DAY_OF_WEEK_0 = 'w'; // (0 - 6) Sunday
4357// * static final char WEEK_OF_YEAR_MONDAY = 'W'; // (00 - 53) Monday
4358 static final char YEAR_2 = 'y'; // (00 - 99)
4359 static final char YEAR_4 = 'Y'; // (0000 - 9999)
4360
4361 // Composites
4362 static final char TIME_12_HOUR = 'r'; // (hh:mm:ss [AP]M)
4363 static final char TIME_24_HOUR = 'R'; // (hh:mm same as %H:%M)
4364// * static final char LOCALE_TIME = 'X'; // (%H:%M:%S) - parse format?
4365 static final char DATE_TIME = 'c';
4366 // (Sat Nov 04 12:02:33 EST 1999)
4367 static final char DATE = 'D'; // (mm/dd/yy)
4368 static final char ISO_STANDARD_DATE = 'F'; // (%Y-%m-%d)
4369// * static final char LOCALE_DATE = 'x'; // (mm/dd/yy)
4370
4371 static boolean isValid(char c) {
4372 switch (c) {
4373 case HOUR_OF_DAY_0:
4374 case HOUR_0:
4375 case HOUR_OF_DAY:
4376 case HOUR:
4377 case MINUTE:
4378 case NANOSECOND:
4379 case MILLISECOND:
4380 case MILLISECOND_SINCE_EPOCH:
4381 case AM_PM:
4382 case SECONDS_SINCE_EPOCH:
4383 case SECOND:
4384 case TIME:
4385 case ZONE_NUMERIC:
4386 case ZONE:
4387
4388 // Date
4389 case NAME_OF_DAY_ABBREV:
4390 case NAME_OF_DAY:
4391 case NAME_OF_MONTH_ABBREV:
4392 case NAME_OF_MONTH:
4393 case CENTURY:
4394 case DAY_OF_MONTH_0:
4395 case DAY_OF_MONTH:
4396// * case ISO_WEEK_OF_YEAR_2:
4397// * case ISO_WEEK_OF_YEAR_4:
4398 case NAME_OF_MONTH_ABBREV_X:
4399 case DAY_OF_YEAR:
4400 case MONTH:
4401// * case DAY_OF_WEEK_1:
4402// * case WEEK_OF_YEAR_SUNDAY:
4403// * case WEEK_OF_YEAR_MONDAY_01:
4404// * case DAY_OF_WEEK_0:
4405// * case WEEK_OF_YEAR_MONDAY:
4406 case YEAR_2:
4407 case YEAR_4:
4408
4409 // Composites
4410 case TIME_12_HOUR:
4411 case TIME_24_HOUR:
4412// * case LOCALE_TIME:
4413 case DATE_TIME:
4414 case DATE:
4415 case ISO_STANDARD_DATE:
4416// * case LOCALE_DATE:
4417 return true;
4418 default:
4419 return false;
4420 }
4421 }
4422 }
4423}