如何在java中将UTC时间转换为CET时间

问题描述 投票:0回答:2

如何使用 Java 中的 yoda 时间库将 UTC 时间转换为 CET 时间?

我正在尝试这个,但看起来我做错了什么

DateTime dateTime = new LocalDateTime(utdDate.getTime()).toDateTime(DateTimeZone.forID("CET"));

如果我使用这个,我会在放入的同时取出。

java timezone jodatime
2个回答
2
投票

我强烈建议您避免使用“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

0
投票

接受的答案非常好。我写了这个关于升级到

java.time
API 的答案。
java.time
API 于 2014 年 3 月作为 Java 8 的一部分发布。新代码应使用
java.time

java.time

以下为Joda-Time主页上的通知:

请注意,从 Java SE 8 开始,用户被要求迁移到

java.time
(JSR-310) - JDK 的核心部分,它取代了这个 项目。

避免时区缩写

下面给出的是 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]

在 Ideone 上尝试一下

注意:如果由于某种原因,您需要

java.util.Date
的实例,请将其获取为
java.util.Date.from(targetZdt.toInstant())

Trail:日期时间了解有关现代日期时间 API 的更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.