java.util.Date和java.time.LocalDate對(duì)比及分析
前言
本文記錄 jdk 中日期 java.util.Date 和 java.time 下的日期 兩者的區(qū)別和使用 。
一、 java.util 和 java.time 下日期的區(qū)別
1.1 java.util.date
Date 內(nèi)部只存一個(gè)毫秒數(shù),全球只有一個(gè)值,但不同時(shí)區(qū)顯示不同,它不存時(shí)區(qū),不存年、月、日、時(shí)、分、秒。在我們new Date () 后查看人日期,此時(shí)該日期會(huì)通過當(dāng)前時(shí)區(qū)(jvm 時(shí)區(qū)) 顯示日期:
long timestamp; // 從 1970-01-01 00:00:00 UTC 開始的毫秒
當(dāng)你打印 new Date() 時(shí),Java 會(huì)自動(dòng)用你當(dāng)前系統(tǒng)的時(shí)區(qū)把時(shí)間戳轉(zhuǎn)成日期時(shí)間顯示
比如同一個(gè)時(shí)間戳:
在中國(guó)時(shí)區(qū) → 顯示 2025-12-25 20:00:00 在紐約時(shí)區(qū) → 顯示 2025-12-25 07:00:00
java.util.Date 本身不存時(shí)區(qū),但它依賴系統(tǒng)時(shí)區(qū) ** 顯示,所以你會(huì)感覺它 “帶時(shí)區(qū)”。
1.2 java.time.LocalDate
java.time.LocalDate 真的完全不帶時(shí)區(qū) **,它就是一個(gè)純?nèi)諝v日期,跟你掛墻上的日歷一模一樣。
LocalDate 存的是:
int year, month, day;
它就是一個(gè)純?nèi)掌冢?025-12-25
它不關(guān)心你在哪個(gè)國(guó)家、哪個(gè)時(shí)區(qū)。
北京是 2025-12-25 紐約也是 2025-12-25 倫敦也是 2025-12-25
LocalDate 不跟時(shí)間戳綁定,不跟任何時(shí)區(qū)綁定。
1.3 兩者的對(duì)比
| 對(duì)比項(xiàng) | java.util.Date | java.time.LocalDate |
|---|---|---|
| 版本 | JDK 1.0 | JDK 8+ |
| 是否線程安全 | ? 非線程安全(可變類) | ? 線程安全(不可變類) |
| 存儲(chǔ)內(nèi)容 | 時(shí)間戳(毫秒) | 包含日期 + 時(shí)間 + 時(shí)區(qū) 僅純?nèi)掌冢?- 月 - 日),無時(shí)間、無時(shí)區(qū) |
| 易用性 | ? 難用(方法命名混亂、很多方法廢棄) | ? 極簡(jiǎn)(方法語義化,如 plusDays()) |
| 時(shí)區(qū)處理 | 隱含時(shí)區(qū),易出 bug | 無時(shí)區(qū),需要時(shí)區(qū)用 ZonedDateTime |
| 常用場(chǎng)景 | 遺留系統(tǒng)、舊代碼 | 新項(xiàng)目、日常開發(fā)首選 |
二、兩者的使用
2.1 java.util.date
Date:表示一個(gè)瞬時(shí)時(shí)間點(diǎn),包含 日期 + 時(shí)間(時(shí):分: 秒:毫秒),底層是 long 類型時(shí)間戳
Date date = new Date(); System.out.println(date); // 輸出:Wed May 21 15:30:20 CST 2025
此時(shí)new Date() 存入 MySQL datetime 字段,最終存進(jìn)去的是:你 Java 程序所在服務(wù)器的【當(dāng)前系統(tǒng)時(shí)間(年月日 時(shí)分秒)】
2.2 java.time.LocalDate
LocalDate:僅表示純?nèi)掌?,沒有時(shí)間、沒有時(shí)區(qū),比如 2025-05-21。
LocalDate localDate = LocalDate.now();
System.out.println(localDate); // 輸出:2025-05-21
LocalDate l1 = LocalDate.now();
// 按照時(shí)區(qū)定義日期
LocalDate l2 = LocalDate.now(ZoneId.of("US/Eastern"));
LocalDateTime l3 = LocalDateTime.now();
// 按照時(shí)區(qū)定義日期
LocalDateTime l4 = LocalDateTime.now(ZoneId.of("US/Eastern"));
LocalDate/LocalDateTime 存入 MySQL datetime 字段:存的就是你代碼里寫的【字面時(shí)間】,不做任何時(shí)區(qū)轉(zhuǎn)換!你給它什么時(shí)間,它就原封不動(dòng)存進(jìn)數(shù)據(jù)庫。
2.3 java.time 日期
LocalDate:只存 日期(年 - 月 - 日)LocalTime:只存 時(shí)間(時(shí):分: 秒)LocalDateTime:存 日期 + 時(shí)間(無時(shí)區(qū))Instant:存 時(shí)間戳(全球統(tǒng)一、帶時(shí)區(qū)概念)
| 類名 | 包含內(nèi)容 | 時(shí)區(qū) | 本質(zhì) |
|---|---|---|---|
| LocalDate | 年月日 | 無時(shí)區(qū) | 日歷日期 |
| LocalTime | 時(shí)分秒 | 無時(shí)區(qū) | 鐘表時(shí)間 |
| LocalDateTime | 年月日 + 時(shí)分秒 | ? 無時(shí)區(qū) | 本地日期時(shí)間 |
| 時(shí)間戳 | UTC | 時(shí)區(qū) | 全球統(tǒng)一時(shí)間點(diǎn) |
2.4 相互轉(zhuǎn)換
Date 轉(zhuǎn)LocalDate
public static LocalDate dateToLocalDate(Date date) {
return date.toInstant()
// .atZone(ZoneId.systemDefault())
.atZone(ZoneId.of("US/Eastern"))
.toLocalDate();
}
public static LocalDateTime dateToLocalDateTime(Date date) {
return date.toInstant()
// .atZone(ZoneId.systemDefault())
.atZone(ZoneId.of("US/Eastern"))
.toLocalDateTime();
}
LocalDate 轉(zhuǎn) Date
// 給 LocalDateTime 綁定時(shí)區(qū)(必須!否則不知道是哪個(gè)時(shí)區(qū)的時(shí)間)
public static Date localDateToDate(LocalDate localDate) {
return Date.from(
localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()
);
}
public static Date localDateTimeToDate(LocalDateTime localDateTime) {
return Date.from(
localDateTime.atZone(ZoneId.systemDefault()).toInstant()
);
}
2.5 格式化輸出
// 日期格式
public static final String DATE_PATTERN = "yyyy-MM-dd";
// 日期時(shí)間格式
public static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
/**
* LocalDate -> yyyy-MM-dd
*/
public static String formatDate(LocalDate date) {
if (date == null) {
return null;
}
return date.format(DateTimeFormatter.ofPattern(DATE_PATTERN));
}
/**
* LocalDateTime -> yyyy-MM-dd HH:mm:ss
*/
public static String formatDateTime(LocalDateTime dateTime) {
if (dateTime == null) {
return null;
}
return dateTime.format(DateTimeFormatter.ofPattern(DATETIME_PATTERN));
}
總結(jié)
本文介紹java.util.Date和java.time.LocalDate 的區(qū)別和使用。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
總結(jié)Java常用到的六個(gè)加密技術(shù)和代碼
大家要記住現(xiàn)代密碼學(xué)最重要的原則柯克霍夫原則:數(shù)據(jù)的安全基于密鑰而不是算法的保密。也就是說即使密碼系統(tǒng)的任何細(xì)節(jié)已為人悉知,只要密匙未洩漏,它也應(yīng)是安全的。這篇文章給大家介紹了6個(gè)常用的加密技術(shù)和代碼。2016-07-07
SpringBoot使用maven指定依賴包的版本(解決示例)
我們?cè)谑褂肁依賴的時(shí)候,這個(gè)依賴有引入了第三方B依賴,這時(shí)候我想指定B依賴的版本號(hào),下面?zhèn)€大家分享解決示例,對(duì)SpringBoot maven依賴包相關(guān)配置方法感興趣的朋友一起看看吧2024-04-04
Spring boot通過切面,實(shí)現(xiàn)超靈活的注解式數(shù)據(jù)校驗(yàn)過程
這篇文章主要介紹了Spring boot通過切面,實(shí)現(xiàn)超靈活的注解式數(shù)據(jù)校驗(yàn)過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
Springboot+Stomp協(xié)議實(shí)現(xiàn)聊天功能
本示例實(shí)現(xiàn)一個(gè)功能,前端通過websocket發(fā)送消息給后端服務(wù),后端服務(wù)接收到該消息時(shí),原樣將消息返回給前端,前端技術(shù)棧html+stomp.js,后端SpringBoot,需要的朋友可以參考下2024-02-02
Java的Tomcat和Servlet的運(yùn)行原理詳解
這篇文章主要為大家詳細(xì)介紹了Java的Tomcat和Servlet,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03

