1. java.util.Date
(已过时,不推荐新代码使用)
特点
-
表示时间戳:存储自 1970-01-01 00:00:00 UTC(Unix 纪元) 以来的毫秒数。
-
问题:
-
不区分日期和时间,也没有时区支持(依赖系统默认时区)。
-
可变性(非线程安全)。
-
API 设计差(大部分方法已废弃,如
getYear()
返回的是year - 1900
)。
-
示例
Date date = new Date(); // 当前时间(包含毫秒)
System.out.println(date); // 输出:Thu Jun 06 18:30:45 CST 2024
2. java.time.LocalDateTime
(Java 8+ 推荐)
特点
-
不可变且线程安全,属于现代日期时间 API(
java.time
包)。 -
无时区信息,仅表示本地日期时间(如
2024-06-06T18:30:45
)。 -
支持精确到纳秒,并提供丰富的操作方法(如
plusDays()
、isBefore()
)。
示例
LocalDateTime now = LocalDateTime.now(); // 当前本地时间
System.out.println(now); // 输出:2024-06-06T18:30:45.123456789
3. javax.xml.datatype.XMLGregorianCalendar
(XML 交互专用)
特点
-
专为 XML 序列化设计(如 SOAP/WSDL、XSD 的
xs:dateTime
类型)。 -
可表示时区(比
LocalDateTime
更灵活)。 -
底层依赖
GregorianCalendar
,支持任意精度(年、月、日、时、分、秒、毫秒等)。
示例
XMLGregorianCalendar xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendar("2024-06-06T18:30:45+08:00");
System.out.println(xmlDate); // 输出:2024-06-06T18:30:45+08:00
4. String
(纯文本表示)
特点
-
无内置日期时间逻辑,仅作为格式化后的文本(如
"2024-06-06 18:30:45"
)。 -
需手动解析/格式化(易出错,推荐用
DateTimeFormatter
处理)。
示例
String dateStr = "2024-06-06T18:30:45";
LocalDateTime parsedDate = LocalDateTime.parse(dateStr, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
对比总结
特性 | Date | LocalDateTime | XMLGregorianCalendar | String |
---|---|---|---|---|
设计目的 | 旧版时间戳 | 本地日期时间(无时区) | XML/WSDL 交互 | 纯文本 |
时区支持 | 依赖系统默认 | 无 | 支持 | 无 |
可变性 | 可变(非线程安全) | 不可变(线程安全) | 不可变 | 不可变 |
精度 | 毫秒 | 纳秒 | 任意精度 | 依赖格式 |
推荐使用场景 | 遗留代码 | 现代 Java 应用 | XML/WebService | 显示或简单存储 |
如何选择?
-
新代码优先用
LocalDateTime
(Java 8+ 标准,清晰易用)。 -
XML/SOAP 交互用
XMLGregorianCalendar
(与 XSDxs:dateTime
兼容)。 -
避免直接使用
Date
(除非维护旧系统)。 -
String
仅用于显示或简单存储,解析时需配合DateTimeFormatter
。
转换示例
LocalDateTime
↔ XMLGregorianCalendar
// LocalDateTime → XMLGregorianCalendar
LocalDateTime ldt = LocalDateTime.now();
XMLGregorianCalendar xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(ldt.toString());// XMLGregorianCalendar → LocalDateTime
LocalDateTime fromXml = xmlDate.toGregorianCalendar().toZonedDateTime().toLocalDateTime();
Date
↔ LocalDateTime
// Date → LocalDateTime
Date date = new Date();
LocalDateTime ldt = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();// LocalDateTime → Date
Date fromLdt = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());