I am confused with time handling in java time. I so long worked under the assumption that if a timestamp is specified as a zulu time, java would take care of the offset with regards to local time.
To illustrate. I am currently in BST which has an offset of UTC +1. With that in mind, I would expect this zulu time:
2016-09-12T13:15:17.309Z
to be
2016-09-12T14:15:17.309 
LocalDateTime after parsing it. This is because my default systemtime is set to BST and the above timestamp (zulu time) specifies that it is a UTC time.
Instead however consider this sample:
        String ts = "2016-09-12T13:15:17.309Z";
        LocalDateTime parse = LocalDateTime.parse(ts, DateTimeFormatter.ISO_DATE_TIME);
        System.out.println(parse);
This will print:
2016-09-12T13:15:17.309
So the timestamp, parsed as a LocalDateTime, is not recognised as UTC time and instead treated as localtime directly. So I thought, maybe I need to parse it as a ZonedDateTime and convert it to LocalDateTime specifically in order to get the correct local time. With this test:
        String ts = "2016-09-12T13:15:17.309Z";
        ZonedDateTime parse = ZonedDateTime.parse(ts, DateTimeFormatter.ISO_DATE_TIME);
        System.out.println(parse);
        System.out.println(parse.toLocalDateTime());
I get the outputs:
2016-09-12T13:15:17.309Z
2016-09-12T13:15:17.309
Same output for both dates.
The only way to correctly parse this that I could find, is:
    String ts = "2016-09-12T13:15:17.309Z";
    Instant instant = Instant.parse(ts); // parses UTC
    LocalDateTime ofInstant = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    System.out.println(instant);
    System.out.println(ofInstant);
This prints:
2016-09-12T13:15:17.309Z
2016-09-12T14:15:17.309
Which is correct.
So the question(s) are:
LocalDateTime#parse approach to get the correct result? Instant for everything now and discard the parsing? The issue is that jersey/jackson's java time modules parse the timestamps using the ISO format and the regular LocalDateTime#parse methods. I realised that my times are no off since they are being treated as LocalTime while in fact they are in Zulu time. 
You are misunderstanding the purpose of LocalDateTime.
To quote the class documentation:
A date-time without a time-zone in the ISO-8601 calendar system, such as {@code 2007-12-03T10:15:30}.
…
This class does not store or represent a time-zone. Instead, it is a description of the date, as used for birthdays, combined with the local time as seen on a wall clock. It cannot represent an instant on the time-line without additional information such as an offset or time-zone.
So it's explicit purpose is just to represent a date and time without a time-zone. It's porpose is not to represent a date and time in the local time zone.
Therefore each conversion just strips the time zone.
So for your purposes you need a ZonedDateTime with ZoneId.systemDefault() as you already used in your third example.
For your second example this could be:
String ts = "2016-09-12T13:15:17.309Z";
ZonedDateTime parse = 
    ZonedDateTime.parse(ts, DateTimeFormatter.ISO_DATE_TIME)
        .withZoneSameInstant(ZoneId.systemDefault());
System.out.println(parse);
System.out.println(parse.toLocalDateTime());
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With