yan*_*kee 16 java postgresql datetime jdbc
我在PostgreSQL中创建了一个这样的表:
create table myTable (
dateAdded timestamp(0) without time zone null default (current_timestamp at time zone 'UTC');
)
Run Code Online (Sandbox Code Playgroud)
我选择"没有时区",因为我知道我的应用程序使用的所有时间戳都是 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);
}
}
Run Code Online (Sandbox Code Playgroud)
从JDBC + PostgreSQL时间戳源获取UTC时间戳的正确方法是什么?
Pav*_*ral 20
将UTC设置为JVM的默认时区-Duser.timezone=UTC或将整个操作系统设置为UTC.
在Postgres的两个TIMESTAMP和TIMESTAMP WITH TIMEZONE因为Postgres历元(2000-01-01)的秒数-被存储的方式相同.主要区别在于Postgres在保存时间戳值时所做的事情,例如2004-10-19 10:23:54+02:
+02就被剥夺了-02校正以使其成为UTC现在有趣的是JDBC驱动程序加载值时:
在这两种情况下,您最终都会得到java.sql.Timestamp具有用户默认TZ的对象.
没有TZ的时间戳非常有限.如果有两个系统连接到数据库,两个系统都有不同的TZ,它们将以不同的方式解释时间戳.因此,我强烈建议你使用TIMESTAMP WITH TIMEZONE.
您可以告诉JDBC在读取时间戳时应该使用哪种TZ ResultSet#getTimestamp(String, Calendar).摘自JavaDoc:
如果基础数据库不存储时区信息,则此方法使用给定日历为时间戳构造适当的毫秒值.
| 归档时间: |
|
| 查看次数: |
9398 次 |
| 最近记录: |