XMLGregorianCalendar跟Date、localDateTime以及String有什么区别

发布于:2025-06-12 ⋅ 阅读:(19) ⋅ 点赞:(0)

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 显示或简单存储

如何选择?

  1. 新代码优先用 LocalDateTime(Java 8+ 标准,清晰易用)。

  2. XML/SOAP 交互用 XMLGregorianCalendar(与 XSD xs:dateTime 兼容)。

  3. 避免直接使用 Date(除非维护旧系统)。

  4. 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());