如何设置HSQLDB的时区



如何在HSQL数据库中设置时区为UTC ?

根据这里的文档,应该只写:

SET TIME ZONE INTERVAL '+00:00' HOUR TO MINUTE;

但这对我不起作用。

我使用HSQLDB (v2.2.8)作为内存数据库,hibernate (v4.2.2)用于单元测试,JodaTime (v2.3)用于时间相关数据。一些数据通过hibernate.hbm2ddl.import_files用sql脚本插入。这些脚本使用now()函数创建时间戳。

然而,当我从数据库中检索插入的值并将其转换为UTC时,我得到以下结果:

没有像上面那样的sql命令:
2014-06-04T16:44:45.193Z
这是我当前的本地时间,但在UTC。

使用上面的SQL-Command:(注意1小时的差异)
2014-06-04T15:50:56.688Z
如果我们这里没有夏令时,这将是本地时间。

有趣的是:不管我在上面的命令中提供的偏移量是多少,输出总是相同的。

编辑:

插入脚本的示例行:

INSERT INTO public.users (created_at, modified_at, email, firstname, lastname, password, state, image_id) VALUES (now(), now(), 'max.mustermann@example.com', 'Max', 'Mustermann', 'password_hash', 'ACTIVE', NULL);

我的用户实体继承自以下实体:

@MappedSuperclass
public abstract class AbstractTrackedEntity extends AbstractEntity {
@Column(name = "created_at")
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
DateTime createdAt;
@Column(name = "modified_at")
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
DateTime modifiedAt;
public DateTime getCreatedAt() {
    return createdAt.withZone(DateTimeZone.UTC);
}
public void setCreatedAt(DateTime createdAt) {
    this.createdAt = createdAt.withZone(DateTimeZone.UTC);
}
public DateTime getModifiedAt() {
    return modifiedAt.withZone(DateTimeZone.UTC);
}
public void setModifiedAt(DateTime modifiedAt) {
    this.modifiedAt = modifiedAt.withZone(DateTimeZone.UTC);
}
@PrePersist
protected void onCreate() {
    modifiedAt = createdAt = DateTime.now(DateTimeZone.UTC);
}
@PreUpdate
protected void onUpdate() {
    modifiedAt = DateTime.now(DateTimeZone.UTC);
}
@Override
public String toString() {
    return "AbstractTrackedEntity{" +
            "createdAt=" + createdAt +
            ", modifiedAt=" + modifiedAt +
            '}';
}
}

请注意,在我的特殊问题中,只有getter是相关的,因为数据不是手工插入的(例如创建实体并使用hibernate持久化),而是使用上面提到的sql脚本。

总结问题:
数据库不存储具有实际时间戳值的时区信息。因此,如果now()返回localtime, localtime将被插入到数据库中。

因为我们的生产数据库使用UTC时区运行,所以代码被编写为将数据库中的每个时间戳视为UTC。(因此那些withZone(DateTimeZone.UTC)无处不在)。
在我的单元测试中,我需要比较代码中生成的utc时间戳和数据库中的时间戳。这些单元测试会中断atm,因为数据库中的时间戳(被视为UTC)与代码生成的时间戳相差2小时,尽管它们生成的时间间隔只有几秒钟。

阅读这些文档,也许CURRENT_TIMESTAMP会比NOW更好。我目前没有能力测试这个,但你可以试一试。

由于它返回TIMESTAMP WITH TIME ZONE,那么您还可以考虑:

CURRENT_TIMESTAMP AT TIME ZONE INTERVAL '0:00'

最新更新