0

I was trying to create a date object from a string of the format "9/2/2004”

Here's my code:

//Set Date
String[] date_array = record[0].split("/");
Date date = new GregorianCalendar(Integer.parseInt(date_array[2]), Integer.parseInt(date_array[1]),
     Integer.parseInt(date_array[0])).getTime();

However, when I was trying to output date object, it printed as:

Tue Mar 09 00:00:00 EST 2004

And 4/20/2004 printed as:

Sun Sep 04 00:00:00 EDT 2005

Question: What's going on here? What went wrong?

sai y
  • 1
  • 1
    You have your day and month transposed (assuming US date format), and the `GregorianCalendar` month index is (unfortunately) 0 based, so you have to add 1. – teppic Sep 10 '18 at 03:14
  • Possible duplicate of [Java string to date conversion](https://stackoverflow.com/questions/4216745/java-string-to-date-conversion) (and many other questions, please search if you need more inspiration). – Ole V.V. Sep 10 '18 at 08:41
  • I recommend you avoid the classes `Date` and `GregorianCalendar`. They are not only long outdated, they are also poorly designed. Today we have so much better in [`java.time`, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). This also means I recommend you ignore the four answers posted until now, all of which use `Date` and the even more troublesome class `SimpleDateFormat`. – Ole V.V. Sep 10 '18 at 08:43

5 Answers5

2

You don't need to split the String to extract date, month and year separately. What you can do is that parse this Date string using SimpleDateFormat:

String dateStr = "9/2/2004"; // I assume it is in dd/MM/yyyy format
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
Date date = format.parse(dateStr);
Mushif Ali Nawaz
  • 3,707
  • 3
  • 18
  • 31
1

The order of arguments (from the Javadoc) is GregorianCalendar(int year, int month, int dayOfMonth) - and you are passing year then day then month. You also need to account for January being 0. Like,

String record = "4/20/2004";
String[] date_array = record.split("/");
Date date = new GregorianCalendar(Integer.parseInt(date_array[2]), 
        Integer.parseInt(date_array[0]) - 1, 
        Integer.parseInt(date_array[1])).getTime();
System.out.println(date);
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
1

why don't use DateTimeFormat to parse your date time text. Try it:

String text = "9/2/2004";
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
Date dt = format.parse(text);
Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
Tran Ho
  • 1,442
  • 9
  • 15
0

Simply use DateTimeFormat to parse your string date time :

String dateInString = "9/2/2004";
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
try {
  Date date = formatter.parse(dateInString);
} catch (ParseException e) {
  e.printStackTrace();
}
imk
  • 374
  • 6
  • 12
0

Question: What's going on here? What went wrong?

Two basic things went wrong:

  1. You tried to hand parse your date string. The recommended way is to use a library method for parsing dates.
  2. You used the wrong classes. Date and GregorianCalendar are long outdated and no more recommended, also because they were always poorly designed. Furthermore despite their names they don’t represent dates (a Date is a point in time, while GregorianCalendar is a date and a time in a particular time zone).

It’s very easy to get things wrong with those old classes, so no wonder you did too, thousands have done before you (just look at how many Stack Overflow questions tesitify to this). What went on more concretely: you correctly passed the numbers 2004, 2 and 9 to the GregorianCalendar constructor. That constructor takes the arguments to be year, month and day in that order. It furthermore confusingly assumes a 0-based month, where 0 means January, so 2 means March. Hence you get March 9, 2004 at 00:00:00 in your JVM’s default time zone.

But 4/20/2004, then? When months are 0 through 11, 20 cannot be a month. A GregorianCalendar with default settings doesn’t care, it just extrapolates and keeps counting months into the following year. So month 11 would have been December 2004, month 12 would be January 2005, etc., so we end up with month 20 being September 2005.

What to do instead?

The modern solution to your problem is:

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/u");
LocalDate date = LocalDate.parse("9/2/2004", dtf);
System.out.println(date);

Output is:

2004-09-02

M/d/u is a format pattern string specifying that your format consists of month, day of month and year separated by slashes. Be aware that format pattern strings are case sensitive: you need uppercase M and lowercase d and u. All the possible format letters are in the documentation.

Links

Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161