Query explained:
What is the best way to convert a String
in the format ‘January 2, 2010’ to a Date
in Java?
Ultimately, I want to break out the month, the day, and the year as integers so that I can use
Date date = new Date();
date.setMonth()..
date.setYear()..
date.setDay()..
date.setlong currentTime = date.getTime();
to convert the date into time.
How to convert string to date in Java? Answer #1:
That’s the hard way, and those java.util.Date
setter methods have been deprecated since Java 1.1 (1997). Moreover, the whole java.util.Date
class was de-facto deprecated (discommended) since introduction of java.time
API in Java 8 (2014).
Simply format the date using DateTimeFormatter
with a pattern matching the input string (the tutorial is available here).
In your specific case of “January 2, 2010” as the input string:
- “January” is the full text month, so use the
MMMM
pattern for it - “2” is the short day-of-month, so use the
d
pattern for it. - “2010” is the 4-digit year, so use the
yyyy
pattern for it.
String string = "January 2, 2010";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM d, yyyy", Locale.ENGLISH);
LocalDate date = LocalDate.parse(string, formatter);
System.out.println(date); // 2010-01-02
Note: if your format pattern happens to contain the time part as well, then use LocalDateTime#parse(text, formatter)
instead of LocalDate#parse(text, formatter)
. And, if your format pattern happens to contain the time zone as well, then use ZonedDateTime#parse(text, formatter)
instead.
Here’s an extract of relevance from the javadoc, listing all available format patterns:
Symbol | Meaning | Presentation | Examples |
---|---|---|---|
G | era | text | AD; Anno Domini; A |
u | year | year | 2004; 04 |
y | year-of-era | year | 2004; 04 |
D | day-of-year | number | 189 |
M /L | month-of-year | number/text | 7; 07; Jul; July; J |
d | day-of-month | number | 10 |
Q /q | quarter-of-year | number/text | 3; 03; Q3; 3rd quarter |
Y | week-based-year | year | 1996; 96 |
w | week-of-week-based-year | number | 27 |
W | week-of-month | number | 4 |
E | day-of-week | text | Tue; Tuesday; T |
e /c | localized day-of-week | number/text | 2; 02; Tue; Tuesday; T |
F | week-of-month | number | 3 |
a | am-pm-of-day | text | PM |
h | clock-hour-of-am-pm (1-12) | number | 12 |
K | hour-of-am-pm (0-11) | number | 0 |
k | clock-hour-of-am-pm (1-24) | number | 0 |
H | hour-of-day (0-23) | number | 0 |
m | minute-of-hour | number | 30 |
s | second-of-minute | number | 55 |
S | fraction-of-second | fraction | 978 |
A | milli-of-day | number | 1234 |
n | nano-of-second | number | 987654321 |
N | nano-of-day | number | 1234000000 |
V | time-zone ID | zone-id | America/Los_Angeles; Z; -08:30 |
z | time-zone name | zone-name | Pacific Standard Time; PST |
O | localized zone-offset | offset-O | GMT+8; GMT+08:00; UTC-08:00; |
X | zone-offset ‘Z’ for zero | offset-X | Z; -08; -0830; -08:30; -083015; -08:30:15; |
x | zone-offset | offset-x | +0000; -08; -0830; -08:30; -083015; -08:30:15; |
Z | zone-offset | offset-Z | +0000; -0800; -08:00; |
Do note that it has several predefined formatters for the more popular patterns. So instead of e.g. DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH);
, you could use DateTimeFormatter.RFC_1123_DATE_TIME
. This is possible because they are, on the contrary to SimpleDateFormat
, thread safe. You could thus also define your own, if necessary.
For a particular input string format, you don’t need to use an explicit DateTimeFormatter
: a standard ISO 8601 date, like 2016-09-26T17:44:57Z, can be parsed directly with LocalDateTime#parse(text)
as it already uses the ISO_LOCAL_DATE_TIME
formatter. Similarly, LocalDate#parse(text)
parses an ISO date without the time component (see ISO_LOCAL_DATE
), and ZonedDateTime#parse(text)
parses an ISO date with an offset and time zone added (see ISO_ZONED_DATE_TIME
).
Pre-Java 8
In case you’re not on Java 8 yet, or are forced to use java.util.Date
, then format the date using SimpleDateFormat
using a format pattern matching the input string.
String string = "January 2, 2010";
DateFormat format = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH);
Date date = format.parse(string);
System.out.println(date); // Sat Jan 02 00:00:00 GMT 2010
Note the importance of the explicit Locale
argument. If you omit it, then it will use the default locale which is not necessarily English as used in the month name of the input string. If the locale doesn’t match with the input string, then you would confusingly get a java.text.ParseException
even though when the format pattern seems valid.
Here’s an extract of relevance from the javadoc, listing all available format patterns:
Letter | Date or Time Component | Presentation | Examples |
---|---|---|---|
G | Era designator | Text | AD |
y | Year | Year | 1996; 96 |
Y | Week year | Year | 2009; 09 |
M /L | Month in year | Month | July; Jul; 07 |
w | Week in year | Number | 27 |
W | Week in month | Number | 2 |
D | Day in year | Number | 189 |
d | Day in month | Number | 10 |
F | Day of week in month | Number | 2 |
E | Day in week | Text | Tuesday; Tue |
u | Day number of week | Number | 1 |
a | Am/pm marker | Text | PM |
H | Hour in day (0-23) | Number | 0 |
k | Hour in day (1-24) | Number | 24 |
K | Hour in am/pm (0-11) | Number | 0 |
h | Hour in am/pm (1-12) | Number | 12 |
m | Minute in hour | Number | 30 |
s | Second in minute | Number | 55 |
S | Millisecond | Number | 978 |
z | Time zone | General time zone | Pacific Standard Time; PST; GMT-08:00 |
Z | Time zone | RFC 822 time zone | -0800 |
X | Time zone | ISO 8601 time zone | -08; -0800; -08:00 |
Note that the patterns are case sensitive and that text based patterns of four characters or more represent the full form; otherwise a short or abbreviated form is used if available. So e.g. MMMMM
or more is unnecessary.
Here are some examples of valid SimpleDateFormat
patterns to parse a given string to date:
Input string | Pattern |
---|---|
2001.07.04 AD at 12:08:56 PDT | yyyy.MM.dd G 'at' HH:mm:ss z |
Wed, Jul 4, ’01 | EEE, MMM d, ''yy |
12:08 PM | h:mm a |
12 o’clock PM, Pacific Daylight Time | hh 'o''clock' a, zzzz |
0:08 PM, PDT | K:mm a, z |
02001.July.04 AD 12:08 PM | yyyyy.MMMM.dd GGG hh:mm aaa |
Wed, 4 Jul 2001 12:08:56 -0700 | EEE, d MMM yyyy HH:mm:ss Z |
010704120856-0700 | yyMMddHHmmssZ |
2001-07-04T12:08:56.235-0700 | yyyy-MM-dd'T'HH:mm:ss.SSSZ |
2001-07-04T12:08:56.235-07:00 | yyyy-MM-dd'T'HH:mm:ss.SSSXXX |
2001-W27-3 | YYYY-'W'ww-u |
An important note is that SimpleDateFormat
is not thread safe. In other words, you should never declare and assign it as a static or instance variable and then reuse it from different methods/threads. You should always create it brand new within the method local scope.
Answer #2:
Ah yes the Java Date discussion, again. To deal with date manipulation we use Date, Calendar, GregorianCalendar, and SimpleDateFormat. For example using your January date as input:
Calendar mydate = new GregorianCalendar();
String mystring = "January 2, 2010";
Date thedate = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH).parse(mystring);
mydate.setTime(thedate);
//breakdown
System.out.println("mydate -> "+mydate);
System.out.println("year -> "+mydate.get(Calendar.YEAR));
System.out.println("month -> "+mydate.get(Calendar.MONTH));
System.out.println("dom -> "+mydate.get(Calendar.DAY_OF_MONTH));
System.out.println("dow -> "+mydate.get(Calendar.DAY_OF_WEEK));
System.out.println("hour -> "+mydate.get(Calendar.HOUR));
System.out.println("minute -> "+mydate.get(Calendar.MINUTE));
System.out.println("second -> "+mydate.get(Calendar.SECOND));
System.out.println("milli -> "+mydate.get(Calendar.MILLISECOND));
System.out.println("ampm -> "+mydate.get(Calendar.AM_PM));
System.out.println("hod -> "+mydate.get(Calendar.HOUR_OF_DAY));
Then you can manipulate that with something like:
Calendar now = Calendar.getInstance();
mydate.set(Calendar.YEAR,2009);
mydate.set(Calendar.MONTH,Calendar.FEBRUARY);
mydate.set(Calendar.DAY_OF_MONTH,25);
mydate.set(Calendar.HOUR_OF_DAY,now.get(Calendar.HOUR_OF_DAY));
mydate.set(Calendar.MINUTE,now.get(Calendar.MINUTE));
mydate.set(Calendar.SECOND,now.get(Calendar.SECOND));
// or with one statement
//mydate.set(2009, Calendar.FEBRUARY, 25, now.get(Calendar.HOUR_OF_DAY), now.get(Calendar.MINUTE), now.get(Calendar.SECOND));
System.out.println("mydate -> "+mydate);
System.out.println("year -> "+mydate.get(Calendar.YEAR));
System.out.println("month -> "+mydate.get(Calendar.MONTH));
System.out.println("dom -> "+mydate.get(Calendar.DAY_OF_MONTH));
System.out.println("dow -> "+mydate.get(Calendar.DAY_OF_WEEK));
System.out.println("hour -> "+mydate.get(Calendar.HOUR));
System.out.println("minute -> "+mydate.get(Calendar.MINUTE));
System.out.println("second -> "+mydate.get(Calendar.SECOND));
System.out.println("milli -> "+mydate.get(Calendar.MILLISECOND));
System.out.println("ampm -> "+mydate.get(Calendar.AM_PM));
System.out.println("hod -> "+mydate.get(Calendar.HOUR_OF_DAY));
Answer #3:
While some of the answers are technically correct, they are not advisable.
- The java.util.Date & Calendar classes are notoriously troublesome. Because of flaws in design and implementation, avoid them. Fortunately we have our choice of two other excellent date-time libraries:
- Joda-Time
This popular open-source free-of-cost library can be used across several versions of Java. - java.time.* package
This new set of classes are inspired by Joda-Time and defined by JSR 310. These classes are built into Java 8. A project is underway to backport these classes to Java 7, but that backporting is not backed by Oracle.
- Joda-Time
- As Kristopher Johnson correctly noted in his comment on the question, the other answers ignore vital issues of:
- Time of Day
Date has both a date portion and a time-of-day portion) - Time Zone
The beginning of a day depends on the time zone. If you fail to specify a time zone, the JVM’s default time zone is applied. That means the behavior of your code may change when run on other computers or with a modified time zone setting. Probably not what you want. - Locale
The Locale’s language specifies how to interpret the words (name of month and of day) encountered during parsing. (The first answer handles this properly.) Also, the Locale affects the output of some formatters when generating a string representation of your date-time.
- Time of Day
Joda-Time
A few notes about Joda-Time follow.
Time Zone
In Joda-Time, a DateTime object truly knows its own assigned time zone. This contrasts the java.util.Date class which seems to have a time zone but does not.
Note in the example code below how we pass a time zone object to the formatter which parses the string. That time zone is used to interpret that date-time as having occurred in that time zone. So you need to think about and determine the time zone represented by that string input.
Since you have no time portion in your input string, Joda-Time assigns the first moment of the day of the specified time zone as the time-of-day. Usually this means 00:00:00
but not always, because of Daylight Saving Time (DST) or other anomalies. By the way, you can do the same to any DateTime instance by calling withTimeAtStartOfDay
.
Formatter Pattern
The characters used in a formatter’s pattern are similar in Joda-Time to those in java.util.Date/Calendar but not exactly the same. Carefully read the doc.
Immutability
We usually use the immutable classes in Joda-Time. Rather than modify an existing Date-Time object, we call methods that create a new fresh instance based on the other object with most aspects copied except where alterations were desired. An example is the call to withZone
in last line below. Immutability helps to make Joda-Time very thread-safe, and can also make some work more clear.
Conversion
You will need java.util.Date objects for use with other classes/framework that do not know about Joda-Time objects. Fortunately, it is very easy to move back and forth.
Going from a java.util.Date object (here named date
) to Joda-Time DateTime…
org.joda.time.DateTime dateTime = new DateTime( date, timeZone );
Going the other direction from Joda-Time to a java.util.Date object…
java.util.Date date = dateTime.toDate();
Sample Code
String input = "January 2, 2010";
java.util.Locale locale = java.util.Locale.US;
DateTimeZone timeZone = DateTimeZone.forID( "Pacific/Honolulu" ); // Arbitrarily chosen for example.
DateTimeFormatter formatter = DateTimeFormat.forPattern( "MMMM d, yyyy" ).withZone( timeZone ).withLocale( locale );
DateTime dateTime = formatter.parseDateTime( input );
System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTime in UTC/GMT: " + dateTime.withZone( DateTimeZone.UTC ) );
When run…
dateTime: 2010-01-02T00:00:00.000-10:00
dateTime in UTC/GMT: 2010-01-02T10:00:00.000Z
Answer #4:
With Java 8 we get a new Date / Time API (JSR 310).
The following way can be used to parse the date in Java 8 without relying on Joda-Time:
String str = "January 2nd, 2010";
// if we 2nd even we have changed in pattern also it is not working please workout with 2nd
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM Q, yyyy", Locale.ENGLISH);
LocalDate date = LocalDate.parse(str, formatter);
// access date fields
int year = date.getYear(); // 2010
int day = date.getDayOfMonth(); // 2
Month month = date.getMonth(); // JANUARY
int monthAsInt = month.getValue(); // 1
LocalDate is the standard Java 8 class for representing a date (without time). If you want to parse values that contain date and time information you should use LocalDateTime. For values with timezones use ZonedDateTime. Both provide a parse()
method similar to LocalDate
:
LocalDateTime dateWithTime = LocalDateTime.parse(strWithDateAndTime, dateTimeFormatter);
ZonedDateTime zoned = ZonedDateTime.parse(strWithTimeZone, zoneFormatter);
The list formatting characters from DateTimeFormatter Javadoc:
All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters.
The following pattern letters are defined:
Symbol Meaning Presentation Examples
------ ------- ------------ -------
G era text AD; Anno Domini; A
u year year 2004; 04
y year-of-era year 2004; 04
D day-of-year number 189
M/L month-of-year number/text 7; 07; Jul; July; J
d day-of-month number 10
Q/q quarter-of-year number/text 3; 03; Q3; 3rd quarter
Y week-based-year year 1996; 96
w week-of-week-based-year number 27
W week-of-month number 4
E day-of-week text Tue; Tuesday; T
e/c localized day-of-week number/text 2; 02; Tue; Tuesday; T
F week-of-month number 3
a am-pm-of-day text PM
h clock-hour-of-am-pm (1-12) number 12
K hour-of-am-pm (0-11) number 0
k clock-hour-of-am-pm (1-24) number 0
H hour-of-day (0-23) number 0
m minute-of-hour number 30
s second-of-minute number 55
S fraction-of-second fraction 978
A milli-of-day number 1234
n nano-of-second number 987654321
N nano-of-day number 1234000000
V time-zone ID zone-id America/Los_Angeles; Z; -08:30
z time-zone name zone-name Pacific Standard Time; PST
O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00;
X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15;
x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15;
Z zone-offset offset-Z +0000; -0800; -08:00;
Convert string to date in Java- Examples:
1.
String str_date = "11-June-07";
DateFormat formatter = new SimpleDateFormat("dd-MMM-yy");
Date date = formatter.parse(str_date);
2.
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date;
try {
date = dateFormat.parse("2013-12-4");
System.out.println(date.toString()); // Wed Dec 04 00:00:00 CST 2013
String output = dateFormat.format(date);
System.out.println(output); // 2013-12-04
}
catch (ParseException e) {
e.printStackTrace();
}
Hope you learned something from this post.
Follow Programming Articles for more!