外部API返回带有日期的对象。
根据他们的API规范,所有的日期总是在GMT中报告。
但是,生成的客户端类(我无法编辑)没有正确设置时区。相反,它使用本地时区,而不将日期转换为该时区。
所以,长话短说,我有一个日期,我知道是格林尼治标准时间,但它说的是CET。如何通过更改计算机上的本地时区或执行以下操作来调整此错误:
LocalDateTime.ofInstant(someObject.getDate().toInstant().plus(1, ChronoUnit.HOURS),
ZoneId.of("CET"));
谢谢。
发布于 2020-01-24 00:25:50
tl;⇒博士使用⇒进行转换
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]
解释:
您的方法不仅纠正了区域,而且相应地调整了时间(如果需要的话,这是很好的),原因是您使用了从LocalDateTime
创建的Instant
。Instant
代表一个时间上的时刻,它可以在不同的区域中有不同的表示,但它保持相同的时刻。如果您从该区域创建一个LocalDateTime
并放置另一个区域,则日期和时间将转换为目标区域的日期和时间。这不仅仅是在保持日期和时间不变的同时替换该区域。
如果从LocalDateTime
中使用ZonedDateTime
,则可以在忽略该区域的情况下提取日期和时间表示,这使您能够在之后添加不同的区域,并保持原来的日期和时间。
编辑:如果代码与错误代码运行在同一个JVM中,您可以使用ZoneId.systemDefault()
获得与错误代码使用的相同的时区。根据口味的不同,您可以使用ZoneOffset.UTC
而不是ZoneId.of("GMT")
。
发布于 2020-01-24 01:05:33
恐怕你不能在这里做些计算了。我强烈建议采用基于java.time
类的方法,但也可以使用java.util.Calendar
类和myCalendar.get(Calendar.ZONE_OFFSET)
进行这些计算:
https://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html#ZONE_OFFSET
https://stackoverflow.com/questions/59892093
复制相似问题