Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java MessageFormat and LocalDate

Tags:

java

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?

like image 758
Simon Martinelli Avatar asked Mar 30 '21 11:03

Simon Martinelli


People also ask

How to use MessageFormat format in Java?

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.

Can local date be null?

As written, dateSentFormatted can't be null: you're setting it to the return from timeFormatted() , which returns a LocalDateTime , which is not nullable.

What is LocalDate format in Java?

LocalDate is an immutable class that represents Date with default format of yyyy-MM-dd.

Does Java LocalDate have time?

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.

What is localdate format () method in Java?

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.

How to format message with date in Java?

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.

What format does MessageFormat use in Java?

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.

What is the return value of localdate in Java?

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.


Video Answer


3 Answers

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 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. It is always recommended to use java.util.Formatter which provides support for formatting java.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.

like image 99
Sweeper Avatar answered Oct 21 '22 09:10

Sweeper


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;
    }
}
like image 4
Jegors Čemisovs Avatar answered Oct 21 '22 11:10

Jegors Čemisovs


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

like image 3
Simon Martinelli Avatar answered Oct 21 '22 11:10

Simon Martinelli