在Java中将日期转换为Unix时间戳

2025/04/14

1. 概述

在计算机科学中,Unix时间戳(也称为纪元时间)是表示特定时间点的标准方式,它表示自1970年1月1日以来经过的秒数。

在本教程中,我们将讲解如何将经典日期转换为Unix时间戳。首先,我们将探索如何使用JDK内置方法来实现此目的。然后,我们将演示如何使用外部库(例如Joda-Time)来实现相同的目的。

2. 使用Java 8+日期时间API

Java 8引入了一个新的Date-Time API,我们可以用它来解答我们的核心问题。这个新的API附带了一些操作日期的方法和类,那么,让我们仔细看看每个选项。

2.1 使用Instant类

简而言之,Instant类模拟了时间轴上的瞬时点,该类提供了一种直接简洁的方法,可以从给定日期获取Unix时间

那么,让我们看看它的实际效果:

@Test
void givenDate_whenUsingInstantClass_thenConvertToUnixTimeStamp() {
    Instant givenDate = Instant.parse("2020-09-08T12:16:40Z");

    assertEquals(1599567400L, givenDate.getEpochSecond());
}

我们可以看到,Instant类提供了getEpochSecond()方法来获取指定日期的纪元时间戳(以秒为单位)。

2.2 使用LocalDateTime类

LocalDateTime是将日期转换为纪元时间时需要考虑的另一个选项,此类表示日期和时间的组合,通常以年、月、日、时、分、秒的形式显示。

通常,此类提供toEpochSecond()方法来获取指定日期时间的纪元时间(以秒为单位)

@Test
void givenDate_whenUsingLocalDateTimeClass_thenConvertToUnixTimeStamp() {
    LocalDateTime givenDate = LocalDateTime.of(2023, 10, 19, 22, 45);

    assertEquals(1697755500L, givenDate.toEpochSecond(ZoneOffset.UTC));
}

如上所示,与其他方法不同,toEpochSecond()接收一个ZoneOffset对象,它允许我们定义时区UTC的固定偏移量。

3. 使用旧版日期API

或者,我们可以使用旧API中的Date和Calendar类来实现相同的效果。那么,让我们深入研究一下,看看如何在实践中使用它们。

3.1 使用Date类

在Java中,Date类以毫秒精度表示特定的时间点,它提供了最简单的方法之一,即通过getTime()方法将日期转换为Unix时间戳

@Test
void givenDate_whenUsingDateClass_thenConvertToUnixTimeStamp() throws ParseException {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    Date givenDate = dateFormat.parse("2023-10-15 22:00:00");

    assertEquals(1697407200L, givenDate.getTime() / 1000);
}

通常,该方法返回自传入日期纪元以来的毫秒数。如我们所见,我们将结果除以1000,得到了纪元的秒数。然而,此类已过时,不应在处理日期时使用

3.2 使用Calendar类

类似地,我们可以使用同一个包java.util中的Calendar类,此类提供了许多设置和操作日期的方法。

使用Calendar,我们必须调用getTimeInMillis()来返回指定日期的Unix时间

@Test
void givenDate_whenUsingCalendarClass_thenConvertToUnixTimeStamp() throws ParseException {
    Calendar calendar = new GregorianCalendar(2023, Calendar.OCTOBER, 17);
    calendar.setTimeZone(TimeZone.getTimeZone("UTC"));

    assertEquals(1697500800L, calendar.getTimeInMillis() / 1000);
}

请注意,此方法顾名思义,以毫秒为单位返回时间戳。这种选择的缺点是,Calendar已被声明为事实上的遗留API,因为它属于旧API

4. 使用Joda-Time

另一个解决方案是使用Joda-Time库,在开始使用该库之前,让我们先将其依赖添加到pom.xml中:

<dependency>
    <groupId>joda-time</groupId> 
    <artifactId>joda-time</artifactId> 
    <version>2.12.6</version> 
</dependency>

Joda-Time提供了Instant类的版本,我们可以用它来应对我们的挑战。那么,让我们用一个新的测试用例来说明如何使用这个类:

@Test
void givenDate_whenUsingJodaTimeInstantClass_thenConvertToUnixTimeStamp() {
    org.joda.time.Instant givenDate = org.joda.time.Instant.parse("2020-09-08T12:16:40Z");

    assertEquals(1599567400L, givenDate.getMillis() / 1000);
}

如图所示,Instant类提供了一种直接的方法来获取自纪元以来的毫秒数。

DateTime类是使用Joda-Time时要考虑的另一种解决方案,它提供了getMillis()方法,返回自DateTime时刻以来经过的毫秒数:

@Test
void givenDate_whenUsingJodaTimeDateTimeClass_thenConvertToUnixTimeStamp() {
    DateTime givenDate = new DateTime("2020-09-08T12:16:40Z");

    assertEquals(1599567400L, givenDate.getMillis() / 1000);
}

测试用例成功通过。

5. 总结

在这篇短文中,我们探讨了将给定日期转换为Unix时间戳的不同方法。

首先,我们解释了如何使用核心JDK方法和类来实现这一点。然后,我们展示了如何使用Joda-Time实现同样的目标。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章