Joda time : How to convert String to LocalDate?

How to specify the format string to convert the date alone from string. In my case, only the date part is relevant

Constructing it as DateTime fails:

String dateString = "2009-04-17";
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
DateTime dateTime = formatter.parseDateTime(dateString);

with error java.lang.IllegalArgumentException: Invalid format: "2011-04-17" is too short

Probably because I should use LocalDate instead. But, I do not see any formatter for LocalDate . What is the best way to convert String dateString = "2009-04-17"; into LocalDate (or something else if that is not the right representation)

thanks...


Solution 1:

You're probably looking for LocalDate(Object). It's a bit confusing since it takes a generic Object, but the docs indicate that it will use a ConverterManager that knows how to handle a String if you pass a String to the constructor, e.g.

LocalDate myDate = new LocalDate("2010-04-28");

Solution 2:

Use the parse(String) method.

LocalDate date = LocalDate.parse("2009-04-17");

Solution 3:

There's a somewhat subtle bug-ish issue with using LocalDate.parse() or new LocalDate(). A code snippet is worth a thousand words. In the following example in the scala repl I wanted to get a Local date in a string format yyyyMMdd. LocalDate.parse() is happy to give me an instance of a LocalDate, but it's not the correct one (new LocalDate() has the same behavior):

scala> org.joda.time.LocalDate.parse("20120202")
res3: org.joda.time.LocalDate = 20120202-01-01

I give it Feb 2, 2016 in the format yyyyMMdd and I get back a date of January 1, 20120202. I'm going out on a limb here: I don't think that this is what it should be doing. Joda uses 'yyyy-MM-dd' as the default but implicitly will accept a string with no '-' characters, thinking you want January 1 of that year? That does not seem like a reasonable default behavior to me.

Given this, it seems to me that using a joda date formatter that can't be so easily fooled is a better solution to parsing a string. Moreover, LocalDate.parse() should probably throw an exception if the date format is not 'yyyy-MM-dd':

scala> val format = org.joda.time.format.DateTimeFormat.forPattern("yyyyMMdd")
format: org.joda.time.format.DateTimeFormatter = org.joda.time.format.DateTimeFormatter@56826a75

scala> org.joda.time.LocalDate.parse("20120202", format)
res4: org.joda.time.LocalDate = 2012-02-02

this will cause other formats to fail so you don't get this odd buggy behavior:

scala> val format = org.joda.time.format.DateTimeFormat.forPattern("yyyy-MM-dd")
format: org.joda.time.format.DateTimeFormatter = org.joda.time.format.DateTimeFormatter@781aff8b

scala> org.joda.time.LocalDate.parse("20120202", format)
java.lang.IllegalArgumentException: Invalid format: "20120202" is too short
  at org.joda.time.format.DateTimeFormatter.parseLocalDateTime(DateTimeFormatter.java:900)
  at org.joda.time.format.DateTimeFormatter.parseLocalDate(DateTimeFormatter.java:844)
  at org.joda.time.LocalDate.parse(LocalDate.java:179)
  ... 65 elided

which is a much more sane behavior than returning a date in the year 20120202.

Solution 4:

In my case, incoming string may be in one of two formats. So I first try to parse string with more specific format:

String s = "2016-02-12";
LocalDateTime ldt;
try {
    ldt = LocalDateTime.parse(s, DateTimeFormat.forPattern("YYYY-MM-dd HH:mm"));
}
catch (IllegalArgumentException e) {
    ldt = LocalDateTime.parse(s, DateTimeFormat.forPattern("YYYY-MM-dd"));
}

Solution 5:

You can use LocalDate.of with the year, month and day passed as separate arguments:

LocalDate date1 = LocalDate.of(2009, 4, 17);
LocalDate date2 = LocalDate.of(2009, Month.APRIL, 17);