Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert "Friday, February 1, 2013" to "2013-02-01"

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
like image 691
sudo Avatar asked Feb 03 '13 20:02

sudo


3 Answers

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

like image 97
Jon Skeet Avatar answered Nov 07 '22 20:11

Jon Skeet


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

like image 28
Gabriele Mariotti Avatar answered Nov 07 '22 18:11

Gabriele Mariotti


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.

like image 2
Arvind Kumar Avinash Avatar answered Nov 07 '22 18:11

Arvind Kumar Avinash