Java String Formatting
Printing or producing a simple String
message has been really trivial in Java. Most of the time, we use concatenation to create String
instance we want:
1 | int a = 3; |
Though modern Java compiler uses StringBuilder
to optimize statements like these, using concatention to construct String
has its limitations, which include:
- The pattern of the
String
is not reusable; - The statements can be unacceptably long if we try to construct a complicated message;
- It is impossible to designate the precision of a floating point number.
Fortunately, Java SE 5.0 brought back the venerable printf
method from the C library, which also come with the basic feature of string formatting.
Elements of Formatting Patterns
printf
method in Java is much like its counterpart in C. For example, the call
1 | System.out.pinrlnt("%8.2f", x); |
prints x
with a field width of 8 characters and a precision of 2 characters.
You can supply multiple parameters to printf
. For example:
1 | System.out.printf("Hello, %s. Next year, you'll be %d.", name, age); |
The formatting patterns is written in a String
constant, where format specifiers that start with a %
character is replaced with the corresponding argument. A format specifier is composed of flag and/or conversion character. Flags are used to control the apperance of the formatted string, while the conversion character that ends a format specifier indicates the type of the value to be formatted: f
is a floating-point number, s
a string, and d
a decimal integer.
Conversion Character | Type | Example |
---|---|---|
d |
Decimal integer | 159 |
x |
Hexadecimal integer | 9f |
o |
Octal integer | 237 |
f |
Fixed-point floating-point | 15.9 |
e |
Exponential floating-point | 1.59e+01 |
g |
Genral floating-point (the shorter of e and f ) |
|
a |
Hexadecimal floating-point | 0x1.fccdp3 |
s |
String | Hello |
c |
Character | H |
b |
boolean |
true |
h |
Hash code | 42628b2 |
% |
The percent symbol | |
n |
The platform-dependent line seperator |
| Flag | Purpose | Example |
| +
| Prints sign for positive and negative numbers. | +3333.33
|
| space | Adds a space before positive numbers. | | 3333.33|
|
| 0
| Adds leading zeroes. | 003333.33
|
| -
| Left-justifies field. | |3333.33 |
|
| (
| Encloses negative numbers in parentheses. | (3333.33)
|
| ,
| Adds group separators. | 3,333.33
|
| #
(for f
format) | Always includes a decimal point. | 3,333.
|
| #
(for x
or o
format) | Adds 0x
or 0
prefix. | 0xcafe
|
| $
| Specifies the index of the argument to be formatted; for example,%1$d %1$x
prints the first argument in deximal and hexadecimal. | 159 9F
|
| <
| Formats the same value as the previous secification; for example,%d %<x
prints the same number in decimal and hexadecimal. | 159 9F
|
You can use the static String.format
method to create a formatted string without printing it:
1 | String message = String.format("Hello, %s. Next year, you'll be %d.", name, age); |
Conversion characters for Date
formatting are also available, which start with t
:
1 | System.out.printf("%tc", new Date()); |
Conversion Character | Type | Example |
---|---|---|
c |
Complete date and time | Mon Feb 09 18:05:19 PST 2004 |
F |
ISO 8601 date | 2004-02-09 |
D |
U.S. formatted date (month/day/year) | 02/09/2004 |
T |
24-hour time | 18:05:19 |
r |
12-hour time | 06:05:19 pm |
R |
24-hour time, no seconds | 18:05 |
Y |
Four-digit year (with leading zeroes) | 2004 |
y |
Last two digits of the year (with leading zeroes) | 04 |
C |
First two digits of the year (with leading zeroes) | 20 |
B |
Full month name | February |
b or h |
Abbreviated month name | Feb |
m |
Two-digit month (with leading zeroes) | 02 |
d |
Two-digit day (with leading zeroes) | 09 |
e |
Two-digit day (without leading zeroes) | 9 |
A |
Full weekday name | Monday |
a |
Abbreviated weekday name | Mon |
j |
Three-digit day of year (with leading zeroes), between 001 and 366 |
069 |
H |
Two-digit hour (with leading zeroes), between 00 and 23 |
18 |
k |
Two-digit hour (without leading zeroes), between 0 and 23 |
18 |
I |
Two-digit hour (with leading zeroes), between 01 and 12 |
06 |
l |
Two-digit hour (without leading zeroes), between 1 and 12 |
6 |
M |
Two-digit minutes (with leading zeroes) | 05 |
S |
Two-digit seconds (with leading zeroes) | 19 |
L |
Three-digit milliseconds (with leading zeroes) | 047 |
N |
Nine-digit nanoseconds (with leading zeroes) | 047000000 |
P |
Uppercase morning or afternoon marker | PM |
p |
Lowercase morning or afternoon marker | pm |
z |
RFC 822 numeric offset from GMT | -0800 |
Z |
Time zone | PST |
s |
Seconds since 1970-01-01 00:00:00 GMT |
1078884319 |
Q |
Milliseconds since 1970-01-01 00:00:00 GMT |
1078884319047 |
As you can see in the preceding table, some of the formates yield only a part of a given date – for example, just the day or just the month.
It would be a bit silly if you had to supply the day multiple times for format each part. For that reason, a format string can indicate
the index of the argument to be formatted. The index must immediately follow the %
, and it must be terminated by a $
. For example:
1 | System.out.println("%1$s %2$tB %2$te, %2$tY", "Due date:", new Date()); |
Alternatively, you can use the <
flag. It indicates that the same argument as in the preceding format specification should be used again.
That is, the statement
1 | System.out.println("%s %tB %<te, %<tY", "Due date:", new Date()); |
yields the same output as the preceding statement.
Java String Formatting