47

I am trying to use the Android SimpleDateFormat like this:

String _Date = "2010-09-29 08:45:22"
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");

try {
    Date date = fmt.parse(_Date);
    return fmt.format(date);
}
catch(ParseException pe) {
    return "Date";    
}

The result is good and I have: 2010-09-29

But if I change the SimpleDateFormat to

SimpleDateFormat("dd-MM-yyyy");

the problem is that I will got 03-03-0035 !!!!

Why and how to get the format like dd-MM-yyyy?

Allan Pereira
  • 2,551
  • 4
  • 18
  • 26
Miloš
  • 17,005
  • 46
  • 137
  • 240
  • 1
    For new readers to this question consider throwing away the long outmoded and notoriously troublesome `SimpleDateFormat` and friends. See if you either can use [desugaring](https://developer.android.com/studio/write/java8-support-table) or add [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP) to your Android project, in order to use java.time, the modern Java date and time API. It is so much nicer to work with. – Ole V.V. Dec 10 '20 at 18:12

11 Answers11

96

I assume you would like to reverse the date format?

SimpleDateFormat can be used for parsing and formatting. You just need two formats, one that parses the string and the other that returns the desired print out:

SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
Date date = fmt.parse(dateString);

SimpleDateFormat fmtOut = new SimpleDateFormat("dd-MM-yyyy");
return fmtOut.format(date);

Since Java 8:

DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneOffset.UTC);
TemporalAccessor date = fmt.parse(dateString);
Instant time = Instant.from(date);

DateTimeFormatter fmtOut = DateTimeFormatter.ofPattern("dd-MM-yyyy").withZone(ZoneOffset.UTC);
return fmtOut.format(time);
Drejc
  • 13,466
  • 15
  • 65
  • 101
  • 2
    Just a side note, the plain old String.format(), can also be used to format the Date ouput. It is not as readable as the SimpleStringFormat, but probably a little bit faster, something, like this: String.format("%td-%tm-%tY", date). – Drejc Feb 14 '12 at 14:02
  • Instead use: new SimpleDateFormat("dd-MM-yyyy", Locale.US); – Rahul Raina Feb 16 '18 at 07:34
  • 1
    Actually both are now more or less deprecated ... with the new Instant class you are probably better off with: DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneOffset.UTC).format(Instant) – Drejc Feb 16 '18 at 08:42
  • Thanks, but SimpleDateFormat("dd-MM-yyyy", Locale.US); is not showing any warning (or depreciation) in Android Studio 3 and Java 9. So it is working. – Rahul Raina Feb 16 '18 at 08:44
  • 3
    Api level 26 is min for android – Vlad Sep 05 '19 at 18:50
  • @Vlad, what has the API level anything to do with this question, that is 7+ years old? – Drejc Sep 07 '19 at 02:25
  • Using java,time, the modern Java date and time API introduced in Java 8, is a good idea. And @Vlad, it works on lower API levels too, see my answer. Drejc, your code doing that does not work. I get `java.time.format.DateTimeParseException: Text '2010-09-29 08:45:22' could not be parsed, unparsed text found at index 10`. – Ole V.V. Dec 10 '20 at 18:11
  • @OleV.V. the code provided works, double check. – Drejc Dec 13 '20 at 20:22
  • I am using the string from the question, `2010-09-29 08:45:22`, and getting the exception mentioned (it wasn’t something I made up). I don’t know which string you were using. – Ole V.V. Dec 14 '20 at 03:57
  • Works like expected --> import org.junit.jupiter.api.Test; import java.text.*; import java.util.Date; import static junit.framework.TestCase.*; class Testing { @Test public void test() { String input = "2010-09-29 08:45:22"; SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd"); try { Date date = fmt.parse(input); String out = fmt.format(date); assertEquals("2010-09-29", out); } catch (Exception pe) { fail(); } } } – Drejc Dec 15 '20 at 08:19
  • [Please see the exception for yourself](https://ideone.com/KyXy43). – Ole V.V. Dec 15 '20 at 14:59
  • No one should use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `DateTimeFormatter` and other classes from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/) as on your second snippet. Only write code that doesn’t throw an exception. – Ole V.V. Dec 15 '20 at 15:20
  • @OleV.V. You know this question was asked 8years ago ... ? – Drejc Dec 16 '20 at 10:07
  • I know that this question and your answer still have readers who deserve to be properly informed, and I expect that they will also have next year. – Ole V.V. Dec 16 '20 at 11:01
  • 1
    I’d like your answer to be helpful to present-day (and future) readers. I offer to change it in the following way, but only if you say you agree to it: I’d make the Java 8 code work with the stirng from the question and put it first, and then put the `SimpleDateFormat` code afterward with a note that it is no longer recommended. And then I’d change my downvote to an upvote. And delete all my comments. Would you like me to? If you accept now and then don’t like my edit when you see it, you can always revert it. – Ole V.V. Dec 16 '20 at 20:52
72

Below is all date formats available, read more doc here.

Symbol  Meaning                Kind         Example
D       day in year             Number        189
E       day of week             Text          E/EE/EEE:Tue, EEEE:Tuesday, EEEEE:T
F       day of week in month    Number        2 (2nd Wed in July)
G       era designator          Text          AD
H       hour in day (0-23)      Number        0
K       hour in am/pm (0-11)    Number        0
L       stand-alone month       Text          L:1 LL:01 LLL:Jan LLLL:January LLLLL:J
M       month in year           Text          M:1 MM:01 MMM:Jan MMMM:January MMMMM:J
S       fractional seconds      Number        978
W       week in month           Number        2
Z       time zone (RFC 822)     Time Zone     Z/ZZ/ZZZ:-0800 ZZZZ:GMT-08:00 ZZZZZ:-08:00
a       am/pm marker            Text          PM
c       stand-alone day of week Text          c/cc/ccc:Tue, cccc:Tuesday, ccccc:T
d       day in month            Number        10
h       hour in am/pm (1-12)    Number        12
k       hour in day (1-24)      Number        24
m       minute in hour          Number        30
s       second in minute        Number        55
w       week in year            Number        27
G       era designator          Text          AD
y       year                    Number        yy:10 y/yyy/yyyy:2010
z       time zone               Time Zone     z/zz/zzz:PST zzzz:Pacific Standard 
heloisasim
  • 4,480
  • 2
  • 23
  • 35
  • For the ones like me : Mysql 24 hour format is : "yyyy-MM-dd kk:mm:ss" NOT "yyyy-MM-dd hh:mm:ss" – ergunkocak May 18 '16 at 15:37
  • 2
    Thete are differences between H, h, K and k. kk = Hours in 1-24 format. hh= hours in 1-12 format. KK= hours in 0-11 format. HH= hours in 0-23 format. – heloisasim May 18 '16 at 15:55
  • So for timestamp conversion i need to use "yyyy-MM-dd HH:mm:ss" for mysql "2016-05-18 18:53:30", right? – ergunkocak May 18 '16 at 16:54
13

I think this Link might helps you

OR

    Date date = Calendar.getInstance().getTime();
    //
    // Display a date in day, month, year format
    //
    DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
    String today = formatter.format(date);
    System.out.println("Today : " + today);
Ajay
  • 4,520
  • 2
  • 28
  • 42
9
String _Date = "2010-09-29 08:45:22"
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat fmt2 = new SimpleDateFormat("dd-MM-yyyy");
    try {
        Date date = fmt.parse(_Date);
        return fmt2.format(date);
    }
    catch(ParseException pe) {

        return "Date";    
    }

try this.

duggu
  • 35,841
  • 11
  • 112
  • 110
Blackbelt
  • 148,780
  • 26
  • 271
  • 285
2

This worked for me...

@SuppressLint("SimpleDateFormat")
private void setTheDate() {
    long msTime = System.currentTimeMillis();
    Date curDateTime = new Date(msTime);
    SimpleDateFormat formatter = new SimpleDateFormat("MM'/'dd'/'y hh:mm");
    curDate = formatter.format(curDateTime);
    mDateText.setText("" + curDate);
}
Roger Belk
  • 179
  • 4
  • 16
2

java.time and desugaring

I recommend that you use java.time, the modern Java date and time API, for your date work. First define a formatter for your string:

private static DateTimeFormatter formatter
        = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");

Then do:

    String dateString = "2010-09-29 08:45:22";
    LocalDateTime dateTime = LocalDateTime.parse(dateString, formatter);
    String newString = dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE);
    System.out.println(newString);

Output is:

2010-09-29

I find it a good practice to parse the entire string even though we currently have no use for the time of day. That may come some other day. java.time furnishes a predefined formatter for your first output format, DateTimeFormatter.ISO_LOCAL_DATE. If you want the opposite order of day, month and year, we will need to write our own formatter for that:

private static DateTimeFormatter dateFormatter
        = DateTimeFormatter.ofPattern("dd-MM-uuuu");

Then we can obtain that too:

    String dmyReversed = dateTime.format(dateFormatter);
    System.out.println(dmyReversed);

29-09-2010

What went wrong in your code?

the problem is that I will got 03-03-0035 !!!!

This is how confusing a SimpleDateFormat with standard settings is: With format pattern dd-MM-yyyy it parses 2010-09-29 as the 2010th day of month 9 of year 29. Year 29 AD that is. And it doesn’t disturb it that there aren’t 2010 days in September. It just keeps counting days through the following months and years and ends up five and a half years later, on 3 March year 35.

Which is just a little bit of the reason why I say: don’t use that class.

Question: Doesn’t java.time require Android API level 26?

java.time works nicely on both older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
  • In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On older Android either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

Ole V.V.
  • 65,573
  • 11
  • 96
  • 117
1

Here is an easy example of SimpleDateFormat tried in Android Studio 3 and Java 9:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.US); 
String strDate = sdf.format(strDate);

Note: SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); shows some deprecation warning in Android Studio 3 Lint. So, add a second parameter Locale.US to specify the Localization in date formatting.

Angelica
  • 456
  • 4
  • 18
Rahul Raina
  • 2,883
  • 21
  • 27
1

Using the date-time API of java.util and their formatting API, SimpleDateFormat I have come across surprises several times but this is the biggest one!

Given below is the illustration of what you have described in your question:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

class Main {
    public static void main(String[] args) {
        System.out.println(formatDateWithPattern1("2010-09-29 08:45:22"));
        System.out.println(formatDateWithPattern2("2010-09-29 08:45:22"));
    }

    static String formatDateWithPattern1(String strDate) {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = fmt.parse(strDate);
            return fmt.format(date);
        } catch (ParseException pe) {
            return "Date";
        }
    }

    static String formatDateWithPattern2(String strDate) {
        SimpleDateFormat fmt = new SimpleDateFormat("dd-MM-yyyy");
        try {
            Date date = fmt.parse(strDate);
            return fmt.format(date);
        } catch (ParseException pe) {
            return "Date";
        }
    }
}

Output:

2010-09-29
03-03-0035

Surprisingly, SimpleDateFormat silently performed the parsing and formatting without raising an alarm. Anyone reading this will not have a second thought to stop using them completely and switch to the modern date-time API.

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.

Using the modern date-time API:

Since the pattern used in both the functions are wrong as per the input string, the parser should raise the alarm and the parsing/formatting types of the modern date-time API do it responsibly.

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

class Main {
    public static void main(String[] args) {
        System.out.println(formatDateWithPattern1("2010-09-29 08:45:22"));
        System.out.println(formatDateWithPattern2("2010-09-29 08:45:22"));
    }

    static String formatDateWithPattern1(String strDate) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd");
        try {
            LocalDateTime date = LocalDateTime.parse(strDate, dtf);
            return dtf.format(date);
        } catch (DateTimeParseException dtpe) {
            return "Date";
        }
    }

    static String formatDateWithPattern2(String strDate) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MM-uuuu");
        try {
            LocalDateTime date = LocalDateTime.parse(strDate, dtf);
            return dtf.format(date);
        } catch (DateTimeParseException dtpe) {
            return "Date";
        }
    }
}

Output:

Date
Date

Moral of the story

  1. The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. Stop using them completely and switch to the modern date-time API. Learn about the modern date-time API at Trail: Date Time.
  2. Stick to the format in your input date-time string while parsing it. If you want the output in a different format, use a differnt instance of the parser/formatter class.

Demo:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

class Main {
    public static void main(String[] args) {
        String strDateTime = "2010-09-29 08:45:22";
        DateTimeFormatter dtfForParsing = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
        LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtfForParsing);
        System.out.println(ldt);// The default format as returned by LocalDateTime#toString

        // Some custom formats for output
        System.out.println("########In custom formats########");
        DateTimeFormatter dtfForFormatting1 = DateTimeFormatter.ofPattern("dd-MM-uuuu HH:mm:ss");
        DateTimeFormatter dtfForFormatting2 = DateTimeFormatter.ofPattern("dd-MM-uuuu");
        DateTimeFormatter dtfForFormatting3 = DateTimeFormatter.ofPattern("'Day: 'EEEE, 'Date: 'MMMM dd uuuu");
        System.out.println(dtfForFormatting1.format(ldt));
        System.out.println(dtfForFormatting2.format(ldt));
        System.out.println(dtfForFormatting3.format(ldt));
        System.out.println("################################");
    }
}

Output:

2010-09-29T08:45:22
########In custom formats########
29-09-2010 08:45:22
29-09-2010
Day: Wednesday, Date: September 29 2010
################################
Arvind Kumar Avinash
  • 50,121
  • 5
  • 26
  • 72
0

It took a lot of efforts. I did a lot of hit and trial and finally I got the solution. I had used ""MMM"" for showing month as: JAN

SFDCCoder
  • 25
  • 4
0

If you looking for date, month and year separately

or how to use letters from answer of heloisasim

    SimpleDateFormat day = new SimpleDateFormat("d");
    SimpleDateFormat month = new SimpleDateFormat("M");
    SimpleDateFormat year = new SimpleDateFormat("y");

    Date d = new Date();
    String dayS = day.format(d);
    String monthS = month.format(d);
    String yearS = year.format(d);
Makarand
  • 623
  • 4
  • 16
0
public String formatDate(String dateString) {
    SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
    Date date = null;
    try {
        date = fmt.parse(dateString);
    } catch (ParseException e) {
        e.printStackTrace();
    }

    SimpleDateFormat fmtOut = new SimpleDateFormat("dd-MM-yyyy");
    return fmtOut.format(date);
}
  • Welcome to SO. (1) Thanks for wanting to contribute. (2) We shouldn’t use `SimpleDateFormat` and `Date` anymore, but java.time, the modern Java date and time API. (3) Are you contributing much that isn’t already in more than one other answer? (4) Please give some explanation aling with your code, and we will generally learn a lot more. – Ole V.V. Dec 10 '20 at 17:55