I'd like to format a Period
using a pattern like YY years, MM months, DD days
. The utilities in Java 8 are designed to format time but neither period, nor duration. There's a PeriodFormatter
in Joda time. Does Java have similar utilities?
How to format a Period in Java 8 / jsr310?
Asked Answered
No, java.time does not have a similar capability. –
Hemminger
#267325 –
Brenneman
One solution is to simply use String.format
:
import java.time.Period;
Period p = Period.of(2,5,1);
String.format("%d years, %d months, %d days", p.getYears(), p.getMonths(), p.getDays());
If your really need to use the features of DateTimeFormatter
, you can use a temporary LocalDate
, but this is a kind of hack that distort the semantic of LocalDate
.
import java.time.Period;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
Period p = Period.of(2,5,1);
DateTimeFormatter fomatter = DateTimeFormatter.ofPattern("y 'years,' M 'months,' d 'days'");
LocalDate.of(p.getYears(), p.getMonths(), p.getDays()).format(fomatter);
I don’t like seeing
LocalDate
used as a hack. Why not do the same placeholder with value replacement approach using the String facilities in Java? –
Marthmartha I agree that distorting the semantic of
LocalDate
is not elegant and could lead to problems. –
Pleader @BasilBourque I agree in general, but it seems to me that it's a workaround for a weakness in the JDK Api, which should allow the
DateTimeFormatter
to accept any TemporalAmount
. –
Ansermet The problem with this (that Joda solves) is that your string is not localized. –
Accountancy
There's no need to use String.format()
for simple string formatting. Using plain old string concatenation will be optimized by JVM:
Function<Period, String> format = p -> p.getYears() + " years, " + p.getMonths() + " months, " + p.getDays() + " days";
Only wondering what would be wrong with a plain old method declaration in this case? –
Hemminger
Personally, I think the
String.format()
version is easier to read in this case. –
Saccharo public static final String format(Period period){
if (period == Period.ZERO) {
return "0 days";
} else {
StringBuilder buf = new StringBuilder();
if (period.getYears() != 0) {
buf.append(period.getYears()).append(" years");
if(period.getMonths()!= 0 || period.getDays() != 0) {
buf.append(", ");
}
}
if (period.getMonths() != 0) {
buf.append(period.getMonths()).append(" months");
if(period.getDays()!= 0) {
buf.append(", ");
}
}
if (period.getDays() != 0) {
buf.append(period.getDays()).append(" days");
}
return buf.toString();
}
}
the proper way seems to be an intermediate LocalDate object and then calling format
date1.format(DateTimeFormatter.ofPattern("uuuu MM LLLL ee ccc"));
OR (where appropriate)
date1.format(DateTimeFormatter.ofPattern("uuuu MM LLLL ee ccc", Locale.CHINA))
this prints 1997 01 一月 07 周六
in chinese, 1997 01 January 01 Sun
in english and 1997 01 januari 07 zo
in dutch.
check out https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html under "Patterns for Formatting and Parsing" for your desired formatting.
© 2022 - 2025 — McMap. All rights reserved.