【问题标题】:Proper way to get EPOCH timestamp in kotlin在 kotlin 中获取 EPOCH 时间戳的正确方法
【发布时间】:2022-12-12 04:49:37
【问题描述】:

我想以 "seconds":"nanoseconds" 格式获取 kotlin 中的 EPOCH 时间戳。

注意:请查看已接受的答案以获得正确的解决方案。

编辑:

这是我目前的解决方案,我相信会有更好的方法来实现这一目标,

import java.time.Instant
import java.time.temporal.ChronoUnit;
import kotlin.time.Duration.Companion.seconds

fun main() {
    val epochNanoseconds = ChronoUnit.NANOS.between(Instant.EPOCH, Instant.now())
    val epochSeconds = epochNanoseconds/1.seconds.inWholeNanoseconds
    val remainingFractionOfNanoSeconds = epochNanoseconds%1.seconds.inWholeNanoseconds
    println("$epochSeconds:$remainingFractionOfNanoSeconds")
}

示例输出:

1670251213:849754000

另一个例子(来自 cmets):对于 1670251213 秒 50000 纳秒,也称为十进制的 1670251213.00005 秒,我想要 1670251213:50000(意思是 :)。

有什么方法可以直接从 java.time.Instant 或任何其他可用的库中获取秒数和剩余纳秒数以方便地实现这一点?

已接受答案的解决方案:

import java.time.Instant

fun main() {
    val time = Instant.now()
    println("${time.epochSecond}:${time.nano}")
}

【问题讨论】:

  • “秒和剩余的纳秒”到底是什么意思?您是否想要自 1970-01-01T00:00Z 以来的整秒计数,以及从那时起以小数秒计的纳秒计数?
  • @BasilBourque 是的
  • 那为什么你的示例输出的小数部分有 18 位数字?纳秒仅使用 9 位数字。如果您的示例有误,请编辑您的问题以更正它。
  • 是的,我不需要太准确。精确到毫秒是可以的,但我需要这种格式来满足某些 json 模式。谢谢你的帮助。

标签: java kotlin epoch


【解决方案1】:

tl;博士

你太辛苦了。

Instant 对象询问自 1970-01-01T00:00Z 以来的整秒计数。制作一个字符串,附加 COLON 字符。然后在 Instant 的小数秒中附加纳秒计数。

instant.getEpochSecond() 
+ ":" 
+ instant.getNano() 

1670220134:130848

细节

无论是遗留的日期时间类(CalendarDate 等)还是现代的java.time类支持您请求的International Atomic Time (TAI)。传统计算机(以及 Java)的计时远不及原子钟准确。

也许您不严格地使用了该术语,并且实际上只想要自 1970 年第一时刻的纪元参考以来的纳秒计数,如 offset 来自 UTC 的零小时-分钟-秒 (1970-01-01T00:00Z) ) 在传统计算机硬件的限制内。

如果是这样,Instant 课程将为您工作。但要注意基于 OpenJDK 代码库的 Java 实现中的限制。

  • 在 Java 8 中,第一个是java.time类,当前时刻以milliseconds的分辨率捕获。
  • 在 Java 9+ 中,当前时刻以 microseconds 的分辨率捕获(通常取决于您的计算机硬件的限制)。

请注意,在所有版本(8、9 和更高版本)中,Instant 能够解析为 nanosecond。上面列出的限制涉及捕捉当下来自计算机硬件时钟。

Instant 类中时刻的内部表示包括两部分:

  • 自 1970-01-01T00:00Z 以来的整秒计数。
  • 用纳秒计数表示的小数秒。

Instant 类提供了一对访问器方法(getter)来查看这两个数字。

您的问题并不完全清楚,您似乎在要求这两个数字之间有一个冒号字符。

Instant instant = Instant.now() ;
String nanos = Long.toString( instant.getNano() ) ;
String output = 
    instant.getEpochSecond() 
    + ":" 
    + instant.getNano()
;

instant.toString(): 2022-12-05T06:12:33.294698Z

输出:1670220753:294698

如果您想在小数秒的右侧填充零,请使用 String.format

Instant instant = Instant.now() ;
String nanos = Long.toString( instant.getNano() ) ;
String output = 
    instant.getEpochSecond() 
    + ":" 
    + String.format( "%1$" + nanos.length() + "s", nanos ).replace(' ', '0') // Pad with leading zeros if needed.
;

看到这个code run at Ideone.com

instant.toString(): 2022-12-05T06:12:33.294698Z

输出:1670220753:294698000

或者,您可以实例化一个 BigDecimal 对象。

【讨论】:

  • 该解决方案是否包括闰秒?
  • @Vencat 不,闰秒被忽略。这在日历的上下文中是有意义的,因为闰秒的目的是减慢时钟,让日历(年-月-日)赶上来。如果您真的需要闰秒,这很不寻常,请将 ThreeTen-Extra 库添加到您的项目以访问其 org.threeten.extra.scale 包。
猜你喜欢
  • 2014-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-20
  • 2020-07-17
  • 1970-01-01
  • 2021-03-19
  • 2021-11-11
相关资源
最近更新 更多