1. 概述
在Java中处理日期时,我们常常会遇到以long值表示的日期/时间,这些值表示自纪元(1970年1月1日格林尼治标准时间00:00:00)以来的天数、秒数或毫秒数。
在这个简短的教程中,我们将探讨将long值转换为Java中的日期的不同方法。首先,我们将解释如何使用核心JDK类来实现这一目标。然后,我们将展示如何使用第三方Joda-Time库来达到相同的目标。
2. 使用Java 8+日期时间API
Java 8因其引入的新日期时间API功能而备受赞誉。这个API主要是为了弥补旧日期API的不足。接下来,让我们仔细看看这个API提供了什么,以回答我们的核心问题。
2.1. 使用Instant
类
最简单的解决方案是使用Java 8新日期时间API中引入的Instant
类。这个类描述了时间线上的一个单一瞬时点。
让我们实践一下:
@Test
void givenLongValue_whenUsingInstantClass_thenConvert() {
Instant expectedDate = Instant.parse("2020-09-08T12:16:40Z");
long seconds = 1599567400L;
Instant date = Instant.ofEpochSecond(seconds);
assertEquals(expectedDate, date);
}
如上所示,我们使用ofEpochSecond()
方法创建了一个Instant
类的对象。请注意,我们也可以使用ofEpochMilli()
方法,使用毫秒来创建Instant
实例。
2.2. 使用LocalDate
类
当你需要将long值转换为日期时,LocalDate
类是另一个可考虑的选择。这个类表示经典的日期,例如2023-10-17,不包含时间细节。
通常,我们可以使用LocalDate#ofEpochDay
方法来实现目标:
@Test
void givenLongValue_whenUsingLocalDateClass_thenConvert() {
LocalDate expectedDate = LocalDate.of(2023, 10, 17);
long epochDay = 19647L;
LocalDate date = LocalDate.ofEpochDay(epochDay);
assertEquals(expectedDate, date);
}
ofEpochDay()
方法根据给定的历元日创建LocalDate
类的实例。
3. 使用遗留的日期API
在Java 8之前,我们通常会使用java.util
包中的Date
或Calendar
类来达成目标。现在让我们看看如何使用这两个类将long值转换为日期。
3.1. 使用Date
类
Date
类表示具有毫秒精度的具体时间点。顾名思义,它提供了一系列方法,可以用来操作日期。它提供了将long值转换为日期的最简单方式,因为它有一个接受long类型参数的重载构造函数。
让我们演示一下:
@Test
void givenLongValue_whenUsingDateClass_thenConvert() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expectedDate = dateFormat.parse("2023-10-15 22:00:00");
long milliseconds = 1689458400000L;
Date date = new Date(milliseconds);
assertEquals(expectedDate, date);
}
请注意,Date
类已过时,属于旧API,因此在处理日期时不是最佳选择。
3.2. 使用Calendar
类
另一种解决方案是使用旧日期API中的Calendar
类。这个类提供了setTimeInMillis(long value)
方法,我们可以用它来将时间设置为给定的long值。
现在,让我们用另一个测试案例来说明这个方法的用法:
@Test
void givenLongValue_whenUsingCalendarClass_thenConvert() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expectedDate = dateFormat.parse("2023-07-15 22:00:00");
long milliseconds = 1689458400000L;
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
calendar.setTimeInMillis(milliseconds);
assertEquals(expectedDate, calendar.getTime());
}
同样,指定的long值表示自纪元以来经过的毫秒数。
4. 使用Joda-Time
最后,我们可以使用Joda-Time库来解决这个问题。首先,我们需要将其依赖项添加到pom.xml
文件中:
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.12.5</version>
</dependency>
Joda-Time也提供了其版本的LocalDate
类。接下来,我们将看到如何使用它将long值转换为LocalDate
对象:
@Test
void givenLongValue_whenUsingJodaTimeLocalDateClass_thenConvert() {
org.joda.time.LocalDate expectedDate = new org.joda.time.LocalDate(2023, 7, 15);
long milliseconds = 1689458400000L;
org.joda.time.LocalDate date = new org.joda.time.LocalDate(milliseconds, DateTimeZone.UTC);
assertEquals(expectedDate, date);
}
如图所示,LocalDate
提供了直接从long值构建日期的方法。
5. 总结
在这篇简短的文章中,我们详细解释了如何在Java中将long值转换为日期。
首先,我们展示了如何使用内置的JDK类进行转换。然后,我们展示了如何使用Joda-Time库来实现相同的目标。
本文中的所有代码可以在GitHub上找到。