Java:修复日期对象中不正确的时区



外部 API 返回一个带有日期的对象。
根据他们的 API 规范,所有日期始终以 GMT 报告。

但是,生成的客户端类(我无法编辑(未正确设置时区。相反,它使用本地时区,而不将日期转换为该时区。

所以,长话短说,我有一个对象,我知道它的日期是格林威治标准时间,但它说的是 CET。如何在不更改计算机上的本地时区或执行以下操作的情况下调整此错误:

LocalDateTime.ofInstant(someObject.getDate().toInstant().plus(1, ChronoUnit.HOURS),
ZoneId.of("CET"));

谢谢。

tl;博士⇒使用ZonedDateTime进行转换

public static void main(String[] args) {
// use your date here, this is just "now"
Date date = new Date();
// parse it to an object that is aware of the (currently wrong) time zone
ZonedDateTime wrongZoneZdt = ZonedDateTime.ofInstant(date.toInstant(), ZoneId.of("CET"));
// print it to see the result
System.out.println(wrongZoneZdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
// extract the information that should stay (only date and time, NOT zone or offset)
LocalDateTime ldt = wrongZoneZdt.toLocalDateTime();
// print it, too
System.out.println(ldt.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
// then take the object without zone information and simply add a zone
ZonedDateTime correctZoneZdt = ldt.atZone(ZoneId.of("GMT"));
// print the result
System.out.println(correctZoneZdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
}

输出:

2020-01-24T09:21:37.167+01:00[CET]
2020-01-24T09:21:37.167
2020-01-24T09:21:37.167Z[GMT]

解释:

您的方法不仅纠正了区域,而且还相应地调整了时间(这在需要时很好(的原因是您使用了从Instant创建的LocalDateTimeInstant表示一个时刻,该时刻在不同的区域中可能具有不同的表示形式,但它保持相同的时刻。如果从中创建LocalDateTime并放置另一个区域,则日期和时间将转换为目标区域的日期和时间。这不仅仅是替换区域,同时保持日期和时间不变。

如果使用ZonedDateTime中的LocalDateTime,则提取日期和时间表示形式时忽略该区域,这使您能够在之后添加其他区域并保持日期和时间不变。

编辑:如果代码与错误代码在同一个JVM中运行,则可以使用ZoneId.systemDefault()来获取与错误代码相同的时区。根据口味,您可以使用ZoneOffset.UTC而不是ZoneId.of("GMT")

恐怕你不会在这里绕过一些计算。我强烈建议遵循基于java.time类的方法,但您也可以使用java.util.Calendar类和myCalendar.get(Calendar.ZONE_OFFSET)进行这些计算:

https://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html#ZONE_OFFSET

最新更新