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

nfs0ujit  于 2024-01-06  发布在  Spring
关注(0)|答案(2)|浏览(180)

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

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

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

  1. if (accountRequest.getAccountCreationDate() != null) {
  2. Instant instant = Instant.ofEpochMilli(accountRequest.getAccountCreationDate());
  3. ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneOffset.UTC);
  4. ZonedDateTime cetDateTime = zonedDateTime.withZoneSameInstant(ZoneOffset.ofHours(1));
  5. OffsetDateTime offsetDateTime = cetDateTime.toOffsetDateTime();
  6. requestTransformer.setAccountDateCreation(offsetDateTime);
  7. }

字符串
响应Transformer:

  1. if (pamUserAccount.getAccountDateCreation() != null) {
  2. OffsetDateTime cetDateTime = pamUserAccount.getAccountDateCreation();
  3. LocalDateTime localDateTime = cetDateTime.toLocalDate().atStartOfDay();
  4. ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneOffset.ofHours(1)); // GMT+01:00
  5. long epochMillis = zonedDateTime.withZoneSameInstant(ZoneOffset.UTC)
  6. .toInstant()
  7. .toEpochMilli();
  8. response.setAccountDateCreation(epochMillis);


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

  1. 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)
你可以对你的代码做一些进一步的改进,例如,

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

字符串
你可以用

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


类似地,而不是使用

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


你可以用

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


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

展开查看全部
f8rj6qna

f8rj6qna2#

解决方法:

  1. private OffsetDateTime getOffsetDateTimeFromMillis(Long epochMillis) {
  2. ZoneOffset systemDefaultOffset = ZoneId.systemDefault().getRules().getOffset(Instant.now());
  3. if (systemDefaultOffset.getTotalSeconds() == 0) {
  4. Instant instant = Instant.ofEpochMilli(epochMillis);
  5. ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneOffset.UTC);
  6. ZonedDateTime adjustedDateTime = zonedDateTime.with(LocalTime.MIN).truncatedTo(ChronoUnit.DAYS);
  7. return OffsetDateTime.ofInstant(adjustedDateTime.toInstant(), ZoneOffset.UTC);
  8. } else {
  9. return OffsetDateTime.ofInstant(Instant.ofEpochMilli(epochMillis), ZoneId.of("UTC"));
  10. }
  11. }

字符串

相关问题