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

问题描述 投票:0回答:14

我想知道是否有办法使用 Java 8 的新

LocalDate
LocalTime
LocalDateTime
类获取自 1970 年 1 月 1 日(纪元)以来的当前毫秒数。

已知的方法如下:

long currentMilliseconds = new Date().getTime();

long currentMilliseconds = System.currentTimeMillis();
java datetime java-8 milliseconds java-time
14个回答
444
投票

我不太确定“当前毫秒”是什么意思,但我假设它是自“纪元”(即 UTC 时间 1970 年 1 月 1 日午夜)以来的毫秒数。

如果您想立即找到自纪元以来的毫秒数,然后使用

System.currentTimeMillis()
,就像Anubian Noob指出的那样。如果是这样,就没有理由使用任何新的 java.time API 来执行此操作。

但是,也许您已经在某个地方有一个

LocalDateTime
或类似的对象,并且您想将其转换为自纪元以来的毫秒数。直接执行此操作是不可能的,因为
LocalDateTime
系列对象不知道它们所在的时区。因此,需要提供时区信息来查找相对于纪元(UTC 格式)的时间。

假设你有一个像这样的

LocalDateTime

LocalDateTime ldt = LocalDateTime.of(2014, 5, 29, 18, 41, 16);

您需要应用时区信息,给出

ZonedDateTime
。我和洛杉矶在同一时区,所以我会做这样的事情:

ZonedDateTime zdt = ldt.atZone(ZoneId.of("America/Los_Angeles"));

当然,这对时区做出了假设。并且可能会出现一些边缘情况,例如,如果本地时间碰巧指定了夏令时(夏令时)过渡附近的时间。让我们把这些放在一边,但你应该知道这些情况是存在的。

无论如何,如果您可以获得有效的

ZonedDateTime
,您可以将其转换为自纪元以来的毫秒数,如下所示:

long millis = zdt.toInstant().toEpochMilli();

139
投票

我所做的就是不指定时区,

System.out.println("ldt " + LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
System.out.println("ctm " + System.currentTimeMillis());

给予

ldt 1424812121078 
ctm 1424812121281

如您所见,除了执行时间较短之外,数字是相同的。

以防万一您不喜欢 System.currentTimeMillis,请使用

Instant.now().toEpochMilli()


26
投票

从 Java 8 开始,您可以调用

java.time.Instant.toEpochMilli()

例如通话

final long currentTimeJava8 = Instant.now().toEpochMilli();

为您提供与

相同的结果
final long currentTimeJava1 = System.currentTimeMillis();

24
投票

为了避免使用 ZoneId,你可以这样做:

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

System.out.println("Initial Epoch (TimeInMillis): " + date.toInstant(ZoneOffset.ofTotalSeconds(0)).toEpochMilli());

获取0作为值,没错!


15
投票

您还可以使用

java.sql.Timestamp
来获取毫秒。

LocalDateTime now = LocalDateTime.now();
long milliSeconds = Timestamp.valueOf(now).getTime();
System.out.println("MilliSeconds: "+milliSeconds);

13
投票

要获取当前时间(以毫秒为单位)(自纪元以来),请使用

System.currentTimeMillis()


12
投票

你可以试试这个:

long diff = LocalDateTime.now().atZone(ZoneOffset.UTC).toInstant().toEpochMilli();

7
投票

为什么没有人提到方法

LocalDateTime.toEpochSecond()
:

LocalDateTime localDateTime = ... // whatever e.g. LocalDateTime.now()
long time2epoch = localDateTime.toEpochSecond(ZoneOffset.UTC);

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


6
投票

如果是

LocalDate
,您可以使用
toEpochDay()
方法。它返回自 1970 年 1 月 1 日以来的天数。然后该数字可以轻松转换为毫秒:

long dateInMillis = TimeUnit.DAYS.toMillis(myLocalDate.toEpochDays());

可以在此处找到文档。

如果是

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

long dateTimeInMillis = TimeUnit.SECONDS.toMillis(myLocalDateTime.toEpochSeconds());

相关文档位于此处


5
投票

对于 LocalDateTime 我这样做:

LocalDateTime.of(2021,3,18,7,17,24,341000000)
    .toInstant(OffsetDateTime.now().getOffset())
    .toEpochMilli()

4
投票

我认为这更简单:

ZonedDateTime zdt = ZonedDateTime.of(LocalDateTime.now(), ZoneId.systemDefault());
Assert.assertEquals(System.currentTimeMillis(), zdt.toInstant().toEpochMilli());

像 System.currentTimeMillis() 一样获取毫秒(来自 UTC)。


3
投票

如果您有 Java 8 时钟,那么您可以使用

clock.millis()
(尽管建议您使用
clock.instant()
来获取 Java 8 Instant,因为它更准确)。

为什么要使用 Java 8 时钟?因此,在您的 DI 框架中,您可以创建一个 Clock bean:

@Bean
public Clock getClock() {
    return Clock.systemUTC();
}

然后在你的测试中你可以轻松地模拟它:

@MockBean private Clock clock;

或者你可以有不同的豆子:

@Bean
public Clock getClock() {
    return Clock.fixed(instant, zone);
}

这有助于进行无法估量的断言日期和时间的测试。


3
投票

日期和时间为长整型字符串(毫秒):

String dateTimeString = "2020-12-12T14:34:18.000Z";

DateTimeFormatter formatter = DateTimeFormatter
                .ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH);

LocalDateTime localDateTime = LocalDateTime
        .parse(dateTimeString, formatter);

Long dateTimeMillis = localDateTime
        .atZone(ZoneId.systemDefault())
        .toInstant()
        .toEpochMilli();

2
投票
  default LocalDateTime getDateFromLong(long timestamp) {
    try {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneOffset.UTC);
    } catch (DateTimeException tdException) {
      //  throw new 
    }
}

default Long getLongFromDateTime(LocalDateTime dateTime) {
    return dateTime.atOffset(ZoneOffset.UTC).toInstant().toEpochMilli();
}
© www.soinside.com 2019 - 2024. All rights reserved.