【发布时间】:2014-11-21 18:08:22
【问题描述】:
我在 PostgreSQL 中创建了一个像这样的表:
create table myTable (
dateAdded timestamp(0) without time zone null default (current_timestamp at time zone 'UTC');
)
我选择“无时区”,因为我知道我的应用程序使用的所有时间戳始终 UTC。就我获得的文档而言,与“带时间戳”的唯一区别是我可以提供其他时区的值,然后将其转换为 UTC。但是我想避免这种自动转换,因为如果我知道我的值是 UTC,它们几乎不会有任何好处。
当我在测试表中添加新记录并使用 pgAdmin 查看表的内容时,我可以看到插入日期已正确保存为 UTC 格式。
但是,当我尝试使用 JDBC 选择值时,该值会减去 2 小时。我位于 UTC+2,所以看起来 JDBC 假定表中的日期不是 UTC 时间戳,而是 UTC+2 时间戳,并尝试转换为 UTC。
一些谷歌搜索显示 JDBC 标准规定了与当前时区之间的转换,但这可以通过向 getTimestamp/setTimestamp 调用提供 Calander 来防止。然而,提供日历并没有任何区别。这是我的 MyBatis/Jodatime 转换器:
@MappedTypes(DateTime.class)
public class DateTimeTypeHandler extends BaseTypeHandler<DateTime> {
private static final Calendar UTC_CALENDAR = Calendar.getInstance(DateTimeZone.UTC.toTimeZone());
@Override
public void setNonNullParameter(PreparedStatement ps, int i,
DateTime parameter, JdbcType jdbcType) throws SQLException {
ps.setTimestamp(i, new Timestamp(parameter.getMillis()), UTC_CALENDAR);
}
@Override
public DateTime getNullableResult(ResultSet rs, String columnName)
throws SQLException {
return fromSQLTimestamp(rs.getTimestamp(columnName, UTC_CALENDAR));
}
/* further get methods with pretty much same content as above */
private static DateTime fromSQLTimestamp(final Timestamp ts) {
if (ts == null) {
return null;
}
return new DateTime(ts.getTime(), DateTimeZone.UTC);
}
}
从 JDBC+PostgreSQL 时间戳源获取 UTC 时间戳的正确方法是什么?
【问题讨论】:
-
你有没有考虑过使用新的java 8 time api?,以前的dateTime类也有这种问题。也许使用 java 8 中的 Instant 类而不是 DateTime。
标签: java postgresql datetime jdbc