前言
在Java开发过程中,处理日期和时间是常见的需求。随着Java 8引入了全新的日期/时间API,原有的java.util.Date
类逐渐被java.time
包中的LocalDate
和LocalDateTime
等类所替代。本文将详细阐述这三个类之间的主要区别以及它们之间的相互转换。
1. 类型介绍与特点
-
java.util.Date
Date
类是Java早期版本提供的用于表示特定的瞬间,精确到毫秒级别的日期和时间对象。它包含了一个从格林尼治标准时间1970年1月1日0点0分0秒(即Unix纪元)开始计算的毫秒数。这个类的设计存在一些问题,如非线程安全、可变性以及时区处理不便等。 -
java.time.LocalDate
LocalDate
是Java 8新增的时间API类,仅表示日期部分,不包括时间信息,也不包含任何时区信息。它是不可变的,提供对年、月、日的精确操作,并且支持各种日期计算方法。 -
java.time.LocalDateTime
LocalDateTime
同样来自Java 8的新时间API,它不仅包含日期信息,还包含了时间信息,但同样不带有时区。它也是不可变的,提供了丰富的日期和时间的操作功能,比如获取当前日期时间、增加或减少日期时间单位等。
2. 主要区别
-
精度与范围
Date
:存储的是自Unix纪元以来的毫秒数,因此它的精度是到毫秒级别。LocalDate
:只表示日期,没有时间信息,精度到天。LocalDateTime
:同时表示日期和时间,精度同样是到纳秒级别。
-
时区
Date
:虽然实际存储的是UTC时间戳,但是由于其设计原因,在显示和解析时可能会受到默认时区的影响。LocalDate
和LocalDateTime
:都不包含时区信息,代表的是本地日期和时间。
-
可变性
Date
:是可变的,可以通过方法修改其内部值。LocalDate
和LocalDateTime
:都是不可变的,每次更改都会返回一个新的实例。
-
易用性与安全性
Date
:使用起来较为繁琐,且容易出现并发问题,因为很多操作不是线程安全的。LocalDate
和LocalDateTime
:具有更好的API设计,易于理解和使用,同时由于不可变性,更有利于编写线程安全的代码。
3. 相互转换
Date转LocalDate或LocalDateTime
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;// Date -> LocalDate
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();// Date -> LocalDateTime
LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
LocalDate或LocalDateTime转Date
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;// LocalDate -> Date
LocalDate localDate = ...;
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());// LocalDateTime -> Date
LocalDateTime localDateTime = ...;
Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
总结
java.util.Date
在Java 8以后已经不再是推荐使用的日期时间类,而LocalDate
和LocalDateTime
分别对应日期和日期时间的精确表达,具有更好的设计和更多的功能。在处理日期时间相关的业务逻辑时,应优先考虑使用新的java.time
包下的类。