-1

I want to convert below date into AEST format using Java.

2018-01-08T02:10:24.000+0000w

Below is the code which i am using for to convert .

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSzzz");
ZonedDateTime zdt = ZonedDateTime.parse(
        map.get("records-LastModifiedDate").toSt‌​ring().trim()); 
System.out.println(zdt);

There is something wrong with the pattern? Please suggest.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
user1734980
  • 45
  • 2
  • 11
  • 1
    Have you tried looking at [`DateTimeFormatter`](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html) and/or [Parsing and Formatting](https://docs.oracle.com/javase/tutorial/datetime/iso/format.html)? Basic answer is, parse the `String` to a date/time value, the format it to the required fomat – MadProgrammer Jan 23 '18 at 23:10
  • 1
    I have tried to convert using below code.`DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSzzz"); ZonedDateTime zdt = ZonedDateTime.parse(map.get("records-LastModifiedDate").toSt‌​ring().trim()); System.out.println(zdt)`.This is not working. – user1734980 Jan 23 '18 at 23:26
  • Your question is already answered here; https://stackoverflow.com/questions/36473928/parse-date-with-aedt-and-aest-time-zone-in-java – Reyeselda95 Jan 23 '18 at 23:27
  • 1
    @user1734980 Add further info as edits to your Question rather than by posting comments. – Basil Bourque Jan 23 '18 at 23:44
  • There’s a `w` at the end of your date-time string? What does it signify? Never seen that in a date-time format before. – Ole V.V. Jan 24 '18 at 04:51
  • In what way “not working”, please? Specify error message (verbatim), stack trace and/or precise difference between expected and actual results. “Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers.” Quoted from [What topics can I ask about here?](https://stackoverflow.com/help/on-topic) – Ole V.V. Jan 24 '18 at 07:59

2 Answers2

5

You have to use the formatter when parsing the date string. Also you need to tell it to change the zone or zone offset to get it into AEST/AEDT.

This might work:

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXX"); 
ZonedDateTime zdt = OffsetDateTime.parse(input, dtf)
    .atZoneSameInstant(ZoneId.of("Australia/Sydney"));
String dateInTimeZone = zdt.format(dtf);

The offset will appear as "+1000" or "+1100" depending on the time of year.

Hank D
  • 6,271
  • 2
  • 26
  • 35
  • It works if I leave out the `w` from the string in the question. With the `w` I get `java.time.format.DateTimeParseException: Text '2018-01-08T02:10:24.000+0000w' could not be parsed, unparsed text found at index 28`. – Ole V.V. Jan 24 '18 at 08:05
0

The accepted answer by @HankD is a good one. Since I find myself sometimes linking to this question (typically from duplicates), I should like to provide an alternative and a little further information.

My assumptions

  • AEST is not a format. It’s a time zone abbreviation, and while four letter time zone abbreviations are often ambiguous, I believe we can take AEST to be Australian Eastern Standard Time, the time used in the Australia/Sydney time zone during standard time (what you want during summer time (DST) is not perfectly clear).
  • I am assuming that the trailing w of your date and time string is a typo. Without it your format becomes ISO 8601, which makes all the sense in the world. I have never seen such a w in a date time string elsewhere.

Two ways to construct a formatter

For the sake of completeness I should like to present two ways you may built a formatter that can parse your string, each with their pros and cons.

1. Reusing built-in functionality

    String lastModifiedString = "2018-01-08T02:10:24.000+0000";

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral('T')
            .append(DateTimeFormatter.ISO_LOCAL_TIME)
            .appendOffset("+HHmm", "Z")
            .toFormatter();

    OffsetDateTime odt = OffsetDateTime.parse(lastModifiedString, formatter);

    ZonedDateTime zdt = odt.atZoneSameInstant(ZoneId.of("Australia/Sydney"));
    System.out.println(zdt);

Output:

2018-01-08T13:10:24+11:00[Australia/Sydney]

Pro: Probably the clearer to read and less error-prone. More flexible: accepts presence and absence of seconds and up to 9 decimals of fractional seconds (or you may consider this a disadvantage if you want the strictest possible validation of your string). Con: wordier.

2. Writing a format pattern string

The other way to construct the formatter is the one also use in the other answer:

    DateTimeFormatter formatter
            = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSXX");

The rest of the code is the same, and so is the output. Pro: brief. Con: More error-prone and less straight-forward to read. Inflexible: requires exactly three decimals on the seconds.

As an aside, while the classes of java.time generally parse the most common ISO 8601 format variants without any explicit formatter, the variant where there is no colon in the offset ( +0000 rather than +00:00) is the most prominent exception. So given that we don’t want to hand manipulate the input string, constructing a custom formatter in one of the two ways shown is our best bet.

There is something wrong with the pattern?

Yes, using zzz doesn’t work for parsing an offset. According to the documentation (link at the bottom) , lowercase z is for time zone name such as Australian Eastern Standard Time or AEST. For an offset like +0000 you need either uppercase X, lowercase x or uppercase Z.

Links

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