1

I am trying to convert a String with format 1/1/2010 3:23:12 PM +00:00 to a Java.util.Date

Unable to convert the String format to a Java Date. It is not identifying the time asAM/PM

String s = "1/1/2010 3:23:12 PM +00:00";
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss a",Locale.ENGLISH);

Date date = sdf.parse(s));

Need the date converted with time identified as AM/PM

user3837868
  • 917
  • 1
  • 12
  • 24
user1767444
  • 39
  • 1
  • 9
  • 4
    You should **drop** the usage of `Date`, `Calendar` and `SimpleDateFormat` classes immediately and switch to the newer Java Date and Time API within the `java.time` package. [Here's why](https://stackoverflow.com/questions/1969442/whats-wrong-with-java-date-time-api). – MC Emperor May 28 '19 at 22:23
  • Can you give me an example? i tried like below but it still doesnot parse the format that i have: DateTimeFormatter formatter = DateTimeFormatter.ISO_ZONED_DATE_TIME; final ZonedDateTime parsed = ZonedDateTime.parse(s, formatter.withZone(ZoneId.of("UTC"))); System.out.println("************"+parsed); – user1767444 May 28 '19 at 22:34
  • 2
    [java parse string to localdatetime](https://www.google.com/search?client=safari&rls=en&q=java+parse+string+to+localdatetime&ie=UTF-8&oe=UTF-8) and the [JavaDocs for `DateTimeFormatter`](https://docs.oracle.com/javase/10/docs/api/java/time/format/DateTimeFormatter.html) would be better places to start – MadProgrammer May 28 '19 at 22:46
  • 1
    You can't. An old-fashioned `Date` is a point in time, nothing more. It never identifies time as AM or PM. That‘s what we have formatters for. – Ole V.V. May 29 '19 at 04:16

2 Answers2

2

OffsetDateTime is what you're looking for.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/M/yyyy h:mm:ss a XXX");
OffsetDateTime time = OffsetDateTime.parse(str, formatter);
System.out.println(time);

Your pattern has some problems:

  • Your day-of-the-month is without a leading zero, yet you are using dd;
  • Same for month with MM;
  • Same for hour with HH;
  • You are using AM/PM in conjunction with a 24-hour hour format specifier (H); you should use h instead.

I don't know exactly how SimpleDateFormat handles the timezone part of the string, but no formatting specifiers for the timezone are given.

That's one of the reasons why I like this Date and Time API: it's pretty straightforward.

MC Emperor
  • 22,334
  • 15
  • 80
  • 130
  • Good catch: the uppercase `HH` in the questioner’s format pattern string causes the time to be parsed incorrectly (in this case into AM even though the string says PM). One more confusing trait of `SimpleDateFormat`, one more reason why we never ever want to use that class again. And you are correct: we need to parse the offset, `+00:00`, too, or we will most likely get an incorrect time (which in turn may also render AM/PM incorrect). – Ole V.V. May 29 '19 at 07:29
0

Unable to convert the String format to a Java Date. It is not identifying the time as AM/PM

You are asking the impossible. A Date is a point in time (internally implemented as a count of milliseconds since the so-called epoch), so it “knows” nothing about AM and PM in your time zone.

That’s just the same, though, because the Date class was always poorly designed and is fortunately long outdated. You should not use it at all.

java.time

java.time, the modern Java date and time API that we should use instead of Date, comes closer to fulfilling your requirement. MC Emperor has already shown the basic code you need for parsing your datetime string. The output from his code is:

2010-01-01T15:23:12Z

There’s no AM or PM here. When we print an OffsetDateTime in this way, its toString method is implicitly called. It produces an ISO 8601 formatted string. ISO 8601 prescribes a 24 hour clock (no AM or PM). But! With assistance from the correct TemporalField object the OffsetDateTime is able to calculate and return whether it is in AM or PM. time.get(ChronoField.AMPM_OF_DAY) returns 0 for AM or 1 for PM:

    System.out.println("AM or PM? 0 for AM. 1 for PM. time: "
            + time.get(ChronoField.AMPM_OF_DAY));

AM or PM? 0 for AM. 1 for PM. time: 1

So in this case we got 1 for PM as expected since your original string had PM in it.

I have deliberately not answered all of your question because much of it has been covered in other Stack Overflow questions and their answers already. So it’s better to keep the information there. I include links to a couple of relevant questions below.

What went wrong in your code?

There are at least two bugs in your code that each cause you to get an incorrect result. I tried running your code in America/Los_Angeles time zone and got

Fri Jan 01 03:23:12 PST 2010

The time printed is on a 24 hour clock (Date always does that), so we got 03:23:12 AM instead of PM. And we got the time in the default time zone (PST is for Pacific Standard Time), so the point in time corresponds to 11:23:12 AM at offset +00:00, the offset in the string.

  • The wrong clock hour comes from conflicting indications in your code: HH in the format pattern string is for hour of day from 00 through 23, so 3 is taken to mean 03 AM and apparently “wins” over the PM marker (for hour within AM or PM, from 1 through 12, you would have needed lowercase h).
  • The default time zone comes from the fact that you are making no attempt to parse the offset from the string (in conjunction with SimpleDateFormat being satisfied with not parsing all of the string).

Links

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