TL; DR版本:请确认(或者如果没有,请提供帮助),我正确地将SQL Server datetimeoffset
数据正确加载到我的Joda Time Java对象中。将SQL Server日期数据导入Joda对象的最佳方法是什么?
我正在计划中,将我们的数据库和Java代码移到时区感知的位置。为了做到这一点,我一直都在this post,并试图实施最佳做法。请注意,所有代码都被认为是“丢弃”代码,所以我并不在乎效率。只是正确。
我们的环境由Microsoft SQL Server 2008数据库和Java服务层组成,我们通过存储过程和Spring访问所有数据。
提到的最佳实践之一是使用乔达时间库。由于这对我来说是新的,所以我想确保我正确地做到这一点(并且因此不会丢失任何信息)。
在SQL Server里面,我创建了一个测试表所有的不同的SQL Server获取时间型功能:
CREATE TABLE MIKE_TEMP (
ID INT NOT NULL IDENTITY,
BLAH NVARCHAR(255),
DT_GET_DATE DATETIME DEFAULT GETDATE() NOT NULL,
DT_GET_UTC_DATE DATETIME DEFAULT GETUTCDATE() NOT NULL,
DT_SYS_DATE_TIME DATETIME DEFAULT sysdatetime() NOT NULL,
DT_SYS_UTC_DATE_TIME DATETIME DEFAULT sysutcdatetime() NOT NULL,
DT_SYS_DATE_TIME_OFFSET DATETIME DEFAULT sysdatetimeoffset() NOT NULL,
DTO_GET_DATE DATETIMEOFFSET DEFAULT GETDATE() NOT NULL,
DTO_GET_UTC_DATE DATETIMEOFFSET DEFAULT GETUTCDATE() NOT NULL,
DTO_SYS_DATE_TIME DATETIMEOFFSET DEFAULT sysdatetime() NOT NULL,
DTO_SYS_UTC_DATE_TIME DATETIMEOFFSET DEFAULT sysutcdatetime() NOT NULL,
DTO_SYS_DATE_TIME_OFFSET DATETIMEOFFSET DEFAULT sysdatetimeoffset() NOT NULL
);
到这个表,我加了一个价值,blah = 'Hello World!'
。将得到的数据是:
ID BLAH DT_GET_DATE DT_GET_UTC_DATE DT_SYS_DATE_TIME DT_SYS_UTC_DATE_TIME DT_SYS_DATE_TIME_OFFSET DTO_GET_DATE DTO_GET_UTC_DATE DTO_SYS_DATE_TIME DTO_SYS_UTC_DATE_TIME DTO_SYS_DATE_TIME_OFFSET
-- ------------ ------------------- ------------------- ------------------- -------------------- ----------------------- ---------------------------------- ---------------------------------- ---------------------------------- ---------------------------------- ----------------------------------
1 Hello World! 2012-02-15 08:58:41 2012-02-15 14:58:41 2012-02-15 08:58:41 2012-02-15 14:58:41 2012-02-15 08:58:41 2012-02-15 08:58:41.6000000 +00:00 2012-02-15 14:58:41.6000000 +00:00 2012-02-15 08:58:41.6005458 +00:00 2012-02-15 14:58:41.6005458 +00:00 2012-02-15 08:58:41.6005458 -06:00
有,简单地做了select * from MIKE_TEMP
并返回所有数据作为输出参数的对应的存储过程。
的Java代码(仅“有趣”进口的主要为清楚起见):
import org.joda.time.DateTime;
import java.util.Date;
@Component
public class MikeTempDaoImpl {
private static final Logger logger = LoggerFactory.getLogger(MikeTempDaoImpl.class);
private DataSource dataSource;
@Autowired
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public DataSource getDataSource() {
return dataSource;
}
public MikeVTemp getMikeTemp() {
SimpleJdbcCall data = new SimpleJdbcCall(getDataSource());
data.withProcedureName("get_MIKE_TEMP");
data.withoutProcedureColumnMetaDataAccess();
data.declareParameters(
new SqlOutParameter("ID", Types.INTEGER),
new SqlOutParameter("BLAH", Types.NVARCHAR),
new SqlOutParameter("DT_GET_DATE", Types.TIMESTAMP),
new SqlOutParameter("DT_GET_UTC_DATE", Types.TIMESTAMP),
new SqlOutParameter("DT_SYS_DATE_TIME", Types.TIMESTAMP),
new SqlOutParameter("DT_SYS_UTC_DATE_TIME", Types.TIMESTAMP),
new SqlOutParameter("DT_SYS_DATE_TIME_OFFSET", Types.TIMESTAMP),
new SqlOutParameter("DTO_GET_DATE", Types.TIMESTAMP),
new SqlOutParameter("DTO_GET_UTC_DATE", Types.TIMESTAMP),
new SqlOutParameter("DTO_SYS_DATE_TIME", Types.TIMESTAMP),
new SqlOutParameter("DTO_SYS_UTC_DATE_TIME", Types.TIMESTAMP),
new SqlOutParameter("DTO_SYS_DATE_TIME_OFFSET", Types.TIMESTAMP)
);
Map out;
try {
out = data.execute();
} catch (Exception ex) {
logger.error(ex.getMessage());
}
int id = (Integer) out.get("ID");
String blah = (String) out.get("BLAH");
DateTime dtGetDate = new DateTime((Date) out.get("DT_GET_DATE"));
DateTime dtGetUtcDate = new DateTime((Date) out.get("DT_GET_UTC_DATE"));
DateTime dtSysDateTime = new DateTime((Date) out.get("DT_SYS_DATE_TIME"));
DateTime dtSysUtcDateTime = new DateTime((Date) out.get("DT_SYS_UTC_DATE_TIME"));
DateTime dtSysDateTimeOffset = new DateTime((Date) out.get("DT_SYS_DATE_TIME_OFFSET"));
DateTime dtoGetDate = new DateTime((Date) out.get("DTO_GET_DATE"));
DateTime dtoGetUtcDate = new DateTime((Date) out.get("DTO_GET_UTC_DATE"));
DateTime dtoSysDateTime = new DateTime((Date) out.get("DTO_SYS_DATE_TIME"));
DateTime dtoSysUtcDateTime = new DateTime((Date) out.get("DTO_SYS_UTC_DATE_TIME"));
DateTime dtoSysDateTimeOffset = new DateTime((Date) out.get("DTO_SYS_DATE_TIME_OFFSET"));
MikeTemp mt = new MikeTemp.Builder()
.id(id)
.blah(blah)
.dtGetDate(dtGetDate)
.dtGetUtcDate(dtGetUtcDate)
.dtSysDateTime(dtSysDateTime)
.dtSysUtcDateTime(dtSysUtcDateTime)
.dtSysDateTimeOffset(dtSysDateTimeOffset)
.dtoGetDate(dtoGetDate)
.dtoGetUtcDate(dtoGetUtcDate)
.dtoSysDateTime(dtoSysDateTime)
.dtoSysUtcDateTime(dtoSysUtcDateTime)
.dtoSysDateTimeOffset(dtoSysDateTimeOffset)
.build();
System.out.println("id = [" + mt.getId() + "]");
System.out.println("blah = [" + mt.getBlah() + "]");
System.out.println("dtGetDate = [" + mt.getDtGetDate() + "]");
System.out.println("dtGetUtcDate = [" + mt.getDtGetUtcDate() + "]");
System.out.println("dtSysDateTime = [" + mt.getDtSysDateTime() + "]");
System.out.println("dtSysUtcDateTime = [" + mt.getDtSysUtcDateTime() + "]");
System.out.println("dtSysDateTimeOffset = [" + mt.getDtSysDateTimeOffset() + "]");
System.out.println("dtoGetDate = [" + mt.getDtoGetDate() + "]");
System.out.println("dtoGetUtcDate = [" + mt.getDtoGetUtcDate() + "]");
System.out.println("dtoSysDateTime = [" + mt.getDtoSysDateTime() + "]");
System.out.println("dtoSysUtcDateTime = [" + mt.getDtoSysUtcDateTime() + "]");
System.out.println("dtoSysDateTimeOffset = [" + mt.getDtoSysDateTimeOffset() + "]");
return mvt;
}
}
这是由一个JUnit测试行使:
@Test
public void testDateData() throws Exception {
MikeTemp mt = dao.getMikeTemp();
assertNotNull("MT should not be null, but it is.", mt);
assertEquals(1, mt.getId());
assertEquals("Hello World!", mt.getBlah());
}
而且从结果所有的println的是:
id = [1]
blah = [Hello World!]
dtGetDate = [2012-02-15T08:58:41.577-06:00]
dtGetUtcDate = [2012-02-15T14:58:41.577-06:00]
dtSysDateTime = [2012-02-15T08:58:41.580-06:00]
dtSysUtcDateTime = [2012-02-15T14:58:41.600-06:00]
dtSysDateTimeOffset = [2012-02-15T08:58:41.600-06:00]
dtoGetDate = [2012-02-15T08:58:41.600-06:00]
dtoGetUtcDate = [2012-02-15T14:58:41.600-06:00]
dtoSysDateTime = [2012-02-15T08:58:41.600-06:00]
dtoSysUtcDateTime = [2012-02-15T14:58:41.600-06:00]
dtoSysDateTimeOffset = [2012-02-15T08:58:41.600-06:00]
作为此服务器是在美国中部时区,我defi翘首以盼-06:00为部分的结果,但绝对不是全部是。我错过了沿途的某个地方吗?打电话给乔达DateTime(Object)
ctor与java.util.Date
对象在这种情况下做正确的事情?我还能做什么?我不是?
谢谢!
你的关键的问题是,'java.util.Date'不存储自定义时区信息。它始终是UTC。为了给出一个合适的答案,这段代码从原始JDBC中抽象得太多了,但是您可能需要使用'ResultSet#getTimestamp()'方法来传递包含时区的'java.util.Calendar'。 – BalusC 2012-02-20 03:02:44