JodaTime 的 DateTime 构造函数现在可以为您处理这个问题。
(我不确定这个问题发布时是否属实,但这是 Google 的顶级搜索结果,所以我想我会添加一个更新的解决方案。)
有几个 API 选项:
public DateTime(Object instant);
public DateTime(Object instant, DateTimeZone zone);
两个选项都接受 java.sql.Timestamp,因为它扩展了 java.util.Date,但纳秒将被忽略(下限),因为 DateTime 和 Date 只有毫秒分辨率*。如果没有特定的时区,它将默认为 DateTimeZone.UTC。
“分辨率”是提供了多少位数。 “精度”是表示的准确程度。例如,MSSQL 的 DateTime 具有毫秒分辨率,但只有 ~1/3 秒精度(DateTime2 具有可变分辨率和更高的精度)。
教学模式>
具有毫秒分辨率的 UTC 时间戳示例:
new DateTime(resultSet.getTimestamp(1));
如果您在数据库中使用 TIMESTAMP WITH TIME ZONE,则不能使用 java.sql.Timestamp,因为它不支持时区。您必须使用 ResultSet#getString 并解析字符串。
不带时区的时间戳,第二分辨率示例**:
LocalDateTime dt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
.parseLocalDateTime(resultSet.getString(1));
具有第二分辨率示例的 UTC 时间戳**:
DateTime dt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
.parseDateTime(resultSet.getString(1));
带时区的时间戳(偏移格式)和第二分辨率示例**:
DateTime dt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss Z")
.parseDateTime(resultSet.getString(1));
奖励:DateTimeFormat#forPattern 按模式静态缓存解析器,因此您不必这样做。
我通常建议在您的 DBO 模型中使用字符串,以便明确解析并避免生成中间对象。 (2013-11-14 09:55:25 是否等于 2013-11-14 09:55:25.000?)我通常会尝试区分针对数据保存问题进行优化的“数据库模型对象”和针对数据保存问题进行优化的“业务模型对象”服务级别的使用,中间有一个转换/映射层。我发现让基于 CRUD 的 DAO 直接生成业务对象往往会混淆优先级并针对两者进行优化,由于错过了边缘情况而从意想不到的地方抛出异常。拥有显式转换层还允许您在必要时添加验证,例如如果您不控制数据源。分离关注点还可以更轻松地独立测试每一层。
教学模式>
* 如果您需要在业务模型中解析到纳秒级分辨率,则必须使用不同的库。
** 时间戳字符串格式可能因数据库而异,不确定。