将 GMT 中的 XMLGregorianCalendar 转换为 LocalDateTime 太平洋时间

Convert XMLGregorianCalendar in GMT to LocalDateTime Pacific time

我正在尝试将以 GMT/UTC 格式发送的 XMLGregorianCalendar 转换为 Java 8 LocalDateTime America/Los_Angeles 时区,但没有成功。

这是我尝试过但无法将时间转换为太平洋时间的方法。

//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

我错过了什么?

atZone() 并不像您认为的那样。它只是将时区附加到日期而不保留时间。您必须使用 ZonedDateTime#withZoneSameInstant() 来完成它,它会保持即时并修改区域:

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);
}

使用 DateTimeFormatter 模式明确定义日期和时间格式,并定义 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));

输出日期和时间:2017-11-12T16:00