如何使用 Java 中的 yoda 时间库将 UTC 时间转换为 CET 时间?
我正在尝试这个,但看起来我做错了什么
DateTime dateTime = new LocalDateTime(utdDate.getTime()).toDateTime(DateTimeZone.forID("CET"));
如果我使用这个,我会在放入的同时取出。
我强烈建议您避免使用“CET”等时区名称,因为它具有固有的本地化性质。这可能只适用于最终用户的格式化输出,但不适用于内部编码。
CET 代表许多不同的时区 ID,例如 IANA-ID
Europe/Berlin
、Europe/Paris
等。在我的时区“欧洲/柏林”中,您的代码的工作方式如下:
DateTime dateTime =
new LocalDateTime(utdDate.getTime()) // attention: implicit timezone conversion
.toDateTime(DateTimeZone.forID("CET"));
System.out.println(dateTime.getZone()); // CET
System.out.println(dateTime); // 2014-04-16T18:39:06.976+02:00
请记住,表达式
new LocalDateTime(utdDate.getTime())
隐式使用系统时区进行转换,因此,如果您的 CET 时区在内部被识别为具有与系统时区相同的时区偏移量,则不会更改任何内容。为了强制 JodaTime 识别 UTC 输入,您应该这样指定它:
Date utdDate = new Date();
DateTime dateTime = new DateTime(utdDate, DateTimeZone.UTC);
System.out.println(dateTime); // 2014-04-16T16:51:31.195Z
dateTime = dateTime.withZone(DateTimeZone.forID("Europe/Berlin"));
System.out.println(dateTime); // 2014-04-16T18:51:31.195+02:00
此示例保留了自 UNIX 纪元以来的绝对时间(以毫秒为单位)的瞬间。如果您想保留字段并从而更改瞬间,那么您可以使用方法
withZoneRetainFields
:
Date utdDate = new Date();
dateTime = new DateTime(utdDate, DateTimeZone.UTC);
System.out.println(dateTime); // 2014-04-16T16:49:08.394Z
dateTime = dateTime.withZoneRetainFields(DateTimeZone.forID("Europe/Berlin"));
System.out.println(dateTime); // 2014-04-16T16:49:08.394+02:00
接受的答案非常好。我写了这个关于升级到
java.time
API 的答案。 java.time
API 于 2014 年 3 月作为 Java 8 的一部分发布。新代码应使用 java.time
。
java.time
以下为Joda-Time主页上的通知:
请注意,从 Java SE 8 开始,用户被要求迁移到
(JSR-310) - JDK 的核心部分,它取代了这个 项目。java.time
下面给出的是 Java 7 的注释
Timezone
文档:
三字母时区 ID
为了与 JDK 1.1.x 兼容,其他一些三字母时区 ID(例如“PST”、“CTT”、“AST”)是 也支持。然而,它们的使用已被弃用,因为同样的 缩写通常用于多个时区(例如,“CST” 可以是美国“中部标准时间”和“中国标准时间”),以及 那么 Java 平台只能识别其中之一。
因此,不要使用
CET
,而是使用特定的 ZoneId
,例如Europe/Paris
。
ZonedDateTime#withZoneSameInstant
ZonedDateTime#withZoneSameInstant
将 ZonedDateTime
转换为不同 ZonedDateTime
中的另一个 ZoneId
。
如果您有
LocalDateTime
,请先使用 ZonedDateTime
将其转换为
LocalDateTime#atZone
,然后再使用 ZonedDateTime#withZoneSameInstant
。
演示:
class Main {
public static void main(String[] args) {
ZoneId sourceZone = ZoneId.of("Etc/UTC");
ZoneId targetZone = ZoneId.of("Europe/Paris");
// A sample local date-time at UTC
LocalDateTime ldt = LocalDateTime.now(sourceZone);
ZonedDateTime sourceZdt = ldt.atZone(sourceZone);
ZonedDateTime targetZdt = sourceZdt.withZoneSameInstant(targetZone);
System.out.println(sourceZdt);
System.out.println(targetZdt);
}
}
示例运行的输出:
2025-01-10T14:15:45.863591Z[Etc/UTC]
2025-01-10T15:15:45.863591+01:00[Europe/Paris]
注意:如果由于某种原因,您需要
java.util.Date
的实例,请将其获取为 java.util.Date.from(targetZdt.toInstant())
。
从 Trail:日期时间了解有关现代日期时间 API 的更多信息。