Joda-Time accepts the month name in a short format (in most languages, it's usually with 3 letters) or long format (with the full name). Your input seems to be in English and with 4 letters, which is not supported.
If it's possible to manipulate the input, you can remove the extra characters and make sure the month name contains just 3 letters.
I also use a java.util.Locale
to specify that the month name is in English. If you don't specify a locale, it uses the system default, and it's not guaranteed to always be English, so it's better to specify one.
I also parse it to a LocalDate
, because its toString()
method already produces the output you want:
String input = "2017-Sept-14";
input = input.replace("Sept", "Sep");
DateTimeFormatter dateTimeFormat = DateTimeFormat.forPattern("yyyy-MMM-dd").withLocale(Locale.ENGLISH);
LocalDate dateTime = dateTimeFormat.parseLocalDate(input);
System.out.println(dateTime);
The output is:
2017-09-14
I was assuming that the locale was English, but in Estonia locale the short month name for September is "sept", so you could also do:
String input = "2017-Sept-14";
input = input.toLowerCase(); // et_EE locale accepts only "sept"
DateTimeFormatter dateTimeFormat = DateTimeFormat.forPattern("yyyy-MMM-dd")
.withLocale(new Locale("et", "EE"));
LocalDate dateTime = dateTimeFormat.parseLocalDate(input);
System.out.println(dateTime);
Or you can try with your system's default (based on your comments that SimpleDateFormat
works with French locale, so there's a chance of the code above to also work).
Java new Date/Time API
Joda-Time is in maintainance mode and is being replaced by the new APIs, so I don't recommend start a new project with it. Even in joda's website it says: "Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310).".
If you can't (or don't want to) migrate from Joda-Time to the new API, you can ignore this section.
In Android you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. To make it work, you'll also need the ThreeTenABP (more on how to use it here).
You can create a formatter, set the locale and parse it to a LocalDate
:
import org.threeten.bp.LocalDate;
import org.threeten.bp.format.DateTimeFormatter;
import org.threeten.bp.format.DateTimeFormatterBuilder;
DateTimeFormatter f = new DateTimeFormatterBuilder()
// case insensitive (so it accepts Sept, sept, and so on)
.parseCaseInsensitive()
// pattern
.appendPattern("yyyy-MMM-dd")
// set locale
.toFormatter(new Locale("et", "EE"));
System.out.println(LocalDate.parse("2017-Sept-14", f));
The output is:
2017-09-14
Or just try with your system's default locale (just call toFormatter()
without arguments and it'll use the system default).
Optionally, you can create a map of custom month names and use it in the formatter. The only detail is that you have to fill it with values for all months. I put Sept
in September, and you can fill the other months accordingly:
// map of custom names for month
Map<Long, String> monthNames = new HashMap<>();
// put the names used in your input
monthNames.put(1L, "Jan");
monthNames.put(2L, "Feb");
monthNames.put(3L, "Mar");
monthNames.put(4L, "Apr");
monthNames.put(5L, "May");
monthNames.put(6L, "Jun");
monthNames.put(7L, "Jul");
monthNames.put(8L, "Aug");
monthNames.put(9L, "Sept");
monthNames.put(10L, "Oct");
monthNames.put(11L, "Nov");
monthNames.put(12L, "Dec");
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// case insensitive (so it accepts Sept, sept, and so on)
.parseCaseInsensitive()
// year
.appendPattern("yyyy-")
// month, using custom names
.appendText(ChronoField.MONTH_OF_YEAR, monthNames)
// day
.appendPattern("-dd")
// create formatter
.toFormatter();
String input = "2017-Sept-14";
System.out.println(LocalDate.parse(input, fmt));