In the documentation of format
there is a link to the page "Format String Syntax", that describes all possible options. There we find this table:
Flag |
General |
Character |
Integral |
Floating Point |
Date/Time |
Description |
'-' |
y |
y |
y |
y |
y |
The result will be left-Justified |
'#' |
y |
- |
y |
y |
- |
The result should use a Conversion-dependent Alternate form |
'+' |
- |
- |
y |
y |
- |
The result will Always include a Sign |
' ' |
- |
- |
y |
y |
- |
The result will include a Leading space for Positive values |
'0' |
- |
- |
y |
y |
- |
The result will be zero-Padded |
',' |
- |
- |
y |
y |
- |
The result will include locale-specific grouping separators |
'(' |
- |
- |
y |
y |
- |
The result will enclose Negative Numbers in parentheses |
That is, to align to the left, just use the hyphen in the format: %-4.1f
instead of %4.1f
, for example. The problem is that it only formats the number, but you want to format also the measure drive together, then only that wouldn’t work:
String origin = "SGBR", destination = "BCO";
double estimatedTime = 9, distance = 5;
int verticalSpeed = 1400, estimatedFuel = 700;
String format = "%s -> %6s | %-4.1f m | %-5.1f NM | %-6d Ft/m | %-6d\n";
System.out.format(format, origin, destination, estimatedTime, distance, verticalSpeed, estimatedFuel);
The exit would be:
SGBR -> BCO | 9.0 m | 5.0 NM | 1400 Ft/m | 700
Notice that only the numbers were aligned to the left, so it was 5.0 NM
instead of 5.0 NM
and more spaces after it (note also that the decimal separator varies according to the default locale of the JVM, but we’ll get there).
Anyway, in your case, you do not want to format only the number, but the number followed by the unit of measure, and already formatted with the comma separating the decimal places. That is, you want to format a left-aligned string (this string is formed by a number plus the unit of measure).
So I suggest first formatting the numbers along with the measure drive, generating the respective strings, and then formatting these strings by aligning left.
Something like that:
// junta o número com a unidade de medida
// o locale é para controlar o separador decimal
static String formataNumero(double valor, String unidade, int casasDecimais, Locale locale) {
if (unidade.isEmpty()) { // sem unidade, formata só o número
return String.format(locale, "%." + casasDecimais + "f", valor);
}
// com unidade, junta com o número
return String.format(locale, "%." + casasDecimais + "f %s", valor, unidade);
}
public static void main(String[] args) {
String origin = "SGBR", destination = "BCO";
double estimatedTime = 9, distance = 5;
int verticalSpeed = 1400, estimatedFuel = 700;
Locale locale = new Locale("pt", "BR"); // para usar a vírgula como separador decimal
String format = "%-4s -> %-6s| %-9s | %-8s | %-9s | %s\n";
System.out.format(format, origin, destination,
formataNumero(estimatedTime, "m", 1, locale),
formataNumero(distance, "NM", 1, locale),
formataNumero(verticalSpeed, "Ft/m", 0, locale), // inteiros usam zero casas decimais
formataNumero(estimatedFuel, "", 0, locale));
}
I used a Locale
for the decimal separator to be the comma (I used "en-BR", which is equivalent to Brazilian Portuguese). If you do not specify one, it will use the default locale which is configured in the JVM, and may not always be what you need (for example, if it is English, the separator will be the point). In addition, the default locale may be amended in Runtime by any application running on the same JVM, and you don’t have much control over it. So it’s best to use a locale specific.
So, I just need to format strings. I adjusted the sizes to match your desired output:
SGBR -> BCO | 9,0 m | 5,0 NM | 1400 Ft/m | 700
But then you can adjust to whatever you need. Note that the last number does not need to be aligned to the left, as there is nothing after it. If you used something like %-6s
, there would be some blanks at the end, but since it’s the last line information, I didn’t think it was necessary.