One of the most common tasks in Java programming is to format a date to a string or convert a string back to a date. In my previous article, we have already 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 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. Similarly, 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 java.time.* package) to fix the flaws of old java.util.Date and java.util.Calendar API. Java 8 new API is thread-safe, easier-to-use, and provides a lot of utility methods for date and time operations. All the 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 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.

Format LocalDate

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

Format LocalTime

A LocalTime represents the time without any 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 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

Format LocalDateTime

LocalDateTime is a popular class for handling both date and time 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 datetime 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 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

Format ZonedDateTime

The ZonedDateTime class is used to work with 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 datetime 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 first parses a string to create a new instance and format the date back to the 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]

Format OffsetDateTime

OffsetDateTime is another class from Java 8 date and time API 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 datetime 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 apply formatting:

// 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 how 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

Format Instant

An Instant represents a specific moment on the timeline since the 1st second of January 1, 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.

Format java.util.Date

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 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 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 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:

LetterDescriptionExamples
yYear2019
MMonth in yearAugust, 08, 8
dDay in month1-31
EDay name in weekMonday, Friday
aAnte meridiem/Post meridiem markerAM, PM
HHour in day0-23
hHour in AM/PM1-12
mMinute in hour0-60
sSecond in minute0-60
SMillisecond in the minute978
zTimezonePacific Standard Time; PST; GMT-08:00
ZTimezone offset in hours (RFC pattern)-0800
XTimezone offset in ISO format-08; -0800; -08:00
sSecond in minute0-60

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

Summary

In this article, we looked at different methods to convert a date to a string using both Java 8 new date and time API and 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 doesn't throw any error. For example, yyyy-mm-dd pattern looks totally fine and it parses or formats a date without any 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.

That's all for formatting dates in Java. If you are using Java 8 and higher, always use the new date and time API with DateTimeFormatter for parsing and formatting dates and times. The new API is thread-safe, immutable, and provides a lot of utility methods for different kinds of date and time operations.

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

✌️ Like this article? Follow @attacomsian on Twitter. You can also follow me on LinkedIn and DEV. Subscribe to RSS Feed.

👋 If you enjoy reading my articles and want to support me to continue creating free tutorials, ☕ Buy me a coffee (cost $5).