Localized Date Time Formats in Java

Starting with JDK 8, we have a comprehensive date-time API containing classes such as LocalDate, LocalTime, LocalDateTime, ZonedDateTime, OffsetDateTime, and OffsetTime. These classes allow easy formatting of the date-time output via DateTimeFormatter.ofPattern(). The API also allows further customize the output based on specified Locale information to support localization and internationalization features.

In this tutorial, we will learn to display the date and time information to the end-user in a location-sensitive manner, based on the user’s timezone. We will show the zone-specific dates in the default locale as well as the custom locales.

1. Display Locale-formatted Date and Time

To display information in a locale-sensitive manner, we must follow these steps:

  • Get the current locale of the user. If locale information is not represented, use a default locale.
  • Use the locale information to build the DateTimeFormatter object.
  • Use DateTimeFormatter.format() to locale-specific date-time outputs.
Locale locale = Locale.forLanguageTag("es");

DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).withLocale(locale);

String formattedDate = formatter.format( ZonedDateTime.now() );
System.out.println(formattedDate);  // Prints '14 ene 2024, 8:09:47'

It is important to understand the Locale specific formatting changes only the display structure and language of the information, it does not modify the date and time values according to the timezone offsets.

We can utilize the ofLocalizedDate(),ofLocalizedTime(), and ofLocalizedDateTime() methods to get the specific date-time parts formatted with Locale rules.

Locale.setDefault(Locale.GERMANY);

String ld = LocalDate.now().format(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG));
System.out.println(ld);  // 14. Januar 2024

String lt = LocalTime.now().format(DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT));
System.out.println(lt);  // 08:14

String ldt = LocalDateTime.now().format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM));
System.out.println(ldt);  // 14.01.2024, 08:14:25

2. Getting the User Locale

Note that fetching the current locale information varies from application to application and framework to framework.

For example, we can use the AcceptHeaderLocaleResolver in a Spring web application that uses the primary locale specified in the “Accept-language” header of the HTTP request (the locale sent by the client browser, usually that of the client’s OS).

@Bean
public LocalResolver localeResolver() {

    AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
    localeResolver.setSupportedLocales(Arrays.asList(new Locale("fa"), new Locale("en")));
    localeResolver.setDefaultLocale(new Locale("fa"));
    return localeResolver;
}

To get the locale-specific language tag, use the LocaleContextHolder.getLocale() method call.

3. Using ofLocalizedPattern() since Java 19

Starting with JDK 19, we can use ofLocalizedPattern(String pattern) method to create a locale-specific DateTimeFormatter derived from the specified template. We can pass any pattern that respects the ISO chronology specified below:

"G{0,5}" +        // Era
"y*" +            // Year
"Q{0,5}" +        // Quarter
"M{0,5}" +        // Month
"w*" +            // Week of Week Based Year
"E{0,5}" +        // Day of Week
"d{0,2}" +        // Day of Month
"B{0,5}" +        // Period/AmPm of Day
"[hHjC]{0,2}" +   // Hour of Day/AmPm (refer to LDML for 'j' and 'C')
"m{0,2}" +        // Minute of Hour
"s{0,2}" +        // Second of Minute
"[vz]{0,4}"       // Zone

In the given example, we are displaying localized date-time information for the English locale:

Locale.setDefault(Locale.ENGLISH);

String ld1 = LocalDate.now().format(DateTimeFormatter.ofLocalizedPattern("yMM"));
System.out.println(ld1);  // 1/2024

String ld2 = LocalDate.now().format(DateTimeFormatter.ofLocalizedPattern("yMMM"));
System.out.println(ld2);  // Jan 2024

4. Conclusion

This short tutorial taught us to display the date and time information based on the user locale. As mentioned earlier, locale-based formatting only changes the information display and does not modify the date-time values based on the timezone rules.

If you wish to change the date and time values as well for a given timezone then use DateTimeFormatter.withZone(zoneId).

Happy Learning !!

Source Code On Github

Comments

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode