Java

Java 知识量:11 - 45 - 220

9.3 处理日期和时间><

日期和时间API- 9.3.1 -

Java 8引入了一个全新的日期和时间API,位于java.time包中,这个API比之前的java.util.Date和java.util.Calendar更加强大和灵活。

以下是这个API中一些主要的类和用法:

  • LocalDate:表示一个日期,例如2023-07-06。可以使用静态方法LocalDate.now()获取当前日期,或者使用LocalDate.of(year, month, dayOfMonth)创建一个指定日期的实例。

  • LocalTime:表示一个时间,例如14:30。可以使用静态方法LocalTime.now()获取当前时间,或者使用LocalTime.of(hour, minute)创建一个指定时间的实例。

  • LocalDateTime:表示一个日期和时间,例如2023-07-06T14:30。可以使用静态方法LocalDateTime.now()获取当前日期和时间,或者使用LocalDateTime.of(year, month, dayOfMonth, hour, minute)创建一个指定日期和时间的实例。

  • ZonedDateTime:表示一个带有时区的日期和时间。可以使用静态方法ZonedDateTime.now()获取当前日期和时间,或者使用ZonedDateTime.of(localDateTime, zoneId)创建一个指定日期、时间和时区的实例。

  • Period:表示一段时间,例如2天、3小时、4分钟。可以使用Period.between(startDate, endDate)方法计算两个日期之间的时间差。

  • Duration:表示一段时间的长度,例如PT2H3M4S(2小时3分钟4秒)。可以使用Duration.between(startTime, endTime)方法计算两个时间之间的时间差。

  • ZoneId:表示一个时区。可以使用ZoneId.of(id)方法根据时区ID创建一个时区实例,或者使用ZoneId.systemDefault()方法获取系统默认时区。

  • Clock:提供了一种获取当前日期和时间的方式,可以与实际时间同步,也可以与某个特定的时间点同步。可以使用Clock.systemDefaultZone()方法获取系统默认时区的时钟,或者使用Clock.fixed(instant, zoneId)方法创建一个固定时间点的时钟。

时间戳- 9.3.2 -

时间戳(timestamp)通常指的是自1970年1月1日00:00:00 GMT以来的秒数,不包括闰秒。这是一种通用的方式来表示特定的时间点,可以跨多种操作系统和语言使用。

时间戳(time-stamp)是一个经加密后形成的凭证文档,由以下三个部分组成:

  • 需加时间戳的文件的摘要(digest):用户首先将需要加时间戳的文件用Hash编码加密形成摘要。

  • DTS收到文件的日期和时间:DTS(时间戳服务中心,Time-stamp Service Center)在收到文件摘要后,会加入收到文件的日期和时间信息。

  • DTS的数字签名:DTS对加入时间信息后的文件摘要进行数字签名。

这个过程保证了时间戳的准确性和不可篡改性,因为文件摘要和时间信息都是由DTS加密并签名的。书面签署文件的时间是由签署人自己写上的,而数字时间戳则是由认证单位DTS来加的,以DTS收到文件的时间为依据。

在Java中,可以使用java.time包中的类来处理时间戳。例如,Instant类可以用来表示一个时间戳,ZoneId类可以用来表示时区,ZonedDateTime类可以用来表示一个带有时区的日期和时间。

以下是如何在Java中获取当前时间戳的示例:

import java.time.Instant;  
  
public class Main {  
    public static void main(String[] args) {  
        // 获取当前时间戳(以秒为单位)  
        long timestamp = Instant.now().toEpochMilli();  
        System.out.println("当前时间戳: " + timestamp);  
    }  
}

在这个例子中,Instant.now()方法获取了当前的日期和时间(以UTC时间为准),然后toEpochMilli()方法将这个日期和时间转换成了自1970年1月1日00:00:00 GMT以来的毫秒数。

也可以将时间戳转换成日期和时间:

import java.time.Instant;  
import java.time.ZoneId;  
import java.time.ZonedDateTime;  
  
public class Main {  
    public static void main(String[] args) {  
        // 获取当前时间戳(以秒为单位)  
        long timestamp = Instant.now().toEpochMilli();  
        System.out.println("当前时间戳: " + timestamp);  
          
        // 将时间戳转换成日期和时间  
        Instant instant = Instant.ofEpochMilli(timestamp);  
        ZonedDateTime dateTime = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());  
        System.out.println("转换后的日期和时间: " + dateTime);  
    }  
}

在这个例子中,Instant.ofEpochMilli(timestamp)方法将时间戳转换成了Instant对象,然后ZonedDateTime.ofInstant(instant, ZoneId.systemDefault())方法将Instant对象转换成了带有系统默认时区的ZonedDateTime对象。

过时的日期和时间API- 9.3.3 -

在Java 8引入新的日期和时间API之前,Java中主要使用的日期和时间API是位于java.util包中的Date和Calendar类。然而,这些类已经被认为是过时的(deprecated),并且在新的代码中不再推荐使用。

以下是这些过时类的一些主要问题和局限性:

  • 非线程安全:Date和Calendar类都不是线程安全的,这意味着在多线程环境中使用它们可能会导致数据不一致和其他问题。

  • 设计问题:Date和Calendar类的API设计不够直观,使用起来比较复杂,而且容易出错。例如,Date类的年份是从1900年开始计算的,月份从0开始计数,这都容易引发错误。

  • 时区处理不当:Date类没有提供时区的支持,而Calendar类的时区支持也比较薄弱。这使得处理涉及时区的日期和时间变得更加困难。

  • 精度问题:Date类只能以毫秒精度表示时间,这在某些情况下可能不够精确。

由于这些问题,Java 8引入了新的日期和时间API,该API设计得更易于使用、更直观,同时也提供了更强大的功能。它支持日期和时间的各种操作,包括解析、格式化、计算时间差、调整日期和时间等等。在新的代码中,应该优先使用新的日期和时间API,而不是过时的Date和Calendar类。