src/share/classes/java/util/Formatter.java

Print this page


   1 /*
   2  * Copyright (c) 2003, 2012, Oracle and/or its affiliates. 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


2790         private void printDateTime(Object arg, Locale l) throws IOException {
2791             if (arg == null) {
2792                 print("null");
2793                 return;
2794             }
2795             Calendar cal = null;
2796 
2797             // Instead of Calendar.setLenient(true), perhaps we should
2798             // wrap the IllegalArgumentException that might be thrown?
2799             if (arg instanceof Long) {
2800                 // Note that the following method uses an instance of the
2801                 // default time zone (TimeZone.getDefaultRef().
2802                 cal = Calendar.getInstance(l == null ? Locale.US : l);
2803                 cal.setTimeInMillis((Long)arg);
2804             } else if (arg instanceof Date) {
2805                 // Note that the following method uses an instance of the
2806                 // default time zone (TimeZone.getDefaultRef().
2807                 cal = Calendar.getInstance(l == null ? Locale.US : l);
2808                 cal.setTime((Date)arg);
2809             } else if (arg instanceof Calendar) {
2810                 cal = (Calendar) ((Calendar)arg).clone();
2811                 cal.setLenient(true);
2812             } else if (arg instanceof TemporalAccessor) {
2813                 print((TemporalAccessor)arg, c, l);
2814                 return;
2815             } else {
2816                 failConversion(c, arg);
2817             }
2818             // Use the provided locale so that invocations of
2819             // localizedMagnitude() use optimizations for null.
2820             print(cal, c, l);
2821         }
2822 
2823         private void printCharacter(Object arg) throws IOException {
2824             if (arg == null) {
2825                 print("null");
2826                 return;
2827             }
2828             String s = null;
2829             if (arg instanceof Character) {
2830                 s = ((Character)arg).toString();
2831             } else if (arg instanceof Byte) {
2832                 byte i = ((Byte)arg).byteValue();
2833                 if (Character.isValidCodePoint(i))


3225                 trailingSign(sb, neg);
3226             } else {
3227                 sb.append(f.contains(Flags.UPPERCASE) ? "NAN" : "NaN");
3228             }
3229 
3230             // justify based on width
3231             a.append(justify(sb.toString()));
3232         }
3233 
3234         // !Double.isInfinite(value) && !Double.isNaN(value)
3235         private void print(StringBuilder sb, double value, Locale l,
3236                            Flags f, char c, int precision, boolean neg)
3237             throws IOException
3238         {
3239             if (c == Conversion.SCIENTIFIC) {
3240                 // Create a new FormattedFloatingDecimal with the desired
3241                 // precision.
3242                 int prec = (precision == -1 ? 6 : precision);
3243 
3244                 FormattedFloatingDecimal fd
3245                     = new FormattedFloatingDecimal(value, prec,
3246                         FormattedFloatingDecimal.Form.SCIENTIFIC);
3247 
3248                 char[] v = new char[MAX_FD_CHARS];
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                 char[] exp = (value == 0.0)
3259                     ? new char[] {'+','0','0'} : exponent(v, len);
3260 
3261                 int newW = width;
3262                 if (width != -1)
3263                     newW = adjustWidth(width - exp.length - 1, f, neg);
3264                 localizedMagnitude(sb, mant, f, newW, l);
3265 
3266                 sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e');
3267 
3268                 Flags flags = f.dup().remove(Flags.GROUP);
3269                 char sign = exp[0];
3270                 assert(sign == '+' || sign == '-');
3271                 sb.append(sign);
3272 
3273                 char[] tmp = new char[exp.length - 1];
3274                 System.arraycopy(exp, 1, tmp, 0, exp.length - 1);
3275                 sb.append(localizedMagnitude(null, tmp, flags, -1, l));
3276             } else if (c == Conversion.DECIMAL_FLOAT) {
3277                 // Create a new FormattedFloatingDecimal with the desired
3278                 // precision.
3279                 int prec = (precision == -1 ? 6 : precision);
3280 
3281                 FormattedFloatingDecimal fd
3282                     = new FormattedFloatingDecimal(value, prec,
3283                         FormattedFloatingDecimal.Form.DECIMAL_FLOAT);
3284 
3285                 // MAX_FD_CHARS + 1 (round?)
3286                 char[] v = new char[MAX_FD_CHARS + 1
3287                                    + Math.abs(fd.getExponent())];
3288                 int len = fd.getChars(v);
3289 
3290                 char[] mant = addZeros(mantissa(v, len), prec);
3291 
3292                 // If the precision is zero and the '#' flag is set, add the
3293                 // requested decimal point.
3294                 if (f.contains(Flags.ALTERNATE) && (prec == 0))
3295                     mant = addDot(mant);
3296 
3297                 int newW = width;
3298                 if (width != -1)
3299                     newW = adjustWidth(width, f, neg);
3300                 localizedMagnitude(sb, mant, f, newW, l);
3301             } else if (c == Conversion.GENERAL) {
3302                 int prec = precision;
3303                 if (precision == -1)
3304                     prec = 6;
3305                 else if (precision == 0)
3306                     prec = 1;
3307 
3308                 FormattedFloatingDecimal fd
3309                     = new FormattedFloatingDecimal(value, prec,
3310                         FormattedFloatingDecimal.Form.GENERAL);
3311 
3312                 // MAX_FD_CHARS + 1 (round?)
3313                 char[] v = new char[MAX_FD_CHARS + 1
3314                                    + Math.abs(fd.getExponent())];
3315                 int len = fd.getChars(v);
3316 
3317                 char[] exp = exponent(v, len);
3318                 if (exp != null) {
3319                     prec -= 1;
3320                 } else {
3321                     prec = prec - (value == 0 ? 0 : fd.getExponentRounded()) - 1;
3322                 }
3323 
3324                 char[] mant = addZeros(mantissa(v, len), prec);
3325                 // If the precision is zero and the '#' flag is set, add the
3326                 // requested decimal point.
3327                 if (f.contains(Flags.ALTERNATE) && (prec == 0))
3328                     mant = addDot(mant);
3329 
3330                 int newW = width;
3331                 if (width != -1) {
3332                     if (exp != null)
3333                         newW = adjustWidth(width - exp.length - 1, f, neg);
3334                     else
3335                         newW = adjustWidth(width, f, neg);
3336                 }
3337                 localizedMagnitude(sb, mant, f, newW, l);
3338 
3339                 if (exp != null) {
3340                     sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e');
3341 
3342                     Flags flags = f.dup().remove(Flags.GROUP);
3343                     char sign = exp[0];
3344                     assert(sign == '+' || sign == '-');


3363                 sb.append(upper ? "0X" : "0x");
3364 
3365                 if (f.contains(Flags.ZERO_PAD))
3366                     for (int i = 0; i < width - s.length() - 2; i++)
3367                         sb.append('0');
3368 
3369                 int idx = s.indexOf('p');
3370                 va = s.substring(0, idx).toCharArray();
3371                 if (upper) {
3372                     String tmp = new String(va);
3373                     // don't localize hex
3374                     tmp = tmp.toUpperCase(Locale.US);
3375                     va = tmp.toCharArray();
3376                 }
3377                 sb.append(prec != 0 ? addZeros(va, prec) : va);
3378                 sb.append(upper ? 'P' : 'p');
3379                 sb.append(s.substring(idx+1));
3380             }
3381         }
3382 
3383         private char[] mantissa(char[] v, int len) {
3384             int i;
3385             for (i = 0; i < len; i++) {
3386                 if (v[i] == 'e')
3387                     break;
3388             }
3389             char[] tmp = new char[i];
3390             System.arraycopy(v, 0, tmp, 0, i);
3391             return tmp;
3392         }
3393 
3394         private char[] exponent(char[] v, int len) {
3395             int i;
3396             for (i = len - 1; i >= 0; i--) {
3397                 if (v[i] == 'e')
3398                     break;
3399             }
3400             if (i == -1)
3401                 return null;
3402             char[] tmp = new char[len - i - 1];
3403             System.arraycopy(v, i + 1, tmp, 0, len - i - 1);
3404             return tmp;
3405         }
3406 
3407         // Add zeros to the requested precision.
3408         private char[] addZeros(char[] v, int prec) {
3409             // Look for the dot.  If we don't find one, the we'll need to add
3410             // it before we add the zeros.
3411             int i;
3412             for (i = 0; i < v.length; i++) {
3413                 if (v[i] == '.')
3414                     break;
3415             }
3416             boolean needDot = false;
3417             if (i == v.length) {
3418                 needDot = true;
3419             }
3420 
3421             // Determine existing precision.
3422             int outPrec = v.length - i - (needDot ? 0 : 1);
3423             assert (outPrec <= prec);
3424             if (outPrec == prec)
3425                 return v;
3426 


   1 /*
   2  * Copyright (c) 2003, 2013, Oracle and/or its affiliates. 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


2790         private void printDateTime(Object arg, Locale l) throws IOException {
2791             if (arg == null) {
2792                 print("null");
2793                 return;
2794             }
2795             Calendar cal = null;
2796 
2797             // Instead of Calendar.setLenient(true), perhaps we should
2798             // wrap the IllegalArgumentException that might be thrown?
2799             if (arg instanceof Long) {
2800                 // Note that the following method uses an instance of the
2801                 // default time zone (TimeZone.getDefaultRef().
2802                 cal = Calendar.getInstance(l == null ? Locale.US : l);
2803                 cal.setTimeInMillis((Long)arg);
2804             } else if (arg instanceof Date) {
2805                 // Note that the following method uses an instance of the
2806                 // default time zone (TimeZone.getDefaultRef().
2807                 cal = Calendar.getInstance(l == null ? Locale.US : l);
2808                 cal.setTime((Date)arg);
2809             } else if (arg instanceof Calendar) {
2810                 cal = (Calendar) ((Calendar) arg).clone();
2811                 cal.setLenient(true);
2812             } else if (arg instanceof TemporalAccessor) {
2813                 print((TemporalAccessor) arg, c, l);
2814                 return;
2815             } else {
2816                 failConversion(c, arg);
2817             }
2818             // Use the provided locale so that invocations of
2819             // localizedMagnitude() use optimizations for null.
2820             print(cal, c, l);
2821         }
2822 
2823         private void printCharacter(Object arg) throws IOException {
2824             if (arg == null) {
2825                 print("null");
2826                 return;
2827             }
2828             String s = null;
2829             if (arg instanceof Character) {
2830                 s = ((Character)arg).toString();
2831             } else if (arg instanceof Byte) {
2832                 byte i = ((Byte)arg).byteValue();
2833                 if (Character.isValidCodePoint(i))


3225                 trailingSign(sb, neg);
3226             } else {
3227                 sb.append(f.contains(Flags.UPPERCASE) ? "NAN" : "NaN");
3228             }
3229 
3230             // justify based on width
3231             a.append(justify(sb.toString()));
3232         }
3233 
3234         // !Double.isInfinite(value) && !Double.isNaN(value)
3235         private void print(StringBuilder sb, double value, Locale l,
3236                            Flags f, char c, int precision, boolean neg)
3237             throws IOException
3238         {
3239             if (c == Conversion.SCIENTIFIC) {
3240                 // Create a new FormattedFloatingDecimal with the desired
3241                 // precision.
3242                 int prec = (precision == -1 ? 6 : precision);
3243 
3244                 FormattedFloatingDecimal fd
3245                         = FormattedFloatingDecimal.valueOf(value, prec,
3246                           FormattedFloatingDecimal.Form.SCIENTIFIC);
3247 
3248                 char[] mant = addZeros(fd.getMantissa(), prec);



3249 
3250                 // If the precision is zero and the '#' flag is set, add the
3251                 // requested decimal point.
3252                 if (f.contains(Flags.ALTERNATE) && (prec == 0))
3253                     mant = addDot(mant);
3254 
3255                 char[] exp = (value == 0.0)
3256                     ? new char[] {'+','0','0'} : fd.getExponent();
3257 
3258                 int newW = width;
3259                 if (width != -1)
3260                     newW = adjustWidth(width - exp.length - 1, f, neg);
3261                 localizedMagnitude(sb, mant, f, newW, l);
3262 
3263                 sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e');
3264 
3265                 Flags flags = f.dup().remove(Flags.GROUP);
3266                 char sign = exp[0];
3267                 assert(sign == '+' || sign == '-');
3268                 sb.append(sign);
3269 
3270                 char[] tmp = new char[exp.length - 1];
3271                 System.arraycopy(exp, 1, tmp, 0, exp.length - 1);
3272                 sb.append(localizedMagnitude(null, tmp, flags, -1, l));
3273             } else if (c == Conversion.DECIMAL_FLOAT) {
3274                 // Create a new FormattedFloatingDecimal with the desired
3275                 // precision.
3276                 int prec = (precision == -1 ? 6 : precision);
3277 
3278                 FormattedFloatingDecimal fd
3279                         = FormattedFloatingDecimal.valueOf(value, prec,
3280                           FormattedFloatingDecimal.Form.DECIMAL_FLOAT);
3281 
3282                 char[] mant = addZeros(fd.getMantissa(), prec);





3283 
3284                 // If the precision is zero and the '#' flag is set, add the
3285                 // requested decimal point.
3286                 if (f.contains(Flags.ALTERNATE) && (prec == 0))
3287                     mant = addDot(mant);
3288 
3289                 int newW = width;
3290                 if (width != -1)
3291                     newW = adjustWidth(width, f, neg);
3292                 localizedMagnitude(sb, mant, f, newW, l);
3293             } else if (c == Conversion.GENERAL) {
3294                 int prec = precision;
3295                 if (precision == -1)
3296                     prec = 6;
3297                 else if (precision == 0)
3298                     prec = 1;
3299 
3300                 FormattedFloatingDecimal fd
3301                         = FormattedFloatingDecimal.valueOf(value, prec,
3302                           FormattedFloatingDecimal.Form.GENERAL);
3303 
3304                 char[] exp = fd.getExponent();





3305                 if (exp != null) {
3306                     prec -= 1;
3307                 } else {
3308                     prec = prec - (value == 0 ? 0 : fd.getExponentRounded()) - 1;
3309                 }
3310 
3311                 char[] mant = addZeros(fd.getMantissa(), prec);
3312                 // If the precision is zero and the '#' flag is set, add the
3313                 // requested decimal point.
3314                 if (f.contains(Flags.ALTERNATE) && (prec == 0))
3315                     mant = addDot(mant);
3316 
3317                 int newW = width;
3318                 if (width != -1) {
3319                     if (exp != null)
3320                         newW = adjustWidth(width - exp.length - 1, f, neg);
3321                     else
3322                         newW = adjustWidth(width, f, neg);
3323                 }
3324                 localizedMagnitude(sb, mant, f, newW, l);
3325 
3326                 if (exp != null) {
3327                     sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e');
3328 
3329                     Flags flags = f.dup().remove(Flags.GROUP);
3330                     char sign = exp[0];
3331                     assert(sign == '+' || sign == '-');


3350                 sb.append(upper ? "0X" : "0x");
3351 
3352                 if (f.contains(Flags.ZERO_PAD))
3353                     for (int i = 0; i < width - s.length() - 2; i++)
3354                         sb.append('0');
3355 
3356                 int idx = s.indexOf('p');
3357                 va = s.substring(0, idx).toCharArray();
3358                 if (upper) {
3359                     String tmp = new String(va);
3360                     // don't localize hex
3361                     tmp = tmp.toUpperCase(Locale.US);
3362                     va = tmp.toCharArray();
3363                 }
3364                 sb.append(prec != 0 ? addZeros(va, prec) : va);
3365                 sb.append(upper ? 'P' : 'p');
3366                 sb.append(s.substring(idx+1));
3367             }
3368         }
3369 
























3370         // Add zeros to the requested precision.
3371         private char[] addZeros(char[] v, int prec) {
3372             // Look for the dot.  If we don't find one, the we'll need to add
3373             // it before we add the zeros.
3374             int i;
3375             for (i = 0; i < v.length; i++) {
3376                 if (v[i] == '.')
3377                     break;
3378             }
3379             boolean needDot = false;
3380             if (i == v.length) {
3381                 needDot = true;
3382             }
3383 
3384             // Determine existing precision.
3385             int outPrec = v.length - i - (needDot ? 0 : 1);
3386             assert (outPrec <= prec);
3387             if (outPrec == prec)
3388                 return v;
3389