英文:
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:
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). ThenZonedDateTime.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 theLocalDateTime
class and virtually never the no-argLocalDateTime.now()
method.- To get the time in a specific format you need to format the date and time into a string. The
LocalDateTime
and theZonedDateTime
objects haven’t got any format.
Links
- Related questions:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论