将 GMT 日期时间转换为本地时区日期时间

时间:2021-01-28 08:29:22

标签: java datetime timezone gmt

在 Java 8 中,我需要一种从 ISO 8601 格式的 GMT 日期时间获取本地日期时间 (GMT+1) 的方法。

一个简单的例子: 客户端在这个日期时间发送给我(服务器)"2020-01-11T23:00:00.000Z" 当用户从日期选择器中选择 2020 年 1 月 12 日时,客户端会向我发送此信息。是 GMT+1 的 1 月 12 日,而是 GMT 的前一天。

由于上述原因,我知道这个日期时间不是 2020 年 1 月 11 日,而是 GMT+1 的 2020 年 1 月 12 日。

所以我需要这个值 "2020-01-12T00:00:00.000"

准确地说,我不需要用 simpleDateFormat 打印它,而只是在 java.util.Date 类字段中将 "2020-01-11T23:00:00.000Z" 转换为 "2020-01-12T00:00:00.000"

谢谢。

1 个答案:

答案 0 :(得分:3)

问题是源系统采用纯日期值,但在午夜添加时间,然后将其转换为 UTC,但您希望 java.util.Date 中的纯日期值,默认情况下打印在您的本地时区,即JVM的默认时区。

因此,您必须解析字符串,将值还原回源系统的时区,并将本地时间视为您自己的 JVM 默认时区中的时间。

您可以这样做,显示所有中间类型:

String sourceStr = "2020-01-11T23:00:00.000Z";
ZoneId sourceTimeZone = ZoneOffset.ofHours(1); // Use real zone of source, e.g. ZoneId.of("Europe/Paris");

// Parse Zulu date string as zoned date/time in source time zone
Instant sourceInstant = Instant.parse(sourceStr);
ZonedDateTime sourceZoned = sourceInstant.atZone(sourceTimeZone);

// Convert to util.Date in local time zone
ZonedDateTime localZoned = sourceZoned.withZoneSameLocal(ZoneId.systemDefault());
Instant localInstant = localZoned.toInstant();
Date localDate = Date.from(localInstant); // <== This is your desired result

// Print value in ISO 8601 format
String localStr = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS").format(localDate);
System.out.println(localStr);

输出

2020-01-12T00:00:00.000

代码当然可以合并在一起:

String input = "2020-01-11T23:00:00.000Z";

Date date = Date.from(Instant.parse(input).atZone(ZoneOffset.ofHours(1))
        .withZoneSameLocal(ZoneId.systemDefault()).toInstant());

System.out.println(date);

输出

Sun Jan 12 00:00:00 EST 2020

如您所见,日期值是正确的,即使我在美国东部时区。