答案 1
当 Hibernate 将 Java 日历对象写入 SQL TIMESTAMP 列时,它会将日期、计算机的日期或日历对象(或其他某个)中指定的日期调整到哪个时区?
Hiberante 3.x 在 中使用以下(参见 HB-1006):CalendarType
public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
final Calendar cal = (Calendar) value;
//st.setTimestamp( index, new Timestamp( cal.getTimeInMillis() ), cal ); //JDK 1.5 only
st.setTimestamp( index, new Timestamp( cal.getTime().getTime() ), cal );
}
因此,Hibernate使用ReadyStatement#setTimestamp(int,Timestamp,Calendar
),它使用日历的时区。
当 Hibernate 将 TIMESTAMP 读取到日历对象中时,它会将日期转换为哪个时区?
好吧,再一次,让我们看看这个类:CalendarType
public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
Timestamp ts = rs.getTimestamp(name);
if (ts!=null) {
Calendar cal = new GregorianCalendar();
if ( Environment.jvmHasTimestampBug() ) {
cal.setTime( new Date( ts.getTime() + ts.getNanos() / 1000000 ) );
}
else {
cal.setTime(ts);
}
return cal;
}
else {
return null;
}
}
因此,Hibernate 使用默认时区中的当前时间与默认区域设置来构造默认的公历
日历。
作为旁注,我强烈建议阅读以下问题:
答案 2
我刚刚花了6个小时来处理类似的问题,并认为我会在这里记录下来。Hibernate确实使用JVM时区,但可以通过扩展CalendarType来更改它,如下所示:
public class UTCCalendarType extends CalendarType {
private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
/**
* This is the original code from the class, with two changes. First we pull
* it out of the result set with an example Calendar. Second, we set the new
* calendar up in UTC.
*/
@Override
public Object get(ResultSet rs, String name) throws SQLException {
Timestamp ts = rs.getTimestamp(name, new GregorianCalendar(UTC));
if (ts != null) {
Calendar cal = new GregorianCalendar(UTC);
cal.setTime(ts);
return cal;
} else {
return null;
}
}
@Override
public void set(PreparedStatement st, Object value, int index) throws SQLException {
final Calendar cal = (Calendar) value;
cal.setTimeZone(UTC);
st.setTimestamp(index, new Timestamp(cal.getTime().getTime()), cal);
}
}
这里的秘诀是:
rs.getTimestamp(name, new GregorianCalendar(UTC));
这会将时区从结果集转换为所需的任何时区。因此,我所做的是将此类型用于任何UTC日历和本地时间的标准Hibernate类型。像哨子一样光滑...
推荐
-
-
如何从时间戳中删除毫秒? 我被问到这个问题: 给定一个时间戳作为长整型值,在 Java 中编写一个实用程序函数来删除毫秒。例如,给定1274883865399输入(实际时间:20100526T14:24:25.399Z),该函数将返回1274883865000(实际
-
Jackson 使用时间戳字段反序列化 JSON 我有这样的字符串: 我不明白为什么...如果我在调试模式下使用Timestamp.valueOf()与“2017-04-12 17:04:42.896026” - 我有成功
-
-
Hibernate 在读取 Java 日历对象并将其写入 SQL 时间戳时使用哪个时区? 当 列时,它会将日期、计算机的日期或日历对象(或其他某个)中指定的日期调整到哪个时区? 当 Hibernate 将 读入日历对象时,它会将日期转换为哪个时区?
标签
推荐