5

How can I perform this conversion in Java?

Currently, I'm doing:

public static String formatDate(String strDateToFormat) {
    try {
        SimpleDateFormat sdfSource = new SimpleDateFormat("EEEE, MMMM DD, YYYY");
        Date date = sdfSource.parse(strDateToFormat);
        SimpleDateFormat sdfDestination = new SimpleDateFormat("yyyy-MM-dd");
        return sdfDestination.format(date);
    } catch (ParseException pe) {
        System.err.println("Parse Exception : " + pe);
    }

    return null;
}

However, this results in an incorrect format. It gives me the following output:

Friday, February 1, 2013 > 2013-01-04
Thursday, January 31, 2013 > 2013-01-03
Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
sudo
  • 319
  • 2
  • 4
  • 10

3 Answers3

9

You're using DD in your parsing part, which is the day of year. You want dd instead. You also probably want yyyy (year) instead of YYYY (week year). (In most cases they're the same value, but not always.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
3

You're using DD in your parsing part, which is the day of year. You want dd instead. Change also YYYY in yyyy.

You can find all patterns here.

http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
2

Your code has got two major problems and the existing answers have already solved one of them. The second and even more dangerous problem is, not using Locale with SimpleDateFormat, which is a Locale-sensitive type. Since your Date-Time string is in English, make sure to use Locale.ENGLISH or some other English-Locale. So, a correct initialization would be:

SimpleDateFormat sdfSource = new SimpleDateFormat("EEEE, MMMM d, y", Locale.ENGLISH);

Check Never use SimpleDateFormat or DateTimeFormatter without a Locale to learn more about it. Also, notice a single d which, for parsing, can cater to both single-digit as well as double-digit representation of a day-of-month. Similarly, a single y can cater to both two-digit as well as four-digit representation of a year.

Switch to the modern Date-Time API

Note that the java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API* released with Java SE 8 in March 2014.

Solution using java.time, the modern Date-Time API

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String input = "Friday, February 1, 2013";
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEEE, MMMM d, u", Locale.ENGLISH);
        LocalDate date = LocalDate.parse(input, dtf);
        System.out.println(date);
    }
}

Output:

2013-02-01

ONLINE DEMO

Some notes:

  1. Here, you can use y instead of u but I prefer u to y.
  2. The LocalDate#toString gives you a String in [ISO-8601 format] which is the exact same format you are expecting. So, you do not need to format LocalDate explicitly to obtain a String in this format.

Learn more about the modern Date-Time API from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110