LocaleDateTime atZone格式忽略不同的时区



我的代码似乎有问题。我期望在我的输出中有不同的时间-一个从UTC转换为德国时间,一个转换为巴西东部时间,但我总是得到相同的UTC时间输出。

我代码:

LocalDateTime localDateTime = resource.getDateOfManufacture();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy_HH-mm-ss", Locale.getDefault());      
ZoneId zoneDE = ZoneId.of("Europe/Berlin");
ZoneId zoneBR = ZoneId.of("Brazil/East");

System.out.println("TIME --------------------------------------------------------------------");

System.out.println(localDateTime);

System.out.println(localDateTime.atZone(zoneDE));
System.out.println(localDateTime.atZone(zoneBR));
System.out.println(localDateTime.atZone(zoneDE).format(dateTimeFormatter));
System.out.println(localDateTime.atZone(zoneBR).format(dateTimeFormatter));

我的实际输出:

13:06:43,890 INFO  [stdout] (EJB default - 2) TIME --------------------------------------------------------------------
13:06:43,904 INFO  [stdout] (EJB default - 2) 2016-05-31T22:00
13:06:43,907 INFO  [stdout] (EJB default - 2) 2016-05-31T22:00+02:00[Europe/Berlin]
13:06:43,908 INFO  [stdout] (EJB default - 2) 2016-05-31T22:00-03:00[Brazil/East]
13:06:43,913 INFO  [stdout] (EJB default - 2) 31-05-2016_22-00-00
13:06:43,917 INFO  [stdout] (EJB default - 2) 31-05-2016_22-00-00

My expectations(关于最后两行):

13:06:43,890 INFO  [stdout] (EJB default - 2) TIME --------------------------------------------------------------------
13:06:43,904 INFO  [stdout] (EJB default - 2) 2016-05-31T22:00
13:06:43,907 INFO  [stdout] (EJB default - 2) 2016-05-31T22:00+02:00[Europe/Berlin]
13:06:43,908 INFO  [stdout] (EJB default - 2) 2016-05-31T22:00-03:00[Brazil/East]
13:06:43,913 INFO  [stdout] (EJB default - 2) 01-06-2016_00-00-00
13:06:43,917 INFO  [stdout] (EJB default - 2) 31-05-2016_19-00-00

您的代码只是在本地日期时间中添加了一个区域,该区域没有区域。前两行显示了这些结果是什么。你的日期时间格式化程序也不会做任何特别的事情,它们只是格式化所有内容,但忽略区域。

您可能存在的误解是,您可能认为本地日期时间表示UTC的日期时间。。它们是年、月、日、时、分、秒和纳米的简单组合。

您期望的输出显示,如果localDateTime在UTC中,您希望在另一个时区中获得相应的日期时间。你实际上是在问,假设我将在UTC的这个日期举办一个聚会,我需要生成什么字符串,以便我可以告诉我在柏林和巴西的朋友来参加聚会?

一种方法是在区域UTC处获得ZonedDateTime,然后设置日期时间格式化程序的区域:

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy_HH-mm-ss", Locale.getDefault()); 
ZoneId zoneDE = ZoneId.of("Europe/Berlin");
ZoneId zoneBR = ZoneId.of("Brazil/East");
DateTimeFormatter formatterDE = dateTimeFormatter.withZone(zoneDE);
DateTimeFormatter formatterBR = dateTimeFormatter.withZone(zoneBR);
System.out.println(localDateTime.atZone(ZoneOffset.UTC).format(formatterDE));
System.out.println(localDateTime.atZone(ZoneOffset.UTC).format(formatterBR));

ZonedDateTime#withZoneSameInstant

使用它来获得具有不同时区的日期时间的副本,保留即时。您需要在UTC处将LocalDateTime转换为ZonedDateTime,然后应用.withZoneSameInstant(zoneId),如下所示:

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy_HH-mm-ss", Locale.ENGLISH);
ZoneId zoneDE = ZoneId.of("Europe/Berlin");
ZoneId zoneBR = ZoneId.of("Brazil/East");
LocalDateTime ldt = LocalDateTime.parse("2016-05-31T22:00");
System.out.println(ldt);
// Date-time in Europe/Berlin
ZonedDateTime zdtDE = ldt.atZone(ZoneOffset.UTC).withZoneSameInstant(zoneDE);
System.out.println(zdtDE.format(dateTimeFormatter));
// Date-time in Brazil/East
ZonedDateTime zdtBR = ldt.atZone(ZoneOffset.UTC).withZoneSameInstant(zoneBR);
System.out.println(zdtBR.format(dateTimeFormatter));
}
}

输出:

2016-05-31T22:00
01-06-2016_00-00-00
31-05-2016_19-00-00

最新更新