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

nfs0ujit  于 12个月前  发布在  Spring
关注(0)|答案(2)|浏览(147)

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

  • 服务器时间戳:2023-12- 20 T13:37:17.288582240Z[GMT]
  • 当地时区:Europe/地拉那
  • 服务器时区偏移: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);
}

字符串
响应Transformer:

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);


}在本地作为例外工作,将此作为时间戳1542754800000,转换为2018-11- 21 T00:00+01:00 OffsetDateTime并返回结果。然而,在服务器上,我得到了NONE。我希望收到相同的数据行。对这里可能出现的问题有什么见解吗?
我也检查一下:

pamUserAccount.getAccountDateCreation();


本地我得到:2018-11- 21 T01:00+01:00
在服务器我得到了:2018-11- 21 T00:00 Z

trnvg8h3

trnvg8h31#

传递一个ZoneIdZonedDateTime#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));

字符串
你可以用

ZonedDateTime cetDateTime = Instant.atZone(ZoneId.of("Europe/Tirana"));


类似地,而不是使用

LocalDateTime localDateTime = cetDateTime.toLocalDate().atStartOfDay();
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneOffset.ofHours(1));


你可以用

ZonedDateTime zonedDateTime = cetDateTime.toLocalDate().atStartOfDay(ZoneId.of("Europe/Tirana"));


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

f8rj6qna

f8rj6qna2#

解决方法:

private OffsetDateTime getOffsetDateTimeFromMillis(Long epochMillis) {
    ZoneOffset systemDefaultOffset = ZoneId.systemDefault().getRules().getOffset(Instant.now());
    if (systemDefaultOffset.getTotalSeconds() == 0) {
        Instant instant = Instant.ofEpochMilli(epochMillis);
        ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneOffset.UTC);
        ZonedDateTime adjustedDateTime = zonedDateTime.with(LocalTime.MIN).truncatedTo(ChronoUnit.DAYS);
        return OffsetDateTime.ofInstant(adjustedDateTime.toInstant(), ZoneOffset.UTC);
    } else {
        return OffsetDateTime.ofInstant(Instant.ofEpochMilli(epochMillis), ZoneId.of("UTC"));
    }
}

字符串

相关问题