英文:
Uncaught RangeError: Duration field days not supported by Temporal.Instant (adding 1 day to a temporal instant without using magic numbers)
问题
Throws Uncaught RangeError: Duration field days not supported by Temporal.Instant. Try Temporal.ZonedDateTime instead.
This is presumably because Temporal.Instant
doesn't contain any calendar info, and the concept of "1 day" could vary depending on things like DST and leap seconds.
The obvious alternative is to use 24 hours:
Temporal.Now.instant().add({ hours: 24 }).epochSeconds
Not bad, but not 100% satisfactory, as now we're left with 24 as a magic number.
To get around this, we can use:
Temporal.Now.instant().add({ hours: Temporal.Duration.from({ days: 1 }).total({ unit: 'hours' }) }).epochSeconds
But that's pretty verbose and hard to visually parse, when all we really wanted is the concept of "one day from now in seconds since the epoch."
We could also use the option suggested by the error message and use a ZonedDateTime
, but time zone info isn't relevant to the use case, plus it's better for the result to be a consistent amount of time in the future, regardless of DST, etc.
Is there a more concise/idiomatic way of doing this without using any magic numbers? Or do I just have to suck it up and use hours: 24
?
英文:
I'm trying to add 1 day to a Temporal.Instant
, to use as the exp
value for a JWT. The most obvious-seeming way to do this:
Temporal.Now.instant().add({ days: 1 }).epochSeconds
Throws Uncaught RangeError: Duration field days not supported by Temporal.Instant. Try Temporal.ZonedDateTime instead.
This is presumably because Temporal.Instant
doesn't contain any calendar info, and the concept of "1 day" could vary depending on things like DST and leap seconds.
The obvious alternative is to use 24 hours:
Temporal.Now.instant().add({ hours: 24 }).epochSeconds
Not bad, but not 100% satisfactory, as now we're left with 24 as a magic number.
To get around this, we can use:
Temporal.Now.instant().add({ hours: Temporal.Duration.from({ days: 1 }).total({ unit: 'hours' }) }).epochSeconds
But that's pretty verbose and hard to visually parse, when all we really wanted is the concept of "one day from now in seconds since the epoch".
We could also use the option suggested by the error message and use a ZonedDateTime
, but time zone info isn't relevant to the use case, plus it's better for the result to be a consistent amount of time in the future, regardless of DST etc.
Is there a more concise/idiomatic way of doing this without using any magic numbers? Or do I just have to suck it up and use hours: 24
?
答案1
得分: 4
在最后,你必须选择一个策略来确定过期时间戳,而你似乎想要的策略是“在 24 小时后过期” —— 事实上与“除非持续时间短于或长于 24 小时的日子”是一样的。“1 天”和“24 小时”一样神奇。😊
为了使你的代码更易读并且只在一个地方定义过期策略,你可以将 Temporal.Duration 存储在一个常量中:
const TOKEN_VALIDITY_DURATION = Temporal.Duration.from({ hours: 24 });
Temporal.Now.instant().add(TOKEN_VALIDITY_DURATION).epochSeconds;
如果你真的不想在你的代码中出现数字 24,这里是一个略短一些的忽略夏令时的转换版本,你可以使用 round()
而不是 total()
来避免构造第三个持续时间:
Temporal.Duration.from({ days: 1 }).round({ largestUnit: 'hours' })
英文:
In the end, you have to choose a policy for determining the expiration timestamp, and the policy that it seems you want is "expire after 24 hours" — this is factually the same as "expire after 1 day except on days that last shorter or longer than 24 hours". "1 day" is just as magic of a number as "24 hours." 😄
To make your code more readable and have the expiration policy only in one place, you might store a Temporal.Duration in a constant:
const TOKEN_VALIDITY_DURATION = Temporal.Duration.from({ hours: 24 });
Temporal.Now.instant().add(TOKEN_VALIDITY_DURATION).epochSeconds;
If you really don't want the number 24 in your code, here is a slightly shorter version of the conversion ignoring DST, where you could use round()
instead of total()
to avoid constructing a third duration:
Temporal.Duration.from({ days: 1 }).round({ largestUnit: 'hours' })
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论