如何在java.sql.Timestamp中使用Joda-Time

Wol*_*gon 62 java postgresql timestamp jodatime

我有一份准备好的声明

INSERT INTO mst(time) VALUES (?);
Run Code Online (Sandbox Code Playgroud)

其中时间是类型的时间戳的PostgreSQL数据库.
我正在插入一个Joda-Time DateTime对象,或者我应该说我正在尝试.我找不到将DateTime对象转换为java.sql.Timestamp的方法.我已经阅读了Joda-Time文档并且没有参考这个.

谢谢.

Jac*_*eow 89

您可以先将Joda DateTime转换为long(自纪元以来的millis),然后再创建一个Timestamp.

DateTime dateTime = new DateTime();
Timestamp timeStamp = new Timestamp(dateTime.getMillis());
Run Code Online (Sandbox Code Playgroud)

  • 对于后代,如果你需要从时间戳转换为Joda DateTime,`new DateTime(timeStamp.getTime())`. (18认同)
  • TimeZone组件在哪里?您只是"复制"了日期和时间,但没有影响实际价值的时区...... (6认同)
  • 值得注意的是,joda-time不存储纳秒,而Timestamp存在.两者之间的任何转换都将失去纳秒精度. (6认同)
  • 你能详细说明你的意思吗?dateTime.getMillis()返回自纪元以来的毫秒数,它考虑了时区. (5认同)

Kar*_*KFI 10

JodaTime的DateTime构造函数现在可以为您处理.(我不确定问题发布后是否属实,但这是谷歌的最高结果,所以我想我会添加一个更新的解决方案.)

有几个API选项:

public DateTime(Object instant);
public DateTime(Object instant, DateTimeZone zone);
Run Code Online (Sandbox Code Playgroud)

这两个选项都接受java.sql.Timestamp,因为它扩展了java.util.Date,但是Nanoseconds将被忽略(floored),因为DateTime和Date只有毫秒级的分辨率*.如果没有特定的时区,它将默认为DateTimeZone.UTC.

<教学模式>
"分辨率"是提供多少位数."精确度"是表示的准确程度.例如,MSSQL的DateTime具有毫秒级的分辨率,但只有约1/3的精度(DateTime2具有可变分辨率和更高的精度).
</ Didactic Mode>

具有毫秒分辨率的UTC时间戳示例:

new DateTime(resultSet.getTimestamp(1));
Run Code Online (Sandbox Code Playgroud)

如果您在数据库中使用TIMESTAMP WITH TIME ZONE,则无法使用java.sql.Timestamp,因为它不支持时区.您必须使用ResultSet#getString并解析字符串.

没有时区的时间戳,带有第二个分辨率示例**:

LocalDateTime dt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
    .parseLocalDateTime(resultSet.getString(1));
Run Code Online (Sandbox Code Playgroud)

带有第二个分辨率示例的UTC时间戳示例**:

DateTime dt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")
    .parseDateTime(resultSet.getString(1));
Run Code Online (Sandbox Code Playgroud)

带时区的时间戳(偏移格式)和第二个分辨率示例**:

DateTime dt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss Z")
    .parseDateTime(resultSet.getString(1));
Run Code Online (Sandbox Code Playgroud)

Bonus:DateTimeFormat#forPattern按模式静态缓存解析器,因此您不必这样做.

<教学模式>
我通常建议在DBO模型中使用String,以使分辨率明确,避免生成中间对象.(2013-11-14 09:55:25是否等于2013-11-14 09:55:25.000?)我一般试图区分"数据库模型对象"优化数据保存问题和"业务模型对象"优化服务级别使用,其间包含转换/映射层.我发现直接生成业务对象的基于CRUD的DAO往往会混淆优先级并优化两者,因为错过边缘情况而从意外的位置抛出异常.拥有显式转换层还允许您在必要时添加验证,例如,如果您不控制数据源.分离问题还可以更容易地独立测试每个层.
</ Didactic Mode>

*如果您需要在商业模式中解析为纳秒分辨率,则必须使用不同的库.

**时间戳字符串格式可能因数据库而异,但不确定.

  • 我不明白你的陈述,`如果你在数据库中使用TIMESTAMP WITH TIME ZONE,那么就不能使用java.sql.Timestamp`.尽管它具有误导性的名称,但"TIMESTAMP WITH TIME ZONE"类型实际上并不存储任何时区信息.该类型在插入和检索日期时间值时考虑时区,但始终以UTC格式存储该值.因此,我们可以检索一个`TIMESTAMP WITH TIME ZONE`值作为JDBC类型`java.sql.Timestamp`对象,以提供给`org.joda.time.DateTime`实例的构造函数.我使用`now()`函数进行了测试. (2认同)