如何从Java 8中的LocalDateTime获取毫秒数

Geo*_*lou 247 java datetime milliseconds java-8 java-time

我想知道如果有一种方法,因为1970年1月1日(时期),以获得当前毫秒使用新的LocalDate,LocalTimeLocalDateTimeJava的8类.

已知的方法如下:

long currentMilliseconds = new Date().getTime();
Run Code Online (Sandbox Code Playgroud)

要么

long currentMilliseconds = System.currentTimeMillis();
Run Code Online (Sandbox Code Playgroud)

Stu*_*rks 293

我不完全确定你的意思是"当前毫秒",但我认为这是自"世纪"以来的毫秒数,即1970年1月1日午夜.

如果你想现在找到自纪元以来的毫秒数,那么System.currentTimeMillis()就像Anubian Noob所指出的那样.如果是这样,没有理由使用任何新的java.time API来执行此操作.

但是,也许您已经LocalDateTime从某个地方拥有了一个或类似的对象,并且您希望将其转换为自纪元以来的毫秒数.直接这样做是不可能的,因为LocalDateTime对象族不知道他们所在的时区.因此需要提供时区信息来查找相对于时间的时间,以UTC为单位.

假设你有LocalDateTime这样的:

LocalDateTime ldt = LocalDateTime.of(2014, 5, 29, 18, 41, 16);
Run Code Online (Sandbox Code Playgroud)

你需要应用时区信息,给出一个ZonedDateTime.我和洛杉矶在同一时区,所以我会这样做:

ZonedDateTime zdt = ldt.atZone(ZoneId.of("America/Los_Angeles"));
Run Code Online (Sandbox Code Playgroud)

当然,这会对时区做出假设.并且存在可能发生的边缘情况,例如,如果本地时间恰好命名接近夏令时(夏令时)转换的时间.让我们把这些放在一边,但你应该知道存在这些情况.

无论如何,如果你能得到一个有效的ZonedDateTime,你可以将它转换为自纪元以来的毫秒数,如下所示:

long millis = zdt.toInstant().toEpochMilli();
Run Code Online (Sandbox Code Playgroud)

  • 使用zdt.get(ChronoField.MILLI_OF_SECOND)避免使用nanos数学.使用zdt.toInstant().toEpochMilli()避免所有数学运算 (15认同)
  • 当然,如果您需要的只是秒,而不是毫秒. (11认同)
  • 请注意,[ZonedDateTime](http://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html)已经*具有*getEpochSecond`方法(通过[ChronoZonedDateTime default](http: //docs.oracle.com/javase/8/docs/api/java/time/chrono/ChronoZonedDateTime.html#toEpochSecond--)).不需要'瞬间'. (4认同)
  • 请注意,`zdt.toInstant()。toEpochMilli();`会给您对应的UTC值的毫秒数,而不是您的分区日期时间。我发现这很困难。toInstant()给您一个UTC瞬间。如果您想要以毫秒为单位的当地时间,则**不会给您期望的**。因此,如果您使用的是+02:00分区时间,则返回的时间将比预期的少3600 * 2 * 1000毫秒。 (2认同)

bri*_*ian 72

我这样做我没有指定时区是,

System.out.println("ldt " + LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
System.out.println("ctm " + System.currentTimeMillis());
Run Code Online (Sandbox Code Playgroud)

ldt 1424812121078 
ctm 1424812121281
Run Code Online (Sandbox Code Playgroud)

如果您不喜欢System.current ....,请使用 Instant.now().toEpochMilli()

  • `System.currentTimeMillis()`是相对于UTC的,所以你应该使用`ZoneOffset.UTC`而不是`ZoneId.systemDefault()`. (12认同)
  • 不,Epoch与UTC相关,但您可以从当地区域获取当前时间. (3认同)
  • @ChristofferHammarström 自纪元以来经过的毫秒数是与时区无关的事实。无论您在一天中的什么时间调用它,毫秒数都是相同的。两个结果不同,因为 brian 的机器执行第二条命令花了 203 毫秒。 (3认同)
  • @GilbertS 你可能永远不应该使用这个确切的代码,按预期使用 API。当存储在计算机上或传输给其他用户时,日期时间应始终为 UTC。通常应使用用户自己的时区设置将其作为本地日期时间呈现给用户。 (2认同)

Dan*_*ani 18

要避免使用ZoneId,您可以:

LocalDateTime date = LocalDateTime.of(1970, 1, 1, 0, 0);

System.out.println("Initial Epoch (TimeInMillis): " + date.toInstant(ZoneOffset.ofTotalSeconds(0)).toEpochMilli());
Run Code Online (Sandbox Code Playgroud)

获得0作为价值,这是正确的!

  • `ZoneOffset.ofTotalSeconds(0)`它与`ZoneOffset.UTC`相同 (4认同)

Mar*_*eng 13

从Java 8开始,您就可以使用了

final long currentTimeJava8 = Instant.now().toEpochMilli();
Run Code Online (Sandbox Code Playgroud)

这给你的结果和

final long currentTimeJava1 = System.currentTimeMillis();
Run Code Online (Sandbox Code Playgroud)

  • 我希望看到上述内容的量化(特别是对于正常使用 - 例如不适用于某些性能关键的实时应用程序......) (3认同)
  • “为您提供与”相同的结果......但需要更多的 CPU 能力并给垃圾收集器带来更多压力。 (2认同)

小智 9

您还可以使用java.sql.Timestamp来获取毫秒数。

LocalDateTime now = LocalDateTime.now();
long milliSeconds = Timestamp.valueOf(now).getTime();
System.out.println("MilliSeconds: "+milliSeconds);
Run Code Online (Sandbox Code Playgroud)

  • 简而言之,它是作为“Date”的子类实现的,但通常不能作为“Date”处理。大多数从“Date”继承的方法和一个构造函数均已弃用。它的“toString”方法使用 JVM 的时区,这让很多人感到困惑,因为相同的“Timestamp”在不同的计算机上打印方式不同([示例](/sf/ask/2993667211/ -即时到java-sql-timestamp-without-zone-offset))。 (2认同)

Anu*_*oob 8

要以毫秒(从纪元开始)获取当前时间,请使用System.currentTimeMillis().


max*_*yme 7

为什么没有人提到这个方法LocalDateTime.toEpochSecond()

LocalDateTime localDateTime = ... // whatever e.g. LocalDateTime.now()
long time2epoch = localDateTime.toEpochSecond(ZoneOffset.UTC);
Run Code Online (Sandbox Code Playgroud)

这似乎比上面许多建议的答案要短得多......

  • 因为它只给出了几秒钟。奇怪的是没有 `toEpochMilli` 方法,考虑到你甚至可以在 LocalDateTime 中指定纳秒:有一个方法 `LocalDateTime.of(intyear, intmonth, int dayOfMonth, int hour, int 分钟, int第二,int nanoOfSecond)`。 (6认同)

Md.*_*man 7

你可以试试这个:

long diff = LocalDateTime.now().atZone(ZoneOffset.UTC).toInstant().toEpochMilli();
Run Code Online (Sandbox Code Playgroud)


Ben*_*Tec 6

如果是的话LocalDate,可以使用该toEpochDay()方法。它返回自 1970 年 1 月 1 日以来的天数。然后这个数字可以很容易地转换为毫秒:

long dateInMillis = TimeUnit.DAYS.toMillis(myLocalDate.toEpochDays());
Run Code Online (Sandbox Code Playgroud)

可以在此处找到文档。

如果是的话LocalDateTime,可以使用该toEpochSecond()方法。它返回自 1970 年 1 月 1 日以来的秒数。该数字也可以转换为毫秒:

long dateTimeInMillis = TimeUnit.SECONDS.toMillis(myLocalDateTime.toEpochSeconds());
Run Code Online (Sandbox Code Playgroud)

相关文档在这里


小智 5

对于 LocalDateTime 我这样做:

LocalDateTime.of(2021,3,18,7,17,24,341000000)
    .toInstant(OffsetDateTime.now().getOffset())
    .toEpochMilli()
Run Code Online (Sandbox Code Playgroud)