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