我如何创建一个Java 8 LocalDate从一个长Epoch时间毫秒?

我有一个外部API,它将日期返回为longs,表示为纪元开始以来的毫秒数。

使用旧风格的Java API,我将简单地从它构造Date

Date myDate = new Date(startDateLong)

在Java 8的LocalDate/LocalDateTime类中等价的是什么?

我感兴趣的是将由long表示的时间点转换为当前本地时区中的LocalDate

286298 次浏览

你可以从Instant.ofEpochMilli(长)开始:

LocalDate date =
Instant.ofEpochMilli(startDateLong)
.atZone(ZoneId.systemDefault())
.toLocalDate();

如果你有Epoch之后的毫秒数,并且想要使用当前本地时区将它们转换为本地日期,你可以使用Instant.ofEpochMilli(long epochMilli)

LocalDate date =
Instant.ofEpochMilli(longValue).atZone(ZoneId.systemDefault()).toLocalDate();

但请记住,即使是系统的默认时区也可能会改变,因此相同的long值可能在后续运行中产生不同的结果,即使是在同一台机器上。

此外,请记住,LocalDatejava.util.Date不同,它真正代表的是日期,而不是日期和时间。

否则,你可以使用LocalDateTime:

LocalDateTime date =
LocalDateTime.ofInstant(Instant.ofEpochMilli(longValue), ZoneId.systemDefault());

抛开时区和其他东西不考虑,new Date(startDateLong)的一个非常简单的替代方法可以是LocalDate.ofEpochDay(startDateLong / 86400000L)

我想我有更好的答案。

new Timestamp(longEpochTime).toLocalDateTime();

在一个特定的情况下,你的epoch seconds时间戳来自SQL或以某种方式与SQL相关,你可以像这样获得它:

long startDateLong = <...>


LocalDate theDate = new java.sql.Date(startDateLong).toLocalDate();

用long值替换now.getTime()。

//GET UTC time for current date
Date now= new Date();
//LocalDateTime utcDateTimeForCurrentDateTime = Instant.ofEpochMilli(now.getTime()).atZone(ZoneId.of("UTC")).toLocalDateTime();
LocalDate localDate = Instant.ofEpochMilli(now.getTime()).atZone(ZoneId.of("UTC")).toLocalDate();
DateTimeFormatter dTF2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
System.out.println(" formats as " + dTF2.format(utcDateTimeForCurrentDateTime));

我不太喜欢在项目中同时使用instant和localdate。

我会做什么:

 val calendar = Calendar.getInstance().apply {
//set timeZone because calendar.timeInMillis = UTC milliseconds
//and calender uses the default timezone
timeZone = TimeZone.getTimeZone("UTC")
}
calendar.clear()
calendar.set(localDate.year, localDate.monthValue - 1, localDate.dayOfMonth)
val millis = calendar.timeInMillis

一个基于@Michael Piefel回答的简单版本:

LocalDate myDate = LocalDate.ofEpochDay(Duration.ofMillis(epochMillis).toDays());

我已经测试了LocalDateTime的替代解决方案:

public static LocalDateTime increaseByMillis(final LocalDateTime ldt, final long millis)
{
return LocalDateTime.ofInstant(Instant.ofEpochMilli(ldt.toInstant(ZoneOffset.UTC).toEpochMilli()+millis), ZoneId.of(ZoneOffset.UTC.getId()));
}

测试:

LocalDateTime test = LocalDateTime.now();
LocalDateTime increased = MyUtilsAbc.increaseByMillis(test, 1000);


Assert.assertEquals("Increase of LocalDateTime not working (anymore)!", test.toEpochSecond(ZoneOffset.UTC) +1, increased.toEpochSecond(ZoneOffset.UTC));