前言
在旧版的 Java 中,日期时间 API 存在诸多问题,其中有:
- 非线程安全: java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java日期类最大的问题之一。
- 设计很差: Java的日期/时间类的定义并不一致,在java.util和java.sql的包中都有日期类,此外用于格式化和解析的类在java.text包中定义。java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期,另外这两个类都有相同的名字,这就显得非常糟糕。
- 时区处理麻烦: 日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和java.util.TimeZone类,但他们同样存在上述所有的问题。
为了解决以上问题,Java 8引入了新的日期时间API。新API具有以下特点:
- 线程安全: 新的日期时间API中的类都是线程安全的。
- 不可变性: 与传统日期时间类不同,新的日期时间API中的类是不可变(immutable)的,这使得更容易编写高质量的代码。
- 类型安全性: 新的日期时间API中所有的类和接口都具有类型安全性,这意味着可以在编译时捕获许多常见的日期时间错误。
Java 8日期时间API中主要涉及到以下类和接口:
java.time.LocalDate
:表示一个ISO-8601格式的日期,不包含时间信息java.time.LocalTime
:表示一个ISO-8601格式的时间,不包含日期信息java.time.LocalDateTime
:表示一个ISO-8601格式的日期时间java.time.Instant
:表示从‘1970-01-01T00:00:00Z’开始的秒数(时间戳)java.time.Duration
:表示两个时刻之间的持续时间或时间段java.time.Period
:表示两个日期之间的天数、月数或年数java.time.ZonedDateTime
:表示带时区的日期时间信息java.time.temporal
:用于校正时间java.time.DateTimeFormatter
:用于格式化和解析日期时间信息
一、LocalDate、LocalTime以及LocalDateTime
- LocalDate主要表示日期类对象如:2024-11-06;
- LocalTime主要表示时间类对象如:20:31:00;
- LocalDateTime则是两个结合版,表示日期加时间如:2024-11-06T20:31:00。
这三者的使用方法其实是如出一辙的,下面我们以LocalDateTime为例,了解一下他们的作用及用法:
@Test
public void test3(){
LocalDateTime now = LocalDateTime.now();//当前时间 yyyy-MM-ddTHH:mm:ss
LocalDateTime localDateTime = LocalDateTime.of(2024, 11, 6, 12, 30, 30);//2024-11-06T12:30:30
LocalDateTime plusHours = localDateTime.plusHours(1);//加上一个小时 -> 2024-11-06T13:30:30
LocalDateTime minusMinutes = localDateTime.minusMinutes(10);//减去10分钟 -> 2024-11-06T12:20:30
int dayOfWeek = localDateTime.getDayOfWeek().getValue();//获取当前时间是一周中的第几天 -> 3
int year = localDateTime.getYear();//获取年 -> 2024
int month = localDateTime.getMonthValue();//获取月份 -> 11
int hour = localDateTime.getHour();//获取小时 -> 12
int minute = localDateTime.getMinute();//获取分钟 -> 30
int second = localDateTime.getSecond();//获取秒 -> 30
}
二、Instant 时间戳
- Instant:时间戳, 存储了一个从1970-01-01 00:00:00 以来的 秒 和 纳秒 数据
- getEpochSecond():获取的是秒
- toEpochMilli():获取的是毫秒
- getNano():获取的是纳秒
- ofEpochSecond():通过秒级时间戳获取Instant
- ofEpochMilli():通过毫秒级时间戳获取Instant
/**
* Instant : 时间戳, 存储了一个从1970-01-01 00:00:00 以来的 秒 和 纳秒 数据
* getEpochSecond() : 获取的是秒
* toEpochMilli() : 获取的是毫秒
* getNano() : 获取的是纳秒
* ofEpochSecond() : 通过秒级时间戳获取Instant
* ofEpochMilli() : 通过毫秒级时间戳获取Instant
*/
@Test
public void test4(){
Instant inst1 = Instant.now();//默认获取 UTC 时区
System.out.println("UTC 时区: " + inst1);//2024-11-06T12:44:24.803617100Z
System.out.println