1. 引言
本文将探讨如何将 java.sql.Timestamp
对象转换为 java.util.Calendar
对象。我们将先分析这两个类在时间处理上的差异,然后探讨转换的典型场景,最后提供具体实现方案。
2. Java 中的时间处理
Java 中时间通常以毫秒为单位表示(自 1970-01-01 00:00:00 GMT 起)。当需要更高精度时,会使用纳秒(十亿分之一秒)。
核心特性对比
✅ java.sql.Timestamp
- 继承自
java.util.Date
- 新增纳秒级精度(通过
nanos
字段) - 专为数据库时间戳设计
- 时间值 = 毫秒 + 纳秒
❌ java.util.Calendar
- 最高仅支持毫秒级精度
- 提供日期字段操作(年/月/日等)
- 适合日期计算和格式化
⚠️ 关键差异:Timestamp
的纳秒精度在转换到 Calendar
时会丢失,这是常见的踩坑点。
3. 时间对象转换
3.1. Timestamp 转 Calendar
当从数据库获取时间戳后,通常需要转换为 Calendar
进行日期字段操作:
Timestamp timestamp = new Timestamp(1713544200801L);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timestamp.getTime());
转换原理:通过 getTime()
获取毫秒值设置到 Calendar
。验证转换是否正确:
assertEquals(calendar.getTimeInMillis(), timestamp.getTime());
3.2. Calendar 转 Timestamp
反向转换时需注意精度丢失问题:
public static Timestamp calendarToTimestamp(Calendar calendar) {
return new Timestamp(calendar.getTimeInMillis());
}
精度丢失演示:
int nanos = 801789562;
int losslessNanos = 801000000; // 转换后实际保留值
Timestamp timestamp = new Timestamp(1713544200801L);
timestamp.setNanos(nanos);
assertEquals(nanos, timestamp.getNanos());
Calendar calendar = SqlTimestampToCalendarConverter.timestampToCalendar(timestamp);
timestamp = SqlTimestampToCalendarConverter.calendarToTimestamp(calendar);
assertEquals(losslessNanos, timestamp.getNanos()); // 断言通过
丢失原因:Timestamp
的 getTime()
方法内部将纳秒值除以 1,000,000 取整(801789562 → 801 毫秒)。
4. 总结
- ✅
Timestamp
和Calendar
都基于毫秒时间戳 - ✅
Timestamp
独有的纳秒精度适合高精度场景 - ❌ 转换到
Calendar
会丢失纳秒精度 - ✅ 当需要操作日期字段(年/月/日)时,转换到
Calendar
是合理选择
如果应用需要纳秒级精度,建议使用 Java 8+ 的
java.time
API(如Instant
和ZonedDateTime
),可避免精度丢失问题。
完整示例代码请查阅 GitHub 仓库。