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.