53

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...

Hank Gay
  • 70,339
  • 36
  • 160
  • 222
bsr
  • 57,282
  • 86
  • 216
  • 316

6 Answers6

60

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");
Michael Myers
  • 188,989
  • 46
  • 291
  • 292
Hank Gay
  • 70,339
  • 36
  • 160
  • 222
  • 7
    It certainly is a potentially confusing Javadoc entry. – SteveD Apr 27 '10 at 14:20
  • thanks a lot for the pointer... I'm bit confused how to use ConverterManager. How do I pass the string to it? Do I need need to add a partial converter to it? but it says by default it accepts string for partial convert. If you could give an example, it would be great help.. thanks – bsr Apr 27 '10 at 15:27
  • 1
    Sorry my answer wasn't clear enough, but it looks like you figured it out. I did indeed mean `final LocalDate myDate = new LocalDate("2010-04-28");` – Hank Gay Apr 28 '10 at 19:24
  • 3
    So does this *always* want the format of the string in 'YYYY-MM-DD' ? or could other platforms require different orders ? (I'm trying to just validate a date string : and for my purposes I always want it in YYYY-MM-DD) – monojohnny Jan 26 '16 at 16:58
20

Use the parse(String) method.

LocalDate date = LocalDate.parse("2009-04-17");
JodaStephen
  • 60,927
  • 15
  • 95
  • 117
10

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.

Kevin Won
  • 7,156
  • 5
  • 36
  • 54
  • Joda clearly statis in the javadocs: `It accepts formats described by the following syntax: date-element = std-date-element | ord-date-element | week-date-element std-date-element = yyyy ['-' MM ['-' dd]] ord-date-element = yyyy ['-' DDD] week-date-element = xxxx '-W' ww ['-' e] `. I think this is quite sane behaviour. – Czar Jun 15 '17 at 06:01
  • stating in the docs is one thing, giving a big pit 'o failure to fall into is another, methinks – Kevin Won Jun 27 '17 at 23:46
5

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"));
}
Mikhail Batcer
  • 1,938
  • 7
  • 37
  • 57
1

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);
trincot
  • 317,000
  • 35
  • 244
  • 286
Computered
  • 440
  • 1
  • 7
  • 21
0

This worked for me:

LocalDate d1 = LocalDate.parse("2014-07-19");
LocalDate dNow = LocalDate.now();  // Current date
hichris123
  • 10,145
  • 15
  • 56
  • 70
CharlesF
  • 17
  • 2