By EricBoersma


2010-08-24 19:29:03 8 Comments

I'm working on taking a date value (createWhen) from Active Directory, and translating it into a Java date, for the purposes of getting a list of accounts created between two dates. Everything is working fine, save for one method: the method where I go from the AD Date to the Java date. The method looks like this:

private Date getParsedDate(String givenString) {
    System.out.println("Value from AD is: " + givenString);
    Date parsedDate = null;
    String formattedString = this.formatDateString(givenString);
    System.out.println("Formatted String is: " + formattedString);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/DD");
    try {
        parsedDate = sdf.parse(formattedString);
        System.out.println("Final date string is: " + parsedDate.toString());
    } catch (ParseException ex) {
        ex.printStackTrace();
    }
    return parsedDate;
}

And, for a single piece of arbitrary data from AD:

Value from AD is: 20050912190509.0Z

Formatted String is: 2005/09/12

Final date string is: Wed Jan 12 00:00:00 EST 2005

Obviously, it's picking up the day and year correctly (and if I choose to include hours/minutes/seconds it includes those correctly as well), but every single date is being placed in January for some reason.

Now, I'm sure that my error is a pretty simple one, but I've rechecked my formatting about ten times, and I'm at the point where I just can't see it any more. Can a second pair of eyes hopefully look over my code and point out where I'm going wrong to get the month so grossly incorrect?

Thanks.

4 comments

@Manti_Core 2020-03-01 08:11:18

I am posting this answer because i was redirected from here and above solutions did not resolve my issue

For me the scenario was that after parsing this date "2020-03-01T07:00:00+0530" i was getting the result as 1/2 [dd/MM] which is the format that i wanted, but that result contained the wrong month since the date string clearly indicates the month is 3 [MARCH].

So basically cal.get(Calendar.DAY_OF_MONTH) was returning me 2 instead of actual 3.

And as per docs in MONTH section

"the first month of the year in the Gregorian and Julian calendars is JANUARY which is 0; the last depends on the number of months in a year."

so we just need to add a +1 and we would get the actual month. Guess this behavior is there may be to return the names of month from month array or so ?! [January,February,etc..]

Below is a sample of my implementation (my date format in string is "yyyy-MM-dd'T'HH:mm:ssZ"):

Calendar cal = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat(Constant.DATE_FORMAT_WITH_TIMEZONE,Locale.ENGLISH);
            try {               
                cal.setTime(Objects.requireNonNull(sdf.parse(forecastList.get(listPosition).fcst_valid_local)));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            String s = "%s/%d";
            String output = String.format(s,cal.get(Calendar.DAY_OF_MONTH),(cal.get(Calendar.MONTH)+1)));

hope this helps some one.

@Ole V.V. 2017-12-11 11:08:45

TL;DR

    LocalDate parsedDate = OffsetDateTime
            .parse("20050912190509.0Z", DateTimeFormatter.ofPattern("uuuuMMddHHmmss.SX"))
            .toLocalDate();

This yields a LocalDate of 2005-09-12.

java.time

I am contributing the modern answer. Suhas Phartale’s answer is correct and was a good answer when it was written 7 years ago. Now the notoriously troublesome SimpleDateFormat class is long outdated and we have so much better in java.time, the modern Java date and time API. I warmly recommend you use this instead of the old date-time classes.

Details

It seems from your code that you reformat your string from AD before parsing it. There’s no need for that, the string from AD can be parsed directly. We might have parsed it directly into a LocalDate, but I recommend parsing it into an OffsetDateTime to grab the time and offset from the string; as you can see, this can be directly converted to a LocalDate afterwards. A LocalDate is a date without time of day, so it seems to match your requirements better than the old Date class.

The string is in UTC (denoted by the Z in the end). The above gives you the date from the string, that is the date in UTC. If instead you wanted the date it was in your local time zone when it was September 12 19:05 in UTC:

    LocalDate parsedDate = OffsetDateTime.parse(givenString, adDateTimeFormatter)
            .atZoneSameInstant(ZoneId.of("America/Coral_Harbour"))
            .toLocalDate();

I assumed we have declared the formatter a static field:

private static final DateTimeFormatter adDateTimeFormatter
        = DateTimeFormatter.ofPattern("uuuuMMddHHmmss.SX");

In this case the result is the same, for other time zones it will not be. Please substitute your own desired time zone for America/Coral_Harbour. To use the JVM’s time zone setting, specify ZoneId.systemDefault(). Beware, however, that the setting may be changed by other parts of your program or other programs running in the same JVM, so this is fragile.

And the point from Suhas Phartale’s answer is valid in java.time too: format pattern strings are case sensitive, and I needed to use lowercase dd for day of month.

Tutorial

Learn more about java.time in the Oracle tutorial and/or search for other resources on the net.

@Ridhuvarshan 2016-07-13 05:53:13

Make sure you don't use 'mm' instead of 'MM' or 'MMM'. As small m denotes minutes and caps M denotes month.

@Suhas Phartale 2010-08-24 19:41:37

Change the pattern string from "yyyy/MM/DD" to "yyyy/MM/dd"

SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");

@EricBoersma 2010-08-24 19:43:36

That fixed it, thanks. Apparently the page Google gave me was giving me incorrect documentation. That's what I get for not going to the source.

@Hossein Amini 2016-04-17 05:23:21

perfect solution, for me changing from mm to MM worked great

Related Questions

Sponsored Content

88 Answered Questions

[SOLVED] Is Java "pass-by-reference" or "pass-by-value"?

8 Answered Questions

[SOLVED] What is this date format? 2011-08-12T20:17:46.384Z

44 Answered Questions

[SOLVED] How do I convert a String to an int in Java?

43 Answered Questions

[SOLVED] How do I efficiently iterate over each entry in a Java Map?

33 Answered Questions

[SOLVED] When to use LinkedList over ArrayList in Java?

58 Answered Questions

[SOLVED] How to create a memory leak in Java?

28 Answered Questions

66 Answered Questions

[SOLVED] How do I generate random integers within a specific range in Java?

  • 2008-12-12 18:20:57
  • user42155
  • 4109306 View
  • 3549 Score
  • 66 Answer
  • Tags:   java random integer

49 Answered Questions

[SOLVED] Does a finally block always get executed in Java?

59 Answered Questions

[SOLVED] How do I read / convert an InputStream into a String in Java?

Sponsored Content