服务器与本地环境之间的Java时区转换问题

Dor*_*ori 2 java database oracle spring-boot java-17

我的服务器和本地环境之间的时区转换遇到问题。我有一个实体帐户,其字段 accountCreationDate 为 OffsetDateTime。详细信息如下:

  • 服务器时间戳:2023-12-20T13:37:17.288582240Z[GMT]
  • 本地时区:Europe/Tirana
  • 服务器时区偏移:0 (GMT)
  • 本地时区偏移:3600 (GMT+01:00) 当我在数据库“SELECT DBTIMEZONE FROM DUAL;”中运行此命令时 结果:“+01:00”

在我的代码中,我尝试在服务器和本地环境之间转换时间戳:

if (accountRequest.getAccountCreationDate() != null) {
Instant instant = Instant.ofEpochMilli(accountRequest.getAccountCreationDate());

ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneOffset.UTC);
ZonedDateTime cetDateTime = zonedDateTime.withZoneSameInstant(ZoneOffset.ofHours(1));
OffsetDateTime offsetDateTime = cetDateTime.toOffsetDateTime();

requestTransformer.setAccountDateCreation(offsetDateTime);
}
Run Code Online (Sandbox Code Playgroud)

响应变压器:

if (pamUserAccount.getAccountDateCreation() != null) {
OffsetDateTime cetDateTime = pamUserAccount.getAccountDateCreation();

LocalDateTime localDateTime = cetDateTime.toLocalDate().atStartOfDay();
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneOffset.ofHours(1)); // GMT+01:00
long epochMillis = zonedDateTime.withZoneSameInstant(ZoneOffset.UTC)
        .toInstant()
        .toEpochMilli();

response.setAccountDateCreation(epochMillis);
Run Code Online (Sandbox Code Playgroud)

本地工作正常,时间戳为 1542754800000,转换为 2018-11-21T00:00+01:00 OffsetDateTime 并返回结果。但是,在服务器上,我什么也没有得到。我希望收到同一行数据。对这里可能出了什么问题有什么见解吗?

我也检查了一下:

 pamUserAccount.getAccountDateCreation();
Run Code Online (Sandbox Code Playgroud)

本地我得到:2018-11-21T01:00+01:00

在服务器中我得到:2018-11-21T00:00Z

Arv*_*ash 5

传递一个ZoneIdtoZonedDateTime#withZoneSameInstant而不是一个固定的ZoneOffset。当您传递一个固定值时ZoneOffset,您将计算限制为一个区域偏移量,但是当您传递一个值时ZoneId,区域偏移量将根据DST自动调整。

更改您的代码以使用ZoneId.of("Europe/Tirana")而不是ZoneOffset.ofHours(1).

您可以对代码进行一些进一步的改进,例如而不是使用

ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneOffset.UTC);
ZonedDateTime cetDateTime = zonedDateTime.withZoneSameInstant(ZoneOffset.ofHours(1));
Run Code Online (Sandbox Code Playgroud)

你可以用

ZonedDateTime cetDateTime = Instant.atZone(ZoneId.of("Europe/Tirana"));
Run Code Online (Sandbox Code Playgroud)

同样,不要使用

LocalDateTime localDateTime = cetDateTime.toLocalDate().atStartOfDay();
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneOffset.ofHours(1));
Run Code Online (Sandbox Code Playgroud)

你可以用

ZonedDateTime zonedDateTime = cetDateTime.toLocalDate().atStartOfDay(ZoneId.of("Europe/Tirana"));
Run Code Online (Sandbox Code Playgroud)

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

  • ++ 第一次看到“欧洲/地拉那”区域 (2认同)
  • 很不错...... (2认同)