以UTC格式将日期保存到数据库

时间:2014-11-14 09:52:20

标签: java date grails jodatime

用户在我的网络应用中选择页面上的日期和时间(Grails,如果这很重要)。我知道用户的时区(他们在用户首选项中设置)。我现在想以UTC格式将该日期保存到数据库中(如果重要的话,使用Hibernate)。

所以,这是我的域类:

class Even {
    Date startTime
}

我有点想要这样做:

def beforeInsert() {
    startTime = new DateTime(startTime, user.timeZone).withZone(TimeDateZone.UTC).toDate()
}

但最后的toDate()只返回与我开始时相同的startTime(因为我认为Date没有时区信息)。

那么,我如何获得用户提供的Date(考虑他们的时区)并将其作为UTC保存到数据库?

我正在考虑做new Date() - user.timeZone.rawOffset这样的事情但是我必须节省日光时间,而且感觉非常容易出错。

1 个答案:

答案 0 :(得分:0)

可能有一个更快的解决方案,但这样做的标准方法是使用自定义Hibernate UserType。这是一个处理Hibernate 3.x部分的示例实现(接口在4.x中略有不同但代码几乎完全相同)并且保留了字符串的转换 - >日期和日期 - >字符串作为读者的练习:

package my.package

import java.sql.PreparedStatement
import java.sql.ResultSet
import java.sql.SQLException
import java.sql.Types

import org.hibernate.usertype.UserType

class UtcDateUserType implements UserType {

    def nullSafeGet(ResultSet rs, String[] names, owner) throws SQLException {
        String value = rs.getString(names[0])
        if (value) {
            return utcStringToDate(value)
        }
    }

    void nullSafeSet(PreparedStatement st, value, int index) throws SQLException {
        if (value) {
            st.setString index, dateToUtcString(value)
        }
        else {
            st.setNull index, Types.VARCHAR
        }
    }

    protected Date utcStringToDate(String s) {
        // TODO
    }

    protected String dateToUtcString(Date d) {
        // TODO
    }

    def assemble(Serializable cached, owner) { cached.toString() }
    def deepCopy(value) { value.toString() }
    Serializable disassemble(value) { value.toString() }
    boolean equals(x, y) { x == y }
    int hashCode(x) { x.hashCode() }
    boolean isMutable() { false }
    def replace(original, target, owner) { original }
    Class<String> returnedClass() { String }
    int[] sqlTypes() { [Types.VARCHAR] as int[] }
}

mapping块的域类中注册它,例如

import my.package.UtcDateUserType

....

static mapping = {
   startTime type: UtcDateUserType
}

这描述为in the docs here