我想知道是否有一种方法可以使用Java 8新的LocalDate
、LocalTime
或LocalDateTime
类获取自1970年1月1日(纪元)以来的当前毫秒数。
已知的方法如下:
long currentMilliseconds = new Date().getTime();
或者long currentMilliseconds = System.currentTimeMillis();
我想知道是否有一种方法可以使用Java 8新的LocalDate
、LocalTime
或LocalDateTime
类获取自1970年1月1日(纪元)以来的当前毫秒数。
已知的方法如下:
long currentMilliseconds = new Date().getTime();
或者long currentMilliseconds = System.currentTimeMillis();
我不完全确定你所说的“当前毫秒”是什么意思,但我会假设它是自1970年1月1日UTC午夜(epoch)以来的毫秒数。
如果你想要找到从现在开始到epoch的毫秒数,那么就像Anubian Noob指出的那样,使用System.currentTimeMillis()
。如果是这样的话,就没有必要使用任何新的java.time API。
但是,也许你已经有一个类似于LocalDateTime
的对象,并且想将其转换为自epoch以来的毫秒数。由于LocalDateTime
对象系列没有时区信息,因此无法直接进行转换。因此,需要提供时区信息以找到相对于UTC中的epoch时间。
假设你有一个像这样的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();
ZonedDateTime
也有 Instant
的 getNano
方法,所以你能否在你的示例中将 inst
替换为 zdt
? - mabi我不指定时区的做法是:
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()
。
System.out.println("ldt " + LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
替换System.out.println("ctm " + System.currentTimeMillis());
即可执行完全相同的语句两次,但您仍将看到与自上次执行相同语句以来经过的毫秒数相等的差异。 - Arvind Kumar Avinashjava.time.Instant.toEpochMilli()
。final long currentTimeJava8 = Instant.now().toEpochMilli();
给你与...相同的结果
final long currentTimeJava1 = System.currentTimeMillis();
为避免使用ZoneId,您可以这样做:
LocalDateTime date = LocalDateTime.of(1970, 1, 1, 0, 0);
System.out.println("Initial Epoch (TimeInMillis): " + date.toInstant(ZoneOffset.ofTotalSeconds(0)).toEpochMilli());
得到0作为值,没错!
ZoneOffset.ofTotalSeconds(0)
和 ZoneOffset.UTC
是相同的。 - Anton NZoneOffset
是ZoneId
的子类,所以我不会完全说你已经避免了它,但只要你满意就好了... - Ole V.V.ZoneId
的原因可能是什么? - Ole V.V.java.sql.Timestamp
来获取毫秒数。LocalDateTime now = LocalDateTime.now();
long milliSeconds = Timestamp.valueOf(now).getTime();
System.out.println("MilliSeconds: "+milliSeconds);
Timestamp
类已经过时且存在设计问题,因此我宁愿避免使用它,特别是当我们可以使用java.time
中的类,如LocalDateTime
。 - Ole V.V.Date
的子类实现,但通常不能作为Date
处理。继承自Date
的大多数方法和一个构造函数已被弃用。其toString
方法使用JVM的时区,在不同的计算机上打印相同的Timestamp
可能会导致混淆(例如)。 - Ole V.V.LocalDate.of(year, month, day)
替换现在即可。 - G_VSystem.currentTimeMillis()
。你可以尝试这个:
long diff = LocalDateTime.now().atZone(ZoneOffset.UTC).toInstant().toEpochMilli();
LocalDateTime
(始终仅使用UTC),那么最好仅针对REST、Websockets和其他逻辑使用 Instant
,然后当您想要使用本地偏移量格式化日期时间以供UI使用时,可以将该 Instant
传递给 ZonedDateTime
。在这种情况下,您不需要使用 LocalDateTime
。 - user924LocalDateTime.now().toInstant(OffsetDateTime.now().offset)
更容易。 - user924为什么没有人提到 LocalDateTime.toEpochSecond()
方法:
LocalDateTime localDateTime = ... // whatever e.g. LocalDateTime.now()
long time2epoch = localDateTime.toEpochSecond(ZoneOffset.UTC);
这里有一些方法可供使用,但没有人在这里提到。但我不明白为什么它们不能起作用。
对于LocalDate
,您可以使用toEpochDay()
方法。 它返回自 1970 年 01/01 起的天数。 然后,该数字可以轻松转换为毫秒:
long dateInMillis = TimeUnit.DAYS.toMillis(myLocalDate.toEpochDays());
文档可以在这里找到。
对于LocalDateTime
,您可以使用toEpochSecond()
方法。它返回自1970年01月01日以来的秒数。该数字还可以转换为毫秒:
long dateTimeInMillis = TimeUnit.SECONDS.toMillis(myLocalDateTime.toEpochSeconds());
这方面的文档可以在这里找到。
对于LocalDateTime,我是这样做的:
LocalDateTime.of(2021,3,18,7,17,24,341000000)
.toInstant(OffsetDateTime.now().getOffset())
.toEpochMilli()
System.currentTimeMillis()
函数有什么问题? - Dawood ibn KareemcurrentTimeMillis
在这种情况下是无关紧要的。可以认为它就像具有非常高精度的日历和挂钟,而且不用担心时区和地域性。因此,没有办法从LocalTime返回到“UTC时间”。 - Gus