问题
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?
回答1:
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);
}
回答2:
Use DateTimeFormatter pattern to clearly define the date and time format, and with defined zoneId.
String xmlDate = "2017-11-13T00:00:00Z";
DateTimeFormatter formatInput =DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'").withZone(ZoneId.of("UTC"));
DateTimeFormatter formatOutput =DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm").withZone(ZoneId.of("America/Los_Angeles"));
ZonedDateTime zoned = ZonedDateTime.parse(xmlDate,formatInput);
System.out.println("Output date and time: "+formatOutput.format(zoned));
Output date and time: 2017-11-12T16:00
来源:https://stackoverflow.com/questions/47245272/convert-xmlgregoriancalendar-in-gmt-to-localdatetime-pacific-time