Java 日期和时间

2025年2月12日 | 阅读 6 分钟

java.time、java.util、java.sql 和 java.text 包包含用于表示日期和时间的类。 以下类对于处理 Java 中的日期很重要。

Java 8 日期/时间 API

Java 通过使用两个包 java.time 和 java.util 提供日期和时间功能。java.time 包是在 Java 8 中引入的,新引入的类试图克服旧版 java.util.Date 和 java.util.Calendar 类的缺点。

java.time.LocalDate 类

表示没有时间的日期,例如 2024-05-30。

用于表示生日、周年纪念日或任何基于日期的事件,而无需时间。

java.time.LocalTime 类

表示没有日期的具体时间,例如 10:15:30。

非常适合表示一天中的时间,例如营业时间或火车时刻表。

java.time.LocalDateTime 类

结合日期和时间,没有时区信息。

用于本地时间的时间戳事件。

java.time.ZonedDateTime 类

结合日期和时间以及时区信息。

用于需要时区意识的全局时间戳。

java.time.OffsetTime 类

表示相对于 UTC 的固定偏移量的时间。

java.time.OffsetDateTime 类

表示相对于 UTC 的固定偏移量的日期和时间。

java.time.Clock 类

使用时区提供对当前时刻、日期和时间的访问。

java.time.Instant 类

表示自纪元(1970-01-01T00:00:00Z)以来以纳秒为单位的时间线上的一个时刻。

java.time.Duration 类

测量两个时刻之间的时间,以秒和纳秒为单位。

java.time.Period 类

测量两个日期之间的时间量,以年、月和天为单位。

java.time.ZoneId 类

表示时区 ID,例如 Europe/Paris。

java.time.ZoneOffset 类

表示与 UTC 的时区偏移量。

java.time.format.DateTimeFormatter 类

用于解析和格式化日期时间对象。

传统日期/时间 API

但是传统的或旧的 Java 日期 API 也有用。 让我们看看传统的日期和时间类的列表。

java.util.Date 类

表示时间上的一个特定时刻,精确到毫秒。

java.sql.Date 类

java.util.Date 的一个瘦包装器,允许 JDBC 将其标识为 SQL DATE 值。

java.util.Calendar 类

用于在特定时刻和一组日历字段之间进行转换的抽象类。

java.util.GregorianCalendar 类

Calendar 的具体子类,它提供世界上大多数国家/地区使用的标准日历系统。

java.util.TimeZone 类

表示时区偏移量并计算夏令时。

java.sql.Time 类

java.util.Date 的一个包装器,允许 JDBC API 将其标识为 SQL TIME 值。

java.sql.Timestamp 类

它扩展了 java.util.Date 类,以提供纳秒精度。

java.text.DateFormat 类

用于日期/时间格式化子类的抽象类,用于格式化和解析日期或时间。

java.text.SimpleDateFormat 类

用于以区域设置敏感的方式格式化和解析日期的具体类。

格式化日期和时间

我们可以使用以下类在 Java 中格式化日期和时间

现有日期/时间 API 的缺点

  1. 线程安全: 现有类(例如 Date 和 Calendar)不提供线程安全性。 因此,它会导致难以调试的并发问题,需要由开发人员处理。 Java 8 的新日期和时间 API 提供了线程安全性并且是不可变的,因此避免了开发人员的并发问题。
  2. 糟糕的 API 设计: 经典的 Date 和 Calendar API 没有提供执行日常基本功能的方法。 Java 8 中引入的日期和时间类以 ISO 为中心,并提供了许多用于执行与日期、时间、持续时间和周期相关的操作的方法。
  3. 难以处理时区: 使用经典的 Date 和 Calendar 类处理时区很困难,因为开发人员应该为此编写逻辑。 使用新的 API,可以使用 Local 和 ZonedDate/Time API 轻松完成时区处理。

Java 8 中的新日期时间 API

新的日期 API 有助于克服上述旧版类的缺点。 它包括以下类

java.time.LocalDate: 它表示 ISO 日历中的年-月-日,对于表示没有时间的日期很有用。 它可以用于仅表示日期信息,例如出生日期或结婚日期。

java.time.LocalTime: 它仅处理时间。 它对于表示基于人类的时间,例如电影时间,或当地图书馆的开放和关闭时间很有用。

java.time.LocalDateTime: 它同时处理日期和时间,没有时区。 它是 LocalDate 和 LocalTime 的组合。

java.time.ZonedDateTime: 它将 LocalDateTime 类与 ZoneId 类中给出的区域信息相结合。 它表示一个完整的时间戳以及时区信息。

java.time.OffsetTime: 它处理时间,并带有相对于格林威治/UTC 的相应时区偏移量,而没有时区 ID。

java.time.OffsetDateTime: 它处理日期和时间,并带有相对于格林威治/UTC 的相应时区偏移量,而没有时区 ID。

java.time.Clock: 它提供对任何给定时区中的当前时刻、日期和时间的访问。 尽管 Clock 类的使用是可选的,但此功能允许我们测试其他时区的代码,或者通过使用固定时钟(时间不改变)。

java.time.Instant: 它表示时间线上的纳秒开始(自 EPOCH 以来),并用于生成表示机器时间的时间戳。 在纪元之前发生的时刻具有负值,在纪元之后发生的时刻具有正值。

java.time.Duration: 两个时刻之间的差异,以秒或纳秒为单位衡量,并且不使用基于日期的结构,例如年、月和日,尽管该类提供了转换为日、小时和分钟的方法。

java.time.Period: 它用于定义基于日期的值(年、月、日)中日期之间的差异。

java.time.ZoneId: 它声明一个时区标识符,并提供用于在 Instant 和 LocalDateTime 之间进行转换的规则。

java.time.ZoneOffset: 它描述了与格林威治/UTC 时间的时区偏移量。

java.time.format.DateTimeFormatter: 它带有各种预定义的格式化程序,或者我们可以定义自己的格式化程序。 它具有用于解析和格式化日期时间值的 parse() 或 format() 方法。

Java 8 日期/时间 API 的优点

不可变性和线程安全性

java.time 包中的类在设计上是不可变的且线程安全的。

丰富的实用程序集

API 提供了许多用于处理常见日期和时间操作的方法,使代码更具可读性和可维护性。

增强的时区支持

java.time 包包括对时区的全面支持,包括 ZoneId 和 ZonedDateTime 类。

清晰度和精度

新的 API 提供了更精确的时间测量,并清楚地区分不同类型的日期和时间表示(例如,LocalDate 与 ZonedDateTime)。

Java 8 日期/时间 API 的示例用法

解析和格式化

计算差异

使用时区

结论

与传统的日期/时间 API 相比,Java 8 日期/时间 API 提供了更强大、更直观且线程安全的方式来处理 Java 中的日期和时间。 它解决了旧 API 的许多缺点,使开发人员更容易有效地使用日期和时间信息。


下一个主题Java LocalDate 类