In my previous article, we looked at different ways to convert a string to a date using Java 8 new date and time API as well as legacy Date and Calendar API.

In this article, you'll learn to change the format of a given date or a string to a new string format using both Java 8 new date and time API and legacy java.util.Date API.

There are many scenarios where you want to convert an instance of date to a more human-readable format.

For instance, you may have a date like 12/23/2019T15:23, and you want to change its format to December 23, 2019 03:23 PM. Likewise, you may want to convert a date from MM/dd/yyyy to dd-MMM-yyyy or any other format of your choice.

Java 8 Date & Time API

A new date and time API was introduced in Java 8 (classes in the java.time.* package) to fix the flaws of the old java.util.Date and java.util.Calendar APIs. Java 8 new API is thread-safe, easier to use, and provides utility methods for date and time operations. All classes in the new date and time API use ISO-8601 format to represent dates and times.

format() method

Java 8 new date and time API provides a format() method that accepts an instance of DateTimeFormatter to format this date using the specified format:

format(DateTimeFormatter formatter)

The format() method returns the formatted date string. DateTimeFormatter is used to specify a pattern for formatting and parsing date-time objects in Java 8 new date and time API.

Let us look at the LocalDate and LocalDateTime examples below to see how it works.

Convert LocalDate to a string

The LocalDate class represents the date without time in ISO-8601 format (yyyy-MM-dd). The following example demonstrates how you can format the current LocalDate into a date string:

// current date
LocalDate now = LocalDate.now();

// format date to string
String dateStr = now.format(DateTimeFormatter.ofPattern("EEEE, MMMM dd, yyyy"));

// print date string
System.out.println(dateStr);

The above code will output the following:

Sunday, December 29, 2019

You can also use DateTimeFormatter to change the format of a date string. The following code snippet shows how you can parse a string in MM/dd/yyyy format to dd-MMM-yyyy format using both LocalDate and DateTimeFormatter:

// old string format
String oldStr = "12/23/2018";

// parse old string to date
LocalDate date = LocalDate.parse(oldStr, DateTimeFormatter.ofPattern("MM/dd/yyyy"));

// format date to string
String newStr = date.format(DateTimeFormatter.ofPattern("dd-MMM-yyyy"));

// print both strings
System.out.println("Old Date Format: " + oldStr);
System.out.println("New Date Format: " + newStr);

Here is the output of the above code snippet:

Old Date Format: 12/23/2018
New Date Format: 23-Dec-2018

Convert LocalTime to a string

A LocalTime represents the time without date and timezone information. Here is an example that shows how you can format an instance of LocalTime:

// current time
LocalTime now = LocalTime.now();

// format time to string
String timeStr = now.format(DateTimeFormatter.ofPattern("hh:mm:ss a"));

// print time string
System.out.println(timeStr);

The output should look something like the below:

03:47:23 PM

Just like LocalDate, you can also use LocalTime and DateTimeFormatter to change the format of an existing time string as shown below:

// old-time format
String oldStr = "23:15:45.456";

// parse old string to time
LocalTime time = LocalTime.parse(oldStr, DateTimeFormatter.ofPattern("HH:mm:ss.SSS"));

// format time to string
String newStr = time.format(DateTimeFormatter.ofPattern("HH 'Hours', mm 'Minutes', ss 'Seconds'"));

// print both strings
System.out.println("Old Time Format: " + oldStr);
System.out.println("New Time Format: " + newStr);

The above code will print the following on the console:

Old Time Format: 23:15:45.456
New Time Format: 23 Hours, 15 Minutes, 45 Seconds

Covert LocalDateTime to a string

The LocalDateTime class is a popular choice for storing dates and times together in Java 8 and beyond. It represents date and time without timezone in ISO-8601 format. The following example demonstrates how you can format an instance of LocalDateTime to a date string:

// current date and time
LocalDateTime now = LocalDateTime.now();

// format date and time to string
String dtStr = now.format(DateTimeFormatter.ofPattern("EEEE, MMMM dd, yyyy hh:mm a"));

// print date string
System.out.println(dtStr);

If you execute the above code, the output looks like the below:

Sunday, December 29, 2019 05:53 PM

You can also convert a date string to LocalDateTime and then apply formatting to change the date string format:

// old string format
String oldStr = "12/23/2019T15:23";

// parse old string to date and time
LocalDateTime dt = LocalDateTime.parse(oldStr, DateTimeFormatter.ofPattern("MM/dd/yyyy'T'HH:mm"));

// format date to string
String newStr = dt.format(DateTimeFormatter.ofPattern("MMMM dd, yyyy hh:mm a"));

// print both strings
System.out.println("Old Date & Time Format: " + oldStr);
System.out.println("New Date & Time Format: " + newStr);

The above example code will output the following:

Old Date & Time Format: 12/23/2019T15:23
New Date & Time Format: December 23, 2019 03:23 PM

Convert ZonedDateTime to a string

The ZonedDateTime class stores timezone-specific dates and times. It represents a date-time with a timezone in ISO-8601 format (e.g. 2019-05-15T10:15:30+05:00[Asia/Karachi]).

The following example demonstrates how you can format an instance of ZonedDateTime using the format() method:

// current date and time
ZonedDateTime now = ZonedDateTime.now();

// format date and time to string
String dtStr = now.format(DateTimeFormatter.ofPattern("EEEE, MMMM dd, yyyy hh:mm a VV"));

// print date string
System.out.println(dtStr);

You should see the following output for the above code snippet:

Sunday, December 29, 2019 06:07 PM Asia/Karachi

Let us look at another example of ZonedDateTime that parses a string to create a new instance and then formats it to a string:

// old string format
String oldStr = "12/23/2019T09:20 +0100 Europe/Paris";

// parse old string to date and time
ZonedDateTime dt = ZonedDateTime.parse(oldStr,
        DateTimeFormatter.ofPattern("MM/dd/yyyy'T'HH:mm Z VV"));

// format date to string
String newStr = dt.format(DateTimeFormatter.ofPattern("EEEE, MMM dd, yyyy HH:mm Z '['VV']'"));

// print both strings
System.out.println("Old Date & Time Format: " + oldStr);
System.out.println("New Date & Time Format: " + newStr);

Here is the output for the above code snippet:

Old Date & Time Format: 12/23/2019T09:20 +0100 Europe/Paris
New Date & Time Format: Monday, Dec 23, 2019 09:20 +0100 [Europe/Paris]

Convert OffsetDateTime to a string

The OffsetDateTime is another Java 8 date and time class that represents a date and time with an offset from UTC/Greenwich in ISO-8601 format (e.g., 1989-08-02T11:55:45+03:30).

The following example shows how you can format an instance of OffsetDateTime to a string:

// current date and time
OffsetDateTime now = OffsetDateTime.now(ZoneOffset.of("-05:00"));

// format date time to string
String dtStr = now.format(DateTimeFormatter.ofPattern("EEEE, MMMM dd, yyyy hh:mm a Z"));

// print date string
System.out.println(dtStr);

The above code will output the following:

Sunday, December 29, 2019 08:23 AM -0500

Just like ZonedDateTime, you can also parse a string into an instance of OffsetDateTime and then convert it back to a string:

// old string format
String oldStr = "12/23/2019 09:20 +0300";

// parse old string to date and time
OffsetDateTime dt = OffsetDateTime.parse(oldStr, DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm Z"));

// format date to string
String newStr = dt.format(DateTimeFormatter.ofPattern("EEEE, MMMM dd, yyyy HH:mm Z"));

// print both strings
System.out.println("Old Date & Time Format: " + oldStr);
System.out.println("New Date & Time Format: " + newStr);

Here is what the output looks like for OffsetDateTime parsing and formatting:

Old Date & Time Format: 12/23/2019 09:20 +0300
New Date & Time Format: Monday, December 23, 2019 09:20 +0300

Convert Instant to a string

An Instant represents a specific moment on the timeline since the January 1st, 1970 UTC/Greenwich (1970-01-01 00:00:00).

Instant doesn't provide format() method. So you have to use the format() method from DateTimeFormatter to convert an Instant to a string, as shown below:

// current instant
Instant instant = Instant.now();

// format instant to string
String dtStr = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)
        .withZone(ZoneId.systemDefault())
        .format(instant);

// print date string
System.out.println(dtStr);

The above code will print the following on the console:

12/29/19 6:39 PM

Check out Introduction to Java 8 Date and Time API guide for more new date and time API examples.

Convert java.util.Date to a string

Before Java 8, java.util.Date and java.util.Calendar classes were used for handling dates and times. If you are still using these legacy classes, you can use SimpleDateFormat to format an instance of the Date class.

The following example demonstrates how you can format a Date object using the SimpleDateFormat class:

// current date
Date date = new Date();

// create a pattern
SimpleDateFormat formatter = new SimpleDateFormat("EEEE, MMMM dd, yyyy hh:mm a");

// format date to string
String dtStr = formatter.format(date);

// print date string
System.out.println(dtStr);

Here is the output of the above code snippet:

Sunday, December 29, 2019 08:20 PM

You can also parse an existing date string to an instance of the Date class and then apply formatting to change the format using SimpleDateFormat as shown below:

// old string format
String oldStr = "08/02/1989T12:20:10";

// create patterns
SimpleDateFormat oldFormatter = new SimpleDateFormat("MM/dd/yyyy'T'HH:mm:ss");
SimpleDateFormat newFormatter = new SimpleDateFormat("EEEE, MMMM dd, yyyy hh:mm a");

// parse old string to date
Date date = oldFormatter.parse(oldStr);

// format date to a new string
String newStr = newFormatter.format(date);

// print both strings
System.out.println("Old Date Format: " + oldStr);
System.out.println("New Date Format: " + newStr);

The above code will output the following on the console:

Old Date Format: 08/02/1989T12:20:10
New Date Format: Wednesday, August 02, 1989 12:20 PM

Common Date and Time Patterns

The following are some of the most common patterns that you can use with DateTimeFormatter and SimpleDateFormat for formatting and parsing dates and times:

Letter Description Examples
y Year 2019
M Month in year August, 08, 8
d Day in month 1-31
E Day name in week Monday, Friday
a Ante meridiem/Post meridiem marker AM, PM
H Hour in day 0-23
h Hour in AM/PM 1-12
m Minute in hour 0-60
s Second in minute 0-60
S Millisecond in the minute 978
z Timezone Pacific Standard Time; PST; GMT-08:00
Z Timezone offset in hours (RFC pattern) -0800
X Timezone offset in ISO format -08; -0800; -08:00
s Second in minute 0-60

Check out this JavaDoc for a complete list of symbols that you can use to define a date and time pattern for parsing a string into a date.

Summary

In this tutorial, we looked at different methods to convert a date to a string using Java 8 new date and time API and the legacy java.util.Date class.

At first glance, the string-to-date conversion seems straightforward, but it may not be as easy as it looks. Many Java developers make subtle mistakes due to the confusing syntax of patterns. Such mistakes are hard to debug and mostly don't throw any errors.

For example, the yyyy-mm-dd pattern looks fine and parses or formats a date without error. But it is a wrong pattern as mm doesn't represent months but minutes. The actual pattern should be yyyy-MM-dd.

There is also another difference between Java 8 new date and time API and before, which means the same pattern which worked with SimpleDateFormat might not work with DateTimeFormatter. So you have to be a little bit careful while defining a pattern.

Read Next: How to convert a string to date in Java

✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.