如何将Java中的时间对象格式化为正确的时区

问题描述

我想使用Java Time API来获取中欧夏令时(CEST)并正确设置其格式。我有以下代码:

LocalDateTime localDateTime= LocalDateTime.now();
DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
localDateTime.format(myFormatObj);
ZoneId europeBerlin = ZoneId.of("Europe/Berlin");
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime,europeBerlin);

命令zonedDateTime.toString()转至以下输出:

2020-09-27T08:42:33.660+02:00[Europe/Berlin]

但是我希望有一个在DateTimeFormatter中指定的输出(“ dd-MM-yyyy HH:mm:ss”)。我已经将localDateTime格式化为这种格式,现在我只想获取CEST时间。我怎样才能做到这一点?我会很感激每个评论。

解决方法

请注意,Java Time API中的日期时间对象是不可变的。因此,每当您要修改现有的日期时间实例时,都会返回一个新的新副本,而旧的副本则保持不变。

还有一个小的优化:DateTimeFormatter是线程安全的。因此,由于格式是恒定的,因此无需每次都构造一个新实例。您可以像这样在顶部声明它:

private static final DateTimeFormatter FORMATTER;

static {
    FORMATTER = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
}

要打印格式化的String,请使用以下命令:

LocalDateTime localDateTime = LocalDateTime.now();
ZoneId europeBerlin = ZoneId.of("Europe/Berlin");
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime,europeBerlin);

// please note that #format has a return value
// originally,you called 'localDateTime.format(myFormatObj);' while ignoring
// the return value
String formatted = FORMATTER.format(zonedDateTime);

System.out.println(formatted); // e.g. 27-09-2020 11:44:27

编辑1:关于线程安全 线程安全性是指何时可以由多个线程安全地同时使用一个对象而又不破坏该类的内部结构。如果一个类是线程安全的,则可以同时从多个线程调用它(因此您不必每次都创建一个新实例,而只需创建一个)。如果类不是线程安全的,则每个线程都需要一个新的实例。

,
    DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
    ZoneId europeBerlin = ZoneId.of("Europe/Berlin");
    ZonedDateTime zonedDateTime = ZonedDateTime.now(europeBerlin);
    
    String formattedDateTime = zonedDateTime.format(myFormatObj);
    System.out.println(formattedDateTime);

刚才在UTC时区运行时的输出:

27-09-2020 20:33:53

我们得到了柏林时间(不是UTC时间)。

您的代码出了什么问题?

两件事:

  1. LocalDateTime.now()为您提供JVM默认时区中的当前时间。看来这不是Eurpoe / Berlin(也许是UTC,可能还有其他)。然后ZonedDateTime.of(localDateTime,europeBerlin)采用该日期和时间,并声称这是欧洲/柏林时区,这是错误的,也是您得出错误结果的原因。您通常不需要LocalDateTime类,实际上也不需要no-arg LocalDateTime.now()方法。
  2. 要以特定格式获取时间,您需要将日期和时间格式化为字符串。 LocalDateTimeZonedDateTime对象没有任何格式。

链接

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...