我有一个使用MyBatis TypeHandler类的Java应用程序。它需要确保存储在MySql数据库中的日期是MST时间。
在任何数据到达应用程序之前,我们有另一个 TypeHandler,它从数据库获取日期,该日期在MST中,并将其转换为UTC。因此,例如,在数据库中,如果时间戳是:
2016-05-05 00:01:00
当日期出现在应用程序端时,它采用以下格式(UTC):
2016-05-05T07:01:00.000Z
应用程序端以UTC进行所有日期比较,但不幸的是,MySql服务器必须存储在MST中。
为了保持日期与应用程序运行的任何服务器(它在MST,PST以及EST中运行)保持一致,我们需要两个TypeHandler,一个用于编组进入应用程序的日期,另一个用于确保它在MST回去了。
UtcToMstDateTimeTypeHanlder的setParameter方法:
@Override
public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException
{
if (parameter != null)
{
//1. 2016-05-05 00:01:00 (timestamp) converted to UTC DateTime -> 2016-05-05T07:01:00.000Z
DateTime thisDateTime = (DateTime) parameter;
//2. UTC DateTime converted to LocalDateTime -> 2016-05-05T07:01:00.000
LocalDateTime thisLocalDateTime = thisDateTime.toLocalDateTime();
//3. LocalDateTime to MST DateTime -> 2016-05-05T07:01:00.000-07:00
DateTime mstTime = thisLocalDateTime.toDateTime(DateTimeZone.forID("MST"));
//4. But TimeStamp adds 3 hours... Why? 2016-05-05 10:01:00.0
Timestamp mstTimeStamp = new Timestamp((mstTime).getMillis());
ps.setTimestamp(i, mstTimeStamp);
}
else
{
ps.setTimestamp(i, null);
}
}
TimeStamp最终比UTC快3小时:
2016-05-05 10:01:00.0
不仅如此,它还比UTC更加相对于UTC,除了现在比UTC早10:01小时。
期望的效果是让TypeHandler将日期写回数据库,如下面的TimeStamp:
2016-05-05 00:01:00.0
我只想将提供给数据库的日期(上面的时间戳)与它出现的日期相同。
请注意,我现在正在美国东海岸(EST)运行。
答案 0 :(得分:0)
这就是我最终要做的事情。请注意下面我正在使用的日期的硬编码,从UTC到MST类型处理程序。基本思路是从时区获得偏移量。
来自DateTimeZone JodaTime类:
getOffset(长时间) 获取要添加到UTC以获取本地时间的毫秒偏移量。
DateTime thisDateTime = new DateTime("2016-05-07T07:01:00.000Z");
thisDateTime = thisDateTime.withZone(DateTimeZone.UTC);
thisDateTime = thisDateTime.toLocalDateTime().toDateTime();
DateTime mstTime = thisDateTime.withZone(DateTimeZone.forID("MST"));
int offset = mstTime.getZone().getOffset(new DateTime().getMillis());
Timestamp mstTimeStamp = new Timestamp(mstTime.getMillis() + offset); // -25200000 == 7 hours
ps.setTimestamp(i, mstTimeStamp); //2016-05-07 00:01:00
现在,无论运行应用程序代码的服务器在哪里,日期总是正确输入到数据库中,该数据库在MST时间内运行。