简体   繁体   English

如何将 Instant 设置为特定时间?

[英]How can I set an Instant to a specific time?

I've been trying to set an instant to a specific time, following stackoverflow advice, but I'm having trouble doing so.根据stackoverflow的建议,我一直在尝试将一个瞬间设置为特定时间,但我在这样做时遇到了麻烦。 I tried the following:我尝试了以下方法:

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

However I get the error:但是我得到了错误:

error: non-static method atZone(ZoneId) cannot be referenced from a static context错误:不能从 static 上下文引用非静态方法 atZone(ZoneId)

Btw the StdIn.readInt() is just a library that reads numbers from input.顺便说一句, StdIn.readInt() 只是一个从输入中读取数字的库。

Let's say I want to set an Instant to 5:10am.假设我想将 Instant 设置为早上 5:10。 How do I do that?我怎么做?

Let's say I want to set an Instant to 5:10am.假设我想将 Instant 设置为早上 5:10。 How do I do that?我怎么做?

I doubt you want to do that.我怀疑你想这样做。 It's not possible in the basic sense, so, the formula would be:这在基本意义上是不可能的,所以,公式是:

  • Have an instant, derived however you please.有一个瞬间,随心所欲地派生。
  • Given that instants are about a moment in time, and human concepts like minutes and days do not apply to this, you can't set an instant's 'minute' to anything.鉴于瞬间大约是一个瞬间,而人类概念(如分钟和天)不适用于此,您不能将瞬间的“分钟”设置为任何东西。 Therefore, Instants are not useful for this, and you must move away from it.因此,Instant 对此没有用,您必须远离它。 Convert to some notion that DOES know what a minute is... convert it to a ZonedDateTime.转换为确实知道一分钟是什么的概念……将其转换为 ZonedDateTime。
  • Take the ZDT and set whatever specifics you want.使用 ZDT 并设置您想要的任何细节。
  • Convert the ZDT back to an instant.将 ZDT 转换回瞬间。

This is a long song and dance routine and it suggests that you may not actually 'want' what you want.这是一段很长的歌舞表演,它表明你可能并不真正“想要”你想要的东西。 Perhaps whatever code you wrote that currently uses Instant could be rewritten to use something more appropriate, such as ZonedDateTime or perhaps LocalDateTime .也许您编写的当前使用Instant的任何代码都可以重写为使用更合适的代码,例如ZonedDateTimeLocalDateTime

But, if you must:但是,如果您必须:

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

To grok the difference between ZDTs and Instants:要了解 ZDT 和 Instant 之间的区别:

Imagine you make an appointment with your barber.想象一下,你和你的理发师约会。 That appointment is best stored as a ZDT: Your appointment is on January 9th, 2023, quarter past 9 in the morning, and as the barber is in Amsterdam, at zone Europe/Amsterdam.该预约最好存储为 ZDT:您的预约时间为 2023 年 1 月 9 日上午 9 点一刻,理发师在阿姆斯特丹,位于欧洲/阿姆斯特丹区。

The time between right this very moment and your appointment is what it is.. when you fly to another time zone it will not change.从这一刻到您的约会之间的时间就是这样。当您飞往另一个时区时,它不会改变。 In that sense it seems like an instant.从这个意义上说,它似乎是一瞬间。 But it is not: If The Netherlands decrees that henceforth The Netherlands will stick to summertime forever and will no longer observe daylight savings time, the very moment that the law is ratified, your appointment will immediately be one hour closer to right now than it was the instant before it was ratified*.但事实并非如此:如果荷兰下令从今以后荷兰将永远坚持夏季并且不再遵守夏令时,那么在该法律被批准的那一刻,您的约会将立即比现在更近一小时批准前的那一刻*。

ZonedDateTimes do that; ZonedDateTimes 这样做; they adjust along (you'll have to wait for a new timezone definition to be downloaded, but they'll pick this up and correctly report on the time remaining until your barber appointment, automatically).他们会随之调整(您必须等待下载新的时区定义,但他们会自动选择并正确报告您的理发师预约之前的剩余时间)。

Instants don't.瞬间没有。 They don't even have a timezone.他们甚至没有时区。 They never change like that.他们永远不会那样改变。 Think more cosmic.想想更宇宙。

That's the difference.这就是区别。

*) But, rzwitserloot, That is preposterous, That would never happen, Ah, but, you see, it probably would . *) 但是,rzwitserloot,那太荒谬了,这永远不会发生,啊,但是,你看, 它可能会发生。

tl;dr tl;博士

You asked:您问:

set an Instant to 5:10am将 Instant 设置为早上 5:10

OffsetDateTime                      // Represent a moment, a specific point on the timeline, as seen through a number of hours-minutes-seconds ahead or behind the baseline of UTC.
.now( ZoneOffset.UTC )              // Capture the current moment as seen at UTC, that is, with an offset of zero hours-minutes-seconds from UTC. Returns a `OffsetDateTime` object.
.with( LocalTime.of( 5 , 10 ) )     // Adjust from current time-of-day to this specific time-of-day. Keep the date the same, keep the offset the same. Returns a new second `OffsetDateTime` object, per immutable objects pattern.
.toInstant()                        // Extract an `Instant` object, representing a moment as seen strictly in UTC, always with an offset of zero.
.toString()                         // Generate text representing the value of this `Instant` object, in standard ISO 8601 format.

2021-02-16T05:10:00Z 2021-02-16T05:10:00Z

Details细节

Let's say I want to set an Instant to 5:10am.假设我想将 Instant 设置为早上 5:10。

It sounds like you want to start with the current date as seen in UTC (an offset of zero hours-minutes-seconds), and assign a certain time-of-day.听起来您想从 UTC 中看到的当前日期开始(零时分秒的偏移量),并分配一个特定的时间。

  • Represent time-of-day with LocalTime .LocalTime表示一天中的时间。
  • Use OffsetDateTime first, then extract Instant .首先使用OffsetDateTime ,然后提取Instant

The Instant class is the basic building-block class of java.time . Instant class 是 java.time 的基本构建块class It represents a moment, a specific point on the timeline, as seen in UTC (that is, with an offset of zero hours-minutes-seconds from UTC).它代表一个时刻,时间线上的一个特定点,如 UTC 所示(即与 UTC 有零小时-分钟-秒的偏移量)。 This class by itself has a limited feature set, as it is intended to be used by more complicated classes such as OffsetDateTime & ZonedDateTime .此 class 本身具有有限的功能集,因为它旨在供更复杂的类使用,例如OffsetDateTimeZonedDateTime

The OffsetDateTime class, in contrast to Instant , is more flexible, with more features. OffsetDateTime class 与Instant相比,更灵活,功能更多。 One of those features is the with method.这些功能之一是with方法。 You can pass a LocalTime object to adjust to that specific time-of-day.您可以通过LocalTime object 来调整到该特定时间。

Notice that java.time use immutable objects .注意java.time使用不可变对象 So with method generates a new fresh OffsetDateTime object with values based on the original.因此with方法生成一个新的OffsetDateTime object,其值基于原始值。 The original is unchanged.原件不变。

LocalTime localTime = LocalTime.of( 5 , 10 ) ;               // 5:10 AM, in 24-hour clock.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;  // Current moment as seen in UTC, an offset of zero hours-minutes-seconds.
OffsetDateTime odtAt0510 = odt.with( localTime ) ;
Instant instant = odt.toInstant() ;

See this code run live at IdeOne.com .请参阅在 IdeOne.com 上实时运行的代码

instant.toString(): 2021-02-16T05:10:00Z即时.toString(): 2021-02-16T05:10:00Z

Regarding your code:关于您的代码:

                        .withHour(StdIn.readInt())
                        .withMinute(StdIn.readInt())

Generally it is better to first gather your inputs from user, then perform your business logic.通常最好先从用户那里收集您的输入,然后执行您的业务逻辑。 Segregating your code will make it easier to read, test, and debug.隔离代码将使阅读、测试和调试更容易。

…
int hour = StdIn.readInt() ;
int minute = StdIn.readInt() ;
…
LocalTime localTime = LocalTime.of( hour , minute ) ;
…

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM