-3

I have played with this for almost 6 hours now and looked at other questions but can't seem to figure out what I'm doing wrong that is giving me these odd results. Here is my code below

    String dateStr = "20171230";
    StringBuilder sb = new StringBuilder();
    sb.append(dateStr.subSequence(0, 4))
        .append("/")
        .append(dateStr.substring(4,6))
        .append("/")
        .append(dateStr.substring(6,8));

    dateStr = sb.toString();

    System.out.println("date string is " + dateStr);

    DateFormat df = new SimpleDateFormat("yyyy/mm/dd");

    df.setLenient(false);

    Date Date = null;

    try {
        Date = df.parse(dateStr);
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    System.out.println("Date is " + Date);

output is

date string is 2017/12/30
Date is Mon Jan 30 00:12:00 CST 2017

The date should be December 30, not January 30. Can someone tell my why this is happening.

Mason
  • 1,662
  • 1
  • 9
  • 10

2 Answers2

1

The format you passed one simple date format has minutes defined where you think the month is.

Notice how the time output is set too 00:12.

Instead, use yyyy/MM/dd

Trenton Trama
  • 4,890
  • 1
  • 22
  • 27
0

Allow me to give a couple of suggestions that go a bit beyond exactly what you asked about. I think my suggestions should be helpful.

First, you shouldn’t want to stick to the long outdated classes Date and SimpleDateFormat. The modern Java date and time API is generally much nicer to work with and contains fewer unpleasant surprises. It is known as JSR-310 or java.time.

Second, there should be no need to reformat your string using a StringBuilder before extracting the date from it. 20171230 can be parsed into a date directly. Even worse, the way you are converting the string, you are not validating the length: if there happened to be 9 digits instead of 8, you would want to catch it and throw an exception, but your code just takes the first 8 digits and ignores if there are more.

Finally, as Trenton Trama already pointed out in the other answer, format pattern strings are case sensitive. It matters whether and where you use uppercase or lowercase letters. Using the incorrect case will most likely lead to incorrect results. This goes for both the outdated and the modern API. Fortunately, when it comes to parsing, the modern API is much more inclined to throw an exception when you use the wrong case so at least you are informed something is wrong.

And finally-finally, when you want someone else to read your code, like other stackoverflowers, use the coding conventions to help us. Variable names begin with a lowercase letter. It’s particularly confusing when you have a class named Date and a variable also named Date.

The above sums up to:

    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuuMMdd");
    String dateStr = "20171230";
    LocalDate date = LocalDate.parse(dateStr, dtf);
    System.out.println("Date is " + date);

Output is:

Date is 2017-12-30

Question: Can I use the modern API with my Java version?

If using at least Java 6, you can.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161