Search code examples
javajava-8java-timedate-conversion

Convert XMLGregorianCalendar in GMT to LocalDateTime Pacific time


I'm trying to convert XMLGregorianCalendar which is sent in GMT/UTC format to Java 8 LocalDateTime in America/Los_Angeles timezone with no luck.

Here is what I tried and couldn't get the time converted to Pacific time.

//xmlDate is 2017-11-13T00:00:00Z
ZonedDateTime zDateTime = xmlDate.toGregorianCalendar().toZonedDateTime().toLocalDateTime().atZone(ZoneId.of("America/Los_Angeles"));
LocalDateTime localDateTime = zDateTime.toLocalDateTime(); 
//Expected localDateTime is 2017-11-12T16:00. But I only get 2017-11-13T00:00

What am I missing?


Solution

  • atZone() does not do what you think it does. It merely attaches a timezone to a date without preserving the instant in time. You must do it using ZonedDateTime#withZoneSameInstant(), which keeps the instant and modifies the zone:

    public static void main(String[] args) throws Exception {
        XMLGregorianCalendar xc = DatatypeFactory.newInstance().newXMLGregorianCalendar(2017, 10, 13, 0, 0, 0, 0, 0);
        System.out.println(xc);
        GregorianCalendar gc = xc.toGregorianCalendar();
        System.out.println(gc);
        ZonedDateTime zdt = gc.toZonedDateTime();
        System.out.println(zdt);
        LocalDateTime ldt = zdt.withZoneSameInstant(ZoneId.of("America/Los_Angeles")).toLocalDateTime();
        System.out.println(ldt);
    }