转换为 java.util.Date (旧 API)
java.util.Date 是 Java 最早的时间日期类,而 Calendar 是它的一个更完善的替代品,从 Calendar 转换为 Date 非常直接,因为 Calendar 内部就持有一个 Date 对象。

核心方法:
calendar.getTime()
这个方法会返回 Calendar 对象所表示时间点的 Date 对象。
代码示例
import java.util.Calendar;
import java.util.Date;
public class CalendarToDateExample {
public static void main(String[] args) {
// 1. 创建一个 Calendar 实例
Calendar calendar = Calendar.getInstance();
// 2. 设置一个特定的日期和时间 ( 2025年10月27日, 15:30:45)
// 注意:月份是从 0 开始的,9 代表十月
calendar.set(Calendar.YEAR, 2025);
calendar.set(Calendar.MONTH, Calendar.OCTOBER); // 或者 9
calendar.set(Calendar.DAY_OF_MONTH, 27);
calendar.set(Calendar.HOUR_OF_DAY, 15);
calendar.set(Calendar.MINUTE, 30);
calendar.set(Calendar.SECOND, 45);
// 3. 将 Calendar 转换为 Date
Date date = calendar.getTime();
// 4. 打印结果
System.out.println("原始 Calendar 对象: " + calendar.getTime());
System.out.println("转换后的 Date 对象: " + date);
// 验证:将 Date 转回 Calendar,看是否一致
Calendar newCalendar = Calendar.getInstance();
newCalendar.setTime(date);
System.out.println("从 Date 重建的 Calendar: " + newCalendar.getTime());
}
}
输出:
原始 Calendar 对象: Fri Oct 27 15:30:45 CST 2025
转换后的 Date 对象: Fri Oct 27 15:30:45 CST 2025
从 Date 重建的 Calendar: Fri Oct 27 15:30:45 CST 2025
转换为 java.time.LocalDate (新 API - 推荐)
自 Java 8 引入 java.time 包后,强烈建议使用它来处理日期和时间。LocalDate 类表示一个不带时区的日期(年、月、日),比 Date 和 Calendar 更清晰、更不容易出错。

核心方法:
calendar.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()
这个转换过程分为三步:
calendar.toInstant(): 将Calendar对象转换为Instant。Instant是时间线上的一个瞬时点,这是连接旧 API 和新 API 的桥梁。.atZone(ZoneId.systemDefault()): 将Instant与一个时区结合,转换为ZonedDateTime,因为Instant本身不带时区信息,而Calendar是依赖于系统默认时区的,所以我们需要在这里指定时区,通常使用系统的默认时区ZoneId.systemDefault()。.toLocalDate(): 从ZonedDateTime中提取出LocalDate部分(年、月、日)。
代码示例
import java.time.*;
import java.util.Calendar;
public class CalendarToLocalDateExample {
public static void main(String[] args) {
// 1. 创建一个 Calendar 实例
Calendar calendar = Calendar.getInstance();
// 2. 设置一个特定的日期和时间 ( 2025年10月27日, 15:30:45)
calendar.set(Calendar.YEAR, 2025);
calendar.set(Calendar.MONTH, Calendar.OCTOBER);
calendar.set(Calendar.DAY_OF_MONTH, 27);
calendar.set(Calendar.HOUR_OF_DAY, 15);
calendar.set(Calendar.MINUTE, 30);
calendar.set(Calendar.SECOND, 45);
// 3. 将 Calendar 转换为 LocalDate
// 步骤 a: 转换为 Instant
Instant instant = calendar.toInstant();
// 步骤 b: 关联时区
ZoneId zoneId = ZoneId.systemDefault(); // 获取系统默认时区
// 步骤 c: 从 ZonedDateTime 中提取 LocalDate
LocalDate localDate = instant.atZone(zoneId).toLocalDate();
// 4. 打印结果
System.out.println("原始 Calendar 对象: " + calendar.getTime());
System.out.println("转换后的 LocalDate 对象: " + localDate);
// 验证:将 LocalDate 转回 Calendar
// 注意:这只是一个反向操作的示例,实际应用中通常不需要
ZonedDateTime zonedDateTime = localDate.atStartOfDay(zoneId);
Instant newInstant = zonedDateTime.toInstant();
Calendar newCalendar = Calendar.getInstance();
newCalendar.setTimeInMillis(newInstant.toEpochMilli());
System.out.println("从 LocalDate 重建的 Calendar (部分信息): " + newCalendar.getTime());
}
}
输出:
原始 Calendar 对象: Fri Oct 27 15:30:45 CST 2025
转换后的 LocalDate 对象: 2025-10-27
从 LocalDate 重建的 Calendar (部分信息): Fri Oct 27 08:00:00 CST 2025
注意:反向转换时,
LocalDate只包含日期,没有时间信息,所以重建的Calendar对象时间部分会是当天的 0 点,并且会根据时区进行调整(CST 时区比 UTC 晚,所以时间会显示为 08:00)。(图片来源网络,侵删)
总结与对比
| 特性 | Calendar -> Date |
Calendar -> LocalDate |
|---|---|---|
| API 版本 | 旧 API (JDK 1.1+) | 新 API (Java 8+) |
| 核心方法 | calendar.getTime() |
calendar.toInstant().atZone(zoneId).toLocalDate() |
| 易用性 | 非常简单,一行代码搞定。 | 稍复杂,需要理解 Instant, ZoneId, ZonedDateTime 的概念。 |
| 数据精度 | 包含日期和时间信息。 | 仅包含日期(年、月、日),时间部分被丢弃。 |
| 推荐度 | 不推荐,除非必须与遗留代码交互。 | 强烈推荐,是现代 Java 开发的标准。 |
完整示例代码
import java.time.*;
import java.util.Calendar;
import java.util.Date;
public class CalendarConversion {
public static void main(String[] args) {
// 准备一个 Calendar 实例
Calendar calendar = Calendar.getInstance();
calendar.set(2025, Calendar.OCTOBER, 27, 10, 0, 0); // 2025-10-27 10:00:00
System.out.println("原始 Calendar 对象: " + calendar.getTime());
System.out.println("------------------------------------");
// --- 转换为 java.util.Date ---
Date date = convertToDate(calendar);
System.out.println("转换为 java.util.Date: " + date);
// --- 转换为 java.time.LocalDate ---
LocalDate localDate = convertToLocalDate(calendar);
System.out.println("转换为 java.time.LocalDate: " + localDate);
}
/**
* 将 Calendar 转换为 java.util.Date
* @param calendar Calendar 对象
* @return Date 对象
*/
public static Date convertToDate(Calendar calendar) {
if (calendar == null) {
return null;
}
return calendar.getTime();
}
/**
* 将 Calendar 转换为 java.time.LocalDate
* @param calendar Calendar 对象
* @return LocalDate 对象
*/
public static LocalDate convertToLocalDate(Calendar calendar) {
if (calendar == null) {
return null;
}
Instant instant = calendar.toInstant();
ZoneId zoneId = ZoneId.systemDefault();
return instant.atZone(zoneId).toLocalDate();
}
}
最佳实践:
如果你的项目使用的是 Java 8 或更高版本,请优先使用 java.time API,虽然转换步骤多一点,但它提供了更强大、更安全、更直观的日期时间操作能力,是未来的趋势,只有在需要与旧系统(如 JDBC 的 java.sql.Date)或旧代码交互时,才考虑使用 java.util.Date。

