In this tutorial, you'll learn different ways to convert a string object to a date object in Java. We'll first look at utility methods provided by Java 8 new date and time API to perform the string-to-date conversion.

Afterward, we'll look at the legacy java.util.Date class used to represent dates. Finally, we'll discuss 3rd-party libraries like Apache Commons Lang that can also be used to perform this conversion.

Java 8 Date & Time API

Java 8 introduced a new date and time API (classes in the java.time.* package) to make it easy to work with dates in Java. These classes use ISO-8601 format to represent dates and times.

parse() method

The new API provides the parse() method that accepts a sequence of characters as an argument and uses the ISO_LOCAL_DATE format to parse the string into a date:

parse(CharSequence text)

The input string must be in ISO-8601 format to convert a string into an instance of date using the above method. Otherwise, a DateTimeParseException will be thrown at runtime.

Alternatively, you can pass another parameter to parse() to explicitly define the string pattern:

parse(CharSequence text, DateTimeFormatter formatter)

A DateTimeFormatter instance is a formatter for formatting and parsing date-time objects in Java 8 new date and time API.

Convert a string to LocalDate object

The LocalDate class represents a date in ISO-8601 format (yyyy-MM-dd) without any time information. It differs from the old Date and doesn't store time or timezone information.

Unlike Date, LocalDate provides utility methods to parse and format dates and add or subtract different units like days, months, and years.

To parse an ISO-8601 string to an instance of LocalDate, you can do the following:

// ISO-8601 string
String str = "2019-12-22";

// parse string to date
LocalDate date = LocalDate.parse(str);

The above code is equivalent to writing the following code to instantiate a LocalDate instance:

LocalDate date = LocalDate.of(2019, Month.DECEMBER, 22);

If the string is not in ISO-8601 format, you must define a custom formatter using DateTimeFormatter as shown below:

// custom string format
String customStr = "December 22, 2019";

// define formatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM dd, yyyy");

// parse string to date
LocalDate customDate = LocalDate.parse(customStr, formatter);

Here is another example that uses the pre-defined formatter BASIC_ISO_DATE from DateTimeFormatter to parse a string into a LocalDate:

// string in basic ISO-8601 format
String str = "20191222";

// parse string to date
LocalDate date = LocalDate.parse(str, DateTimeFormatter.BASIC_ISO_DATE);

Convert a string to LocalTime object

A LocalTime instance represents a time without the date or timezone information in ISO-8601 format. Just like LocalDate, you can use the LocalTime.parse() method to convert a string to a LocalTime object, as shown below:

// ISO-8601 string
String str = "08:45";

// parse string to time
LocalTime time = LocalTime.parse(str);

The above code is equivalent to writing the following code to instantiate an instance of LocalTime:

LocalTime time = LocalTime.of(8, 45);

For none ISO-8601 string formats, you have to pass a formatter using DateTimeFormatter as shown below:

// custom string format
String customStr = "10:15 PM";

// define formatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm a");

// parse string to time
LocalTime customTime = LocalTime.parse(customStr, formatter);

Convert a string to LocalDateTime object

The LocalDateTime is the most popular class for handling date and time together in Java 8 and higher. It stores a combination of date and time without timezone in ISO-8601 format (yyyy-MM-ddTHH:mm).

To parse an ISO-8601 string into an instance of LocalDateTime, you can use the parse() method as shown below:

// ISO-8601 string
String str = "1989-08-02T11:25";

// parse string to date and time
LocalDateTime dateTime = LocalDateTime.parse(str);

The above code is equivalent to the following code that instantiates an instance of LocalDateTime:

LocalDateTime dateTime = LocalDateTime.of(1989, Month.AUGUST, 2, 11, 25); 

To convert a string with a custom date format into a LocalDateTime object, you need to supply a formatter using DateTimeFormatter:

// custom string format
String customStr = "07/17/2018 12:45 PM";

// define formatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a");

// parse string to date and time
LocalDateTime customDT = LocalDateTime.parse(customStr, formatter);

Convert a string to ZonedDateTime object

The ZonedDateTime class handles timezone-specific dates and times. It represents a date-time with a timezone in the ISO-8601 format (e.g. 2010-05-15T10:15:30+01:00[Europe/Paris]).

To convert an ISO-8601 string into an instance of ZonedDateTime, just use the parse() method:

// ISO-8601 string
String str = "2010-05-15T10:15:30+01:00[Europe/Paris]";

// parse string to zoned date and time
ZonedDateTime dateTime = ZonedDateTime.parse(str);

Convert a string to OffsetDateTime object

The OffsetDateTime class represents a date and time with an offset from UTC/Greenwich in the ISO-8601 format (e.g. 1992-06-30T23:15:30-03:30).

The following example demonstrates how you can convert an ISO-8601 string into an instance of OffsetDateTime:

// ISO-8601 string
String str = "1992-06-30T23:15:30-03:30";

// parse string to offset date and time
OffsetDateTime dateTime = OffsetDateTime.parse(str);

To parse custom strings into OffsetDateTime, you need to parse a custom formatter using DateTimeFormatter as shown below:

// custom string format
String customStr = "Mon, July 15, 2019 10:00 AM +03:00";

// define formatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE, MMMM dd, yyyy hh:mm a XXX");

// parse string to offset date and time
OffsetDateTime customDT = OffsetDateTime.parse(customStr, formatter);

Convert a string to Instant object

The Instant class represents a specific moment on the timeline. To convert a string into an Instant object, the string must be in ISO_INSTANT format (e.g. 2011-12-03T10:15:30Z).

Here is an example:

// ISO-8601 string
String str = "2011-12-03T10:15:30Z";

// parse string to instant
Instant instant = Instant.parse(str);

You can easily convert an Instant object to any other date-time format like LocalDateTime or ZonedDateTime:

// convert instant to local date-time
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.of(ZoneOffset.UTC.getId()));
System.out.println(localDateTime);

// convert instant to zoned date-time
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("Asia/Karachi"));
System.out.println(zonedDateTime);

Here is the output of the above code snippet:

2011-12-03T10:15:30
2011-12-03T15:15:30+05:00[Asia/Karachi]

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

Convert a string to java.util.Date

Before Java 8, both java.util.Date and java.util.Calendar classes were used to handle dates and times. To convert a string into an instance of Date, you need to use the SimpleDateFormat to define a custom date and time pattern.

Here are a few examples:

try {
    // different data-time strings
    String str1 = "10/23/2011";
    String str2 = "10-Jan-2015";
    String str3 = "Fri, August 3 2018";
    String str4 = "Friday, Jun 07, 2019 10:10:56 AM";
    String str5 = "2018-10-05T15:23:01Z";

    // define date-time patterns
    SimpleDateFormat sdf1 = new SimpleDateFormat("MM/dd/yyyy");
    SimpleDateFormat sdf2 = new SimpleDateFormat("dd-MMM-yyyy");
    SimpleDateFormat sdf3 = new SimpleDateFormat("EEE, MMMM d yyyy");
    SimpleDateFormat sdf4 = new SimpleDateFormat("EEEE, MMM dd, yyyy hh:mm:ss a");
    SimpleDateFormat sdf5 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");

    // convert string to dates
    System.out.println(sdf1.parse(str1));
    System.out.println(sdf2.parse(str2));
    System.out.println(sdf3.parse(str3));
    System.out.println(sdf4.parse(str4));
    System.out.println(sdf5.parse(str5));

} catch (ParseException ex) {
    ex.printStackTrace();
}

The above code generates the following output:

Sun Oct 23 00:00:00 PKT 2011
Sat Jan 10 00:00:00 PKT 2015
Fri Aug 03 00:00:00 PKT 2018
Fri Jun 07 10:10:56 PKT 2019
Fri Oct 05 20:23:01 PKT 2018

By default, Date doesn't contain any information about the timezone. Therefore, you can not set a timezone for a Date object. When we convert a string to Date using SimpleDateFormat.parse(), it is automatically converted to the default system timezone.

For example, look at the last string-to-date conversion in the example above. The 2018-10-05T15:23:01Z date-time string in UTC (with time 15:23:01) is converted to Fri Oct 05 20:23:01 PKT 2018 with time 20:23:01. This is because the PKT is 5 hours ahead of UTC (+05:00).

However, you can format the Date object and add the timezone information to a string using SimpleDateFormat:

try {
    // date-time string
    String str = "2018-10-05T15:23:01Z";

    // define date-time pattern
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");

    // set Europe/Paris timezone
    formatter.setTimeZone(TimeZone.getTimeZone("Europe/Paris"));

    // convert string to date
    Date date = formatter.parse(str);

    // format date to string with timezone
    String zonedDate = formatter.format(date);

    // print dates
    System.out.println(date);
    System.out.println(zonedDate);

} catch (ParseException ex) {
    ex.printStackTrace();
}

Here is the output of the above code:

Fri Oct 05 20:23:01 PKT 2018
2018-10-05T17:23:01+02

DateTimeFormatter vs. SimpleDateFormat

After learning string-to-date conversion through Java 8 new date and time APIs DateTimeFormatter and SimpleDateFormat, you may be wondering "how do they differ from each other, and what is the right choice for me?"

Introduced in Java 8 with the new date and time API, DateTimeFormatter is a part of java.time.format.* that replaces the older and less frequently used SimpleDateFormat. Both these classes are used to declare a date and time pattern for parsing and formatting dates and times.

The DateTimeFormatter class is thread-safe unlike its older counterpart and offers new utility methods and constants for various date and time formats.

Let us look at the below example:

// `DateTimeFormatter` example
LocalDate localDate = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MMM-yyyy");
String localDateStr = localDate.format(formatter);
LocalDate parsedLocalDate = LocalDate.parse(localDateStr, formatter);

// `SimpleDateFormat` example
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
String dateStr = sdf.format(date);
Date parseDate = sdf.parse(dateStr);

As you can see above, the difference between DateTimeFormatter and SimpleDateFormat is clear. In the new date and time API, the classes have their own parse and format methods and use DateTimeFormatter for patterns only. In the older API, a formatter is used to both parse and format the date.

Rule of thumb, use DateTimeFormatter if you use Java 8 new date and time API. For legacy codebase (Java 7 and below), use SimpleDateFormat for patterns.

3rd-Party Libraries

Now that we have developed a good understanding of performing string-to-date conversion using new and old APIs included in core Java, let us look at some external libraries.

Joda-Time

Before Java 8, Joda-Time was developed to overcome the shortcomings of the old date and time API. It provided an excellent alternative to core Java date and time classes and quickly became a de facto standard date and time library for Java before Java SE 8.

Since Java 8, all Java-Time functionality is already implemented in the core Java in the form of the new date and time API. That is why the author of Joda-Time recommends users migrate to Java 8 java.time (JSR-310) for working with dates and times.

If the migration is not possible, or if you are using Java 7 or below, Joda-Time is still a good library to handle date and time.

To add Joda-Time to your Maven project, add the following dependency to the pom.xml file:

<dependency>
  <groupId>joda-time</groupId>
  <artifactId>joda-time</artifactId>
  <version>2.10.5</version>
</dependency>

For a Gradle project, include the below dependency to your build.gradle file:

implementation 'joda-time:joda-time:2.10.5'

Working with Joda-Time is very much similar to working with Java 8 new date and time API. Here is a quick example:

// date-time string
String str = "12/27/2019 14:15:45";

// define date and time pattern
DateTimeFormatter formatter = DateTimeFormat.forPattern("MM/dd/yyyy HH:mm:ss");
 
// convert string to date
DateTime dateTime = DateTime.parse(str, formatter);

The DateTime class from Joda-Time also supports the timezone information:

// date-time string
String str = "12/27/2019 14:15:45";

// define date and time pattern
DateTimeFormatter formatter = DateTimeFormat.forPattern("MM/dd/yyyy HH:mm:ss");
 
// convert string to date
DateTime dateTime = DateTime.parse(str, formatter);

// specify timezone
DateTime zonedDateTime  = dateTime.withZone(DateTimeZone.forID("Europe/Paris"));

Apache Commons Lang

The Apache Commons Lang library is another 3rd-party library that provides many utility classes for working with legacy Date and Calendar classes.

To add the library to your Maven project, add the following dependency to the pom.xml file:

<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>3.9</version>
</dependency>

For Gradle, add the below dependency to your build.gradle file:

implementation 'org.apache.commons:commons-lang3:3.9'

Now you can use the DateUtils class from Apache Commons Lang to parse a string into a Date object:

// date string
String str = "10-Jan-2020";

// parse string to date
Date date = DateUtils.parseDate(str, new String[] { "dd-MMM-yyyy", "dd/MM/yyyy" });

As you can see above, DateUtils.parseDate() accepts an array of patterns. It will parse each pattern after another. If no pattern matches the given input string, it throws a ParseException exception.

Common Date and Time Patterns

Let us take a look at 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

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

Summary

String-to-date conversion is one of the most frequent operations in Java. In this article, we covered multiple ways to convert a string object into a date object, including Java 8 new date and time API, legacy Date class, and 3rd-party libraries like Joda-Time and Apache Commons Lang.

The new date and time API provides a comprehensive set of classes for parsing different types of strings into the date and time objects. These classes are thread-safe, backward-compatible, and easier to use. You should always use the new API for parsing and formatting dates and times in Java 8 and higher.

If, for some reason, you cannot use the new API, go for the Joda-Time library. It is an excellent replacement for core Java date and time API before Java 8.

Read next: How to get current date and time in Java

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