1. 背景介绍
在Java8之前,Date和Calendar两个类占据了Java中对时间操作的几乎所有地方,但由于它们的可变性和非线程安全性也时常导致了一些bug的产生;所以在Java8中引入了新的日期时间相关类,放在java.time
包下;
2. 新日期时间相关类介绍
- LocalDate:本地日期,不包含时区;
- LocalTime:本地时间,不包含时区;
- LocalDateTime:本地日期+时间,内部维护者一对LocalDate与LocalTime实例,同时也不包含时区;
- ZoneId:时区标识符,是Instant和LocalDateTime之间转换的规则;
- ZoneOffset:格林威治/UTC时间之间的时区偏移量;
- ZonedDateTime:一个包含得有时区标识符和时区偏移量的日期+时间类,内部维护者LocalDateTime、ZoneId、ZoneOffset三个实例;
- Instant:一个可以精确到纳秒的时间戳类;
- DateTimeFormatter:日期时间格式化与解析类;
3. 新日期时间常用API介绍
-
LocalDate
public class LocalDateTimeTest { public static void main(String[] args) { // 获取当前日期 LocalDate date1 = LocalDate.now(); System.out.println("date1: " + date1); System.out.println("date1 year: " + date1.getYear()); System.out.println("date1 month: " + date1.getMonthValue()); System.out.println("date1 day: " + date1.getDayOfMonth()); // 创建LocalDate实例 LocalDate date2 = LocalDate.of(2021, 1, 1); System.out.println("date2: " + date2); // 修改LocalDate实例, 返回一个新的实例 LocalDate date3 = date2.plus(7, ChronoUnit.DAYS); System.out.println("date3: " + date3); // 解析日期字符串 LocalDate date4 = LocalDate.parse("20210131", DateTimeFormatter.ofPattern("yyyyMMdd")); System.out.println("date4: " + date4); } }
// 运行结果 date1: 2021-04-20 date1 year: 2021 date1 month: 4 date1 day: 20 date2: 2021-01-01 date3: 2021-01-08 date4: 2021-01-31
-
LocalTime
public class LocalDateTimeTest { public static void main(String[] args) { // 获取当前时间 LocalTime time1 = LocalTime.now(); System.out.println("time1: " + time1); System.out.println("time1 hour: " + time1.getHour()); System.out.println("time1 minute: " + time1.getMinute()); System.out.println("time1 second: " + time1.getSecond()); System.out.println("time1 nano: " + time1.getNano()); // 创建LocalTime实例 LocalTime time2 = LocalTime.of(8, 8, 8); System.out.println("time2: " + time2); // 修改LocalTime实例, 返回一个新的实例 LocalTime time3 = time2.plus(7, ChronoUnit.MINUTES); System.out.println("time3: " + time3); // 解析时间字符串 LocalTime time4 = LocalTime.parse("12:30:10", DateTimeFormatter.ofPattern("HH:mm:ss")); System.out.println("time4: " + time4); } }
// 运行结果 time1: 14:20:35.276 time1 hour: 14 time1 minute: 20 time1 second: 35 time1 nano: 276000000 time2: 08:08:08 time3: 08:15:08 time4: 12:30:10
-
LocalDateTime
public class LocalDateTimeTest { public static void main(String[] args) { // 获取当前日期时间 LocalDateTime dateTime1 = LocalDateTime.now(); System.out.println("dateTime1: " + dateTime1); // 创建LocalDateTime实例 LocalDateTime dateTime2 = LocalDateTime.of(2021, 4, 20, 14, 23, 1); System.out.println("dateTime2: " + dateTime2); // 解析日期时间对象 LocalDateTime dateTime3 = LocalDateTime.parse("2021-04-20 14:30:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); System.out.println("dateTime3: " + dateTime3); // 修改LocalDateTime实例, 返回一个新的实例 LocalDateTime dateTime4 = dateTime3.withMonth(5); System.out.println("dateTime4: " + dateTime4.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); } }
// 运行结果 dateTime1: 2021-04-20T14:33:10.264 dateTime2: 2021-04-20T14:23:01 dateTime3: 2021-04-20T14:30 dateTime4: 2021-05-20 14:30:00
-
ZonedDateTime
public class LocalDateTimeTest { public static void main(String[] args) { // 获取当前日期时间+时区 ZonedDateTime dateTime1 = ZonedDateTime.now(); System.out.println("dateTime1: " + dateTime1); // 创建ZonedDateTime实例 LocalDate date = LocalDate.of(2021, 4, 20); LocalTime time = LocalTime.of(14, 30, 30); ZonedDateTime dateTime2 = ZonedDateTime.of(LocalDateTime.of(date, time), ZoneId.of("Asia/Shanghai")); System.out.println("dateTime2: " + dateTime2); } }
// 运行结果 dateTime1: 2021-04-20T14:37:47.019+08:00[Asia/Shanghai] dateTime2: 2021-04-20T14:30:30+08:00[Asia/Shanghai]
-
Instant
public class LocalDateTimeTest { public static void main(String[] args) { // 获取格林威治时间 Instant instant1 = Instant.now(); System.out.println("instant1: " + instant1); // Date转Instant Instant instant2 = new Date().toInstant(); System.out.println("instant2: " + instant2); // Instant转ZonedDateTime ZonedDateTime dateTime1 = ZonedDateTime.ofInstant(instant2, ZoneId.of("Asia/Shanghai")); System.out.println("dateTime1: " + dateTime1); // Instant转LocalDateTime LocalDateTime dateTime2 = LocalDateTime.ofInstant(instant2, ZoneId.of("Asia/Shanghai")); System.out.println("dateTime2: " + dateTime2); } }
// 运行结果 instant1: 2021-04-20T06:49:52.519Z instant2: 2021-04-20T06:49:52.577Z dateTime1: 2021-04-20T14:49:52.577+08:00[Asia/Shanghai] dateTime2: 2021-04-20T14:49:52.577
4. 类型转换表
类 | To遗留类 | From遗留类 |
---|---|---|
java.time.Instant java.util.Date | Date.from(instant) | date.toInstant() |
java.time.Instant java.sql.Timestamp | Timestamp.from(instant) | timestamp.toInstant() |
java.time.LocalDate java.sql.Date | Date.valueOf(localDate) | Date.toLocalDate() |
java.time.LocalTime java.sql.Time | Time.valueOf(localTime) | Time.toLocalTime() |
java.time.LocalDateTime java.sql.Timestamp | Timestamp.valueOf(localDateTime) | Timestamp.toLocalDateTime() |