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

huangapple go评论142阅读模式
英文:

How to format time objects in Java into the correct timezone

问题

我想使用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时间。我应该如何做?我会感激每一个意见。

英文:

I want to use the Java Time API to get the central Europen summer time (CEST) and format it correctly. I have the following code:

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

The command zonedDateTime.toString()leaves to the following output:

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

But I would like to have an output as specified before in the DateTimeFormatter ("dd-MM-yyyy HH:mm:ss"). I have already formatted the localDateTime into this format and now I just want to get the CEST time. How can I do that? I'd appreciate every comment.

答案1

得分: 2

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

另外,一个小的优化:DateTimeFormatter 是线程安全的。因此,没有必要每次都构造一个新的实例,因为格式是恒定的。您可以像这样在顶部声明它:

private static final DateTimeFormatter FORMATTER;

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

要打印格式化的字符串,请使用以下代码:

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

// 请注意,#format 方法有一个返回值
// 最初,您调用了 'localDateTime.format(myFormatObj);'
// 而忽略了返回值
String formatted = FORMATTER.format(zonedDateTime);

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

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

英文:

Please note that date-time objects from the Java Time API are immutable. Therefore, whenevery you want to modify an existing date-time instance, a new fresh copy is returned, leaving the old one untouched.

Also, a minor optimization: DateTimeFormatter is thread-safe. Thus, there is no need to construct a new instance every time, since the format is constant. You could declare it at the top like this:

private static final DateTimeFormatter FORMATTER;

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

To print a formatted String, use the following:

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

Edit 1: Regarding thread-safety
Thread-safety refers to when an object can safely be used by mutliple threads concurrently, without breaking internals of the class. If a class is thread-safe, you can call it from mutliple threads at the same time (therefore you do not need to create a new instance every time, but only one). If a class is not thread-safe, a new instance is needed for each thread.

答案2

得分: 0

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

// Output when running in UTC time zone just now:
// > 27-09-2020 20:33:53

// We got the Berlin time (not the UTC time).

// What went wrong in your code?

// Two things:

// 1. `LocalDateTime.now()` gives you the current time in the default time zone of the JVM.
// It seems that this was not Eurpoe/Berlin (perhaps it was UTC, it could be something else).
// Then `ZonedDateTime.of(localDateTime, europeBerlin)` takes that date and time of day and claims
// that it is Europe/Berlin time zone, which is wrong and the reason why you got an incorrect result.
// You don’t often need the `LocalDateTime` class and virtually never the no-arg `LocalDateTime.now()` method.
// 2. To get the time in a specific format you need to format the date and time into a string.
// The `LocalDateTime` and the `ZonedDateTime` objects haven’t got any format.

// Links

// - Related questions:
// - [Can’t rid of 'T' in LocalDateTime](https://stackoverflow.com/questions/52311884/can-t-rid-of-t-in-localdatetime)
// - [String to ZonedDateTime is changing format](https://stackoverflow.com/questions/50120213/string-to-zoneddatetime-is-changing-format)
英文:
	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);

Output when running in UTC time zone just now:

> 27-09-2020 20:33:53

We got the Berlin time (not the UTC time).

What went wrong in your code?

Two things:

  1. LocalDateTime.now() gives you the current time in the default time zone of the JVM. It seems that this was not Eurpoe/Berlin (perhaps it was UTC, it could be something else). Then ZonedDateTime.of(localDateTime, europeBerlin) takes that date and time of day and claims that it is Europe/Berlin time zone, which is wrong and the reason why you got an incorrect result. You don’t often need the LocalDateTime class and virtually never the no-arg LocalDateTime.now() method.
  2. To get the time in a specific format you need to format the date and time into a string. The LocalDateTime and the ZonedDateTime objects haven’t got any format.

huangapple
  • 本文由 发表于 2020年9月27日 16:51:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/64086597.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定