Java中获取当前时间的7种方法

Java 提供了诸如Calendar和Date之类的遗留类来处理日期和时间信息。然而,由于设计缺陷,Java 8 DateTime API 引入了新的类。Date 、Calendar和SimpleDateFormatter类是可变的并且不是线程安全的。

我们将首先查看遗留类Calendar和Date来生成时间戳并获得基本的了解,然后了解 Java 8 DateTime API 类,例如Instant、LocalDateTime、ZonedDateTime和OffsetDateTime。

值得注意的是,对于较新的 Java 程序,建议使用 Java 8 DateTime API 类,而不是旧版 Java 日期和时间类。

1. 使用Calendar日历
最基本的方法是使用Calendar.getInstance()方法,该方法返回使用默认时区和区域设置的Calendar实例。此外,getTime() 方法为我们提供了以毫秒为单位的时间值:

@Test
public void whenUsingCalender_thenGetCurrentTime() {
    String currentTime = SIMPLEDATE_FORMAT.format(Calendar.getInstance().getTime());
    String fileName = getFileName(currentTime);
  
    assertTrue(verifyFileName(fileName));
}

SimpleDateFormatter类可以将时间值转换为适当的时间戳格式。

2. 使用Date
类似地,我们可以构造一个Date类的对象,以毫秒为单位表示对象的创建时间。SimpleDateFormatter将毫秒时间值转换为所需的字符串模式:

@Test
public void whenUsingDate_thenGetCurrentTime() {
    String currentTime = SIMPLEDATE_FORMAT.format(new Date());
    String fileName = getFileName(currentTime);
  
    assertTrue(verifyFileName(fileName));
}

建议使用我们将在下一节中看到的新 Java 8 类。

3. 使用即nstant
在 Java 中,Instant类表示 UTC 时间轴上的单个时刻:

@Test
public void whenUsingInstant_thenGetCurrentTime() {
    String currentTime = Instant
      .now()
      .truncatedTo(ChronoUnit.SECONDS)
      .toString()
      .replaceAll("[:TZ-]", "");
    String fileName = getFileName(currentTime);
    assertTrue(verifyFileName(fileName));
}

Instant.now()方法询问系统时钟当前时刻。我们可以使用truncatedTo()方法将值四舍五入到最接近的秒。然后可以将第二个值更改为字符串,以替换时间戳中时区信息中的任何不需要的字符。

4. 使用LocalDateTime
LocalDateTime表示 ISO-8601 日历系统中没有时区的日期和时间:

@Test
public void whenUsingLocalDateTime_thenGetCurrentTime() {
    String currentTime = LocalDateTime.now().format(DATETIME_FORMATTER);
    String fileName = getFileName(currentTime);
    assertTrue(verifyFileName(fileName));
}

LocalDateTime.now()方法查询默认系统时钟以提供日期时间信息。然后我们可以传递一个DateTimeFormatter将时间戳格式化为字符串

5. 使用ZonedDateTime
ZonedDateTime是带有时区的日期时间的不可变表示形式:

@Test
public void whenUsingZonedDateTime_thenGetCurrentTime() {
    String currentTime = ZonedDateTime
      .now(ZoneId.of("Europe/Paris"))
      .format(DATETIME_FORMATTER);
    String fileName = getFileName(currentTime);
    assertTrue(verifyFileName(fileName));
}

时区标识符能够唯一标识地球上的特定地理位置,例如“欧洲/巴黎”。使用此标识,我们可以获得 ZoneId ,它确定用于从 Instant 到LocalDateTime 转换的时区。

ZonedDateTime自动处理全年夏令时 (DST) 调整。

6. 使用OffsetDateTime
OffsetDateTime是忽略时区的ZonedDateTime的简化版本。世界不同地区的时区偏移量有所不同。例如,“ +2:00 ”表示某个时区的时间比 UTC 晚两小时。我们可以通过使用ZoneOffSet 的偏移值来更改 UTC 中的默认时间:

@Test
public void whenUsingOffsetDateTime_thenGetCurrentTime() {
    String currentTime = OffsetDateTime
      .of(LocalDateTime.now(), ZoneOffset.of("+02:00"))
      .format(DATETIME_FORMATTER);
    String fileName = getFileName(currentTime);
    assertTrue(verifyFileName(fileName));
}

ZonedDateTime和OffsetDateTime都存储时间线的瞬间,精度高达纳秒。了解它们的差异有助于我们在它们之间进行选择。

7、使用Joda-Time 的当前时间
Joda-Time 是一个著名的日期和时间处理库。它是开发人员中最流行的库之一,可以替代麻烦的遗留 Java 类。它使用不可变类处理日期和时间值。
在pom.xml中添加 Joda-Time Maven依赖项:

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

DateTime.now()方法使用默认时区获取设置为当前系统毫秒时间的DateTime 。然后我们可以将其转换为具有定义的时间戳格式的字符串:

@Test
public void whenUsingJodaTime_thenGetCurrentTime() {
    String currentTime = DateTime.now().toString(TIMESTAMP_FORMAT);
    String fileName = getFileName(currentTime);
    assertTrue(verifyFileName(fileName));
}

Joda-Time 库还提供Instant类来捕获当前时间轴中的时刻。我们可以使用DateTimeFormat将时间戳转换为所需的字符串模式:

@Test
public void whenUsingJodaTimeInstant_thenGetCurrentTime() {
    String currentTime = DateTimeFormat
      .forPattern(TIMESTAMP_FORMAT)
      .print(org.joda.time.Instant.now().toDateTime());
    String fileName = getFileName(currentTime);
    assertTrue(verifyFileName(fileName));
}