【问题标题】:Java ZonedDateTime.toInstant() moves to UTC [duplicate]Java ZonedDateTime.toInstant() 移至 UTC [重复]
【发布时间】:2020-04-08 10:53:00
【问题描述】:

我只想将 Instant 时刻移动到另一个时区。

例如

2020-04-08 23:59:59.999 UTC -> 到Europe/Sarajevo[UTC+1]

应该在: 2021-04-09 00:59:59.999 UTC

它不会返回这个

 dateVal.atZone(operatorTimeZone).toInstant()

返回错误的值。

dateVal.atZone(operatorTimeZone) 返回正确的值。

不幸的是,我需要即时响应。

如何解决这个问题?

感谢和问候,

【问题讨论】:

  • Instant 不支持时区。查看此问题了解详情:Getting the the current Instant in a specific TimeZone
  • Java 日期时间 API (java.time.Instant) 中的 Instant 类表示时间线上的特定时刻。瞬间被定义为从原点开始的偏移量(称为纪元)。 Zone 没有任何意义,因为您可能会看到它从原点开始的持续时间,无论您在地球上的哪个地方,这都是一样的
  • “结果应该是:2021-04-09 00:59:59.999 UTC”——不,不应该。听起来您误解了 Instant 所代表的含义。我怀疑您实际上想从 2020-04-08 23:59:59.999 作为LocalDateTime 开始,然后将 that 转换为 Europe/Sarajevo 时区,然后将其转换为 Instant。

标签: java


【解决方案1】:

您似乎想要做的是将dateVal 时刻的时区偏移量添加到该时刻。这可以通过获取偏移量并直接添加来完成:

ZoneOffset offset = operatorTimeZone.getRules().getOffset(i);
Instant newInstant = dateVal.plusSeconds(offset.getTotalSeconds());

另一种方法是使用withZoneSameLocal,尽管我认为这并不能清楚地表明意图,更像是一种“技巧”。

Instant newInstant = dateVal
                        .atZone(operatorTimeZone)
                        .withZoneSameLocal(ZoneOffset.UTC)
                        .toInstant();

也就是说,我想得越多,这就越像是一个 XY 问题。将结果表示为ZonedDateTime 而不是Instant 可能是您真正应该做的。

【讨论】:

  • 这基本上是围绕 OP 使用错误的数据类型作为起点。 withZoneSameLocal通常是一种代码异味,因为它很少(IMO)代表语义上合理的操作。
  • @JonSkeet 是的,当我想得更多时,我开始认为这是一个 XY 问题...您的评论是在我编辑时出现的。
猜你喜欢
  • 2019-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-03
  • 2012-04-01
  • 2018-02-10
  • 1970-01-01
  • 2020-11-02
相关资源
最近更新 更多