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.
Best Solution
That's the hard way, and those
java.util.Datesetter methods have been deprecated since Java 1.1 (1997). Moreover, the wholejava.util.Dateclass was de-facto deprecated (discommended) since introduction ofjava.timeAPI in Java 8 (2014).Simply format the date using
DateTimeFormatterwith a pattern matching the input string (the tutorial is available here).In your specific case of "January 2, 2010" as the input string:
MMMMpattern for itdpattern for it.yyyypattern for it.Note: if your format pattern happens to contain the time part as well, then use
LocalDateTime#parse(text, formatter)instead ofLocalDate#parse(text, formatter). And, if your format pattern happens to contain the time zone as well, then useZonedDateTime#parse(text, formatter)instead.Here's an extract of relevance from the javadoc, listing all available format patterns:
GuyDM/LdQ/qYwWEe/cFahKkHmsSAnNVzOXxZDo 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 useDateTimeFormatter.RFC_1123_DATE_TIME. This is possible because they are, on the contrary toSimpleDateFormat, 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 withLocalDateTime#parse(text)as it already uses theISO_LOCAL_DATE_TIMEformatter. Similarly,LocalDate#parse(text)parses an ISO date without the time component (seeISO_LOCAL_DATE), andZonedDateTime#parse(text)parses an ISO date with an offset and time zone added (seeISO_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 usingSimpleDateFormatusing a format pattern matching the input string.Note the importance of the explicit
Localeargument. 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 ajava.text.ParseExceptioneven though when the format pattern seems valid.Here's an extract of relevance from the javadoc, listing all available format patterns:
GyYM/LwWDdFEuaHkKhmsSzZXNote 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.
MMMMMor more is unnecessary.Here are some examples of valid
SimpleDateFormatpatterns to parse a given string to date:yyyy.MM.dd G 'at' HH:mm:ss zEEE, MMM d, ''yyh:mm ahh 'o''clock' a, zzzzK:mm a, zyyyyy.MMMM.dd GGG hh:mm aaaEEE, d MMM yyyy HH:mm:ss ZyyMMddHHmmssZyyyy-MM-dd'T'HH:mm:ss.SSSZyyyy-MM-dd'T'HH:mm:ss.SSSXXXYYYY-'W'ww-uAn important note is that
SimpleDateFormatis 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.