巧用SQL Server日期類型數據二進制輸出計算時間差

1、SQL Server日期數據庫內部表示及查詢輸出:

 

SQL Server內部對DateTime類型的表示是用8個字節來表示,其中前4個字節表示的數值爲自1900年1月1日零時以來的天數,後四個字節是天數之外的有多少個1/300秒,這也說明SQL Server內部表示時間的精度爲1/300秒,約3.3毫秒。

 

常規的SQL查詢,正常日期輸出格式爲:yyyy-MM-dd hh:mm:ss.SSS,這也是中文操作系統的日期格式,可以通過修改操作系統日期表達格式來影響SQL Server缺省的日期輸出格式。但是,有些時候缺省的日期輸出格式並不是我們需要的,特別是基於時間差的應用需求。

 

2、應用需求:

 

基於一系列時間點的數據記錄分析、統計某種結果。比如GPS定位設備按一定時間間隔回傳位置數據並記錄到數據庫中,數據包括經緯度、時間、速度等,現在需要基於這些回傳數據統計是否在某地有停留,停留時間、開始時間、結束時間。停留標誌是速度爲0。顯示,這需要根據數據記錄之間的差值做統計計算。

 

3、適合需求的輸出及轉換、處理:

如果按照缺省的SQL Server日期輸出格式,輸出內容可映射爲編程語言相關的數據類型,如Java可以是String、Date,轉爲爲Date有一定統計數據量的話,這個轉換本身就是低效和耗時的,實際過程可能是先從SQL Server內部表示轉換爲yyyy-MM-dd hh:mm:ss.SSS字符串,再從這個字符串轉換爲Date;作爲String使用也需要轉換爲Date之後纔可以做時間差運算,同樣低效。

 

SQL Server內部數據表示格式其實已經適合表達時間差了,是不是能直接利用。SQL Server有cast函數,可以將日期輸出爲二進制數據。如:

 

select longi, lati, speed, cast(gpsDate as binary(8)) as gpsDate from loc_history

 

後續處理代碼片段爲:

 

float lon = rs.getFloat("longi");
float lat = rs.getFloat("lati");

byte time[] = rs.getBytes("gpsDate");

獲得經緯度、時間二進制表示

 

int days = ((time[0] & 0x00ff) << 24) + ((time[1] & 0x00ff) << 16)
                    + ((time[2] & 0x00ff) << 8) + (time[3] & 0x00ff);
int seconds = ((time[4] & 0x00ff) << 24) + ((time[5] & 0x00ff) << 16)
                    + ((time[6] & 0x00ff) << 8) + (time[7] & 0x00ff);

seconds /= 300;

將時間轉換爲天和秒,至此,可以很方便的進行時間差運算了。

 

如果需要將天、秒時間轉換爲yyyy-MM-dd hh:mm:ss.SSS格式,基於1900-01-01,使用Calendar和SimpleDateFormat即可完成。

 

這種使用方式是一定程度上直接使用SQL Server的內部表示格式,去掉不必要的格式轉換,從而加快運算速度,缺點是這種處理方式是數據庫相關的,換爲其他數據庫則算法失效。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章