I'm using
MessageFormat.format("Hello {0}", "World"));
Now I want to use LocalDate
or LocalDateTime
as parameters but as far as I can see MessageFormat.format
doesn't support java.time
!
So I have to use
MessageFormat.format("Today is {0,date}",
Date.from(LocalDate.now().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
This is terrible!
Is there a better way to use MessageFormat
with java.time
? Or are there better solutions to replace placeholders in a text that considers Locale configuration?
Update
I'm aware of how to format LocalDate and LocalDateTime but I have the requirement to format a message with various types.
Example
MessageFormat.format("Today is {0,date} {1,number} {2}", aDate, aNumber, aString);
Where is the replacement for MessageFormat
with java.time
Types?
The following example creates a MessageFormat instance that can be used repeatedly: int fileCount = 1273; String diskName = "MyDisk"; Object[] testArgs = {new Long(fileCount), diskName}; MessageFormat form = new MessageFormat( "The disk \"{1}\" contains {0} file(s). "); System.
As written, dateSentFormatted can't be null: you're setting it to the return from timeFormatted() , which returns a LocalDateTime , which is not nullable.
LocalDate is an immutable class that represents Date with default format of yyyy-MM-dd.
A date without a time-zone in the ISO-8601 calendar system, such as 2007-12-03 . LocalDate is an immutable date-time object that represents a date, often viewed as year-month-day.
LocalDate format () method in Java Last Updated : 28 Nov, 2018 The format () method of LocalDate class in Java method formats this date using the specified formatter.
To format message with date in Java, we use the MessageFormat class and the Date class. The MessageFormat class gives us a way to produce concatenated messages which are not dependent on the language. The MessageFormat class extends the Serializable and Cloneable interfaces.
The MessageFormat is designed to work with java.text.Format classes, so it uses DateFormat / SimpleDateFormat to format date/time. Providing support for java.time.format.DateTimeFormatter to format java.time types ( TemporalAccessors) may complicate the MessageFormat API.
Exceptions: The function throws only DateTimeException which occurs during an error in printing. Return Value: It returns the formatted date string and not null. Below programs illustrate the format () method of LocalDate in Java: Program 2: To illustrate the exception.
There had been an issue opened for this, which was resolved as "won't fix". The reason is that:
The
MessageFormat
is designed to work withjava.text.Format
classes, so it usesDateFormat
/SimpleDateFormat
to format date/time. Providing support forjava.time.format.DateTimeFormatter
to formatjava.time
types (TemporalAccessors
) may complicate theMessageFormat
API. It is always recommended to usejava.util.Formatter
which provides support for formattingjava.time
types.
So you should use Formatter
instead:
StringBuilder sb = new StringBuilder();
Formatter formatter = new Formatter(sb, Locale.US);
int someNumber = 10;
String someString = "Hello";
formatter.format("Today is %tD and someNumber is %d %s", LocalDate.now(), someNumber, someString);
System.out.println(sb);
// prints "Today is 03/30/21 and someNumber is 10 Hello"
This works with any kind of TemporalAccessor
.
MessageFormat allows to create and set up a custom format for any argument.
val randomDate = LocalDate.EPOCH.plusDays(random.nextInt(20_000));
val fmt = new MessageFormat("Today is {0}");
fmt.setFormat(0, new SummaryDateFormat());
val out = fmt.format(new Object[]{randomDate});
System.out.println(out);
Here is a sample implementation of your custom format:
public class SummaryDateFormat extends Format {
@Override
public StringBuffer format(final Object obj, final StringBuffer toAppendTo, final FieldPosition pos) {
toAppendTo.append(String.format("%tA, %<tB %<te", obj));
return toAppendTo;
}
@Override
public Object parseObject(final String source, final ParsePosition pos) {
return null;
}
}
I finally found a bug report about supporting java.time
in MessageFormat
.
https://bugs.openjdk.java.net/browse/JDK-8254654
Until this is solved I will go with the suggested workaround and convert LocalDate
etc. to java.util.Date
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With