首页 > 解决方案 > 如何将 Instant 设置为特定时间?

问题描述

我一直在尝试按照 stackoverflow 的建议将一个瞬间设置为特定的时间,但我在这样做时遇到了麻烦。我尝试了以下方法:

Instant instant = Instant.atZone(ZoneOffset.UTC)
                        .withHour(StdIn.readInt())
                        .withMinute(StdIn.readInt())
                        .withSecond(0)
                        .toInstant();

但是我收到错误:

错误:不能从静态上下文引用非静态方法 atZone(ZoneId)

顺便说一句, StdIn.readInt() 只是一个从输入中读取数字的库。

假设我想将 Instant 设置为早上 5:10。我怎么做?

标签: javadatetime

解决方案


假设我想将 Instant 设置为早上 5:10。我怎么做?

我怀疑你想这样做。这在基本意义上是不可能的,所以,公式是:

  • 有一个瞬间,随心所欲地派生。
  • 鉴于瞬间大约是一个瞬间,而人类概念(如分钟和天)并不适用于此,您不能将瞬间的“分钟”设置为任何东西。因此,Instant 对此没有用,您必须远离它。转换为确实知道一分钟是什么的概念……将其转换为 ZonedDateTime。
  • 使用 ZDT 并设置您想要的任何细节。
  • 将 ZDT 转换回瞬间。

这是一段很长的歌舞表演,它表明你可能并不真正“想要”你想要的东西。也许您编写的当前使用的任何代码Instant都可以重写以使用更合适的东西,例如.ZonedDateTimeLocalDateTime

但是,如果您必须:

Instant original = Instant.now();
ZonedDateTime zdt = original.atZone(Zone.UTC);
// setting minutes and seconds _AT UTC_? That sounds.. bizarre.
// what in the blazes is your use case??

ZonedDateTime adjusted = zdt
  .withHour(hour).withMinute(minute).withSecond(0)
  .withNano(0) // you forgot about the nanos!
  ;

Instant out = adjusted.toInstant();

要了解 ZDT 和 Instant 之间的区别:

想象一下,你和你的理发师约会。该预约最好存储为 ZDT:您的预约时间为 2023 年 1 月 9 日上午 9 点一刻,理发师在阿姆斯特丹,位于欧洲/阿姆斯特丹区。

从这一刻到您的约会之间的时间就是这样。当您飞往另一个时区时,它不会改变。从这个意义上说,它似乎是一瞬间。但事实并非如此:如果荷兰下令从今以后荷兰将永远坚持夏季并且不再遵守夏令时,那么在该法律被批准的那一刻,您的约会将立即比现在更近一小时批准前的那一刻*。

ZonedDateTimes 这样做;他们会随之调整(您必须等待新的时区定义被下载,但他们会自动选择并正确报告距离您预约理发师的剩余时间)。

瞬间没有。他们甚至没有时区。他们永远不会那样改变。想想更宇宙。

这就是区别。

*) 但是,rzwitserloot!那太荒谬了!那永远不会发生!啊,但是,你看,它可能会


推荐阅读