在Microsoft SQL Server的類型系統中,使用 date 表示日期類型,使用time表示時間類型,使用DateTime和DateTime2表示日期和時間的組合,DateTime2是DateTime的升級版本,這些數據類型佔用的存儲空間各不相同;當存儲大量數據時,合理的選擇小數秒的精度,可以節省數據的佔用空間。sql
當表示國際時間時,存在本地時間和UTC時間之別,同一個時刻,UTC時間是固定的,而本地時間因爲時區的差別而不相同。若是一個數據實體的時間字段對時區敏感,那麼能夠使用DateTimeOffset數據類型,該類型不只包含本地的日期和時間,還包括本地的時區,用戶可以根據本地的時間和時區推算出UTC時間,公式是:UTC時間=本地時間+時區偏移。express
小數秒的精度(fractional seconds precision)是指使用多少位小數表示一秒,DateTime二、Time和DataTimeOffset能夠控制小數秒的精度,語法是DateTime2(n)、time(n),DataTimeOffset(n),n是小數秒的精度,n的取值範圍是0-7,默認值是7,即便用7位小數表示1s,可以表示的最小精確時間(Accuracy)是100ns。DateTime數據類型的最小精確時間是3.33毫秒(0.00333秒),其精確度不高,建議在產品環境中,使用DateTime2(n)來代替DateTime類型。函數
DateTime2(n)表示日期和時間,Date只表示日期,Time(n)只表示時間,最後簡單介紹DateTime類型。spa
1,DateTime2數據類型code
DateTime2(n)數據類型存儲日期和時間,它是DateTime的升級版本,因爲小數秒n的精度能夠自主設置,其存儲大小(Storage Size)不固定,DateTime2(n)佔用的存儲空間和小數秒的精度之間的關係是:server
DateTime2能夠表示比DateTime更精確的時間,默認的數據格式是yyyy-MM-dd hh:mm:ss.nnnnnnn,DateTime2 秒默認的精度是7,即用7位小數表示一秒的精度。blog
datetime2 [ (fractional seconds precision) ]
下面兩種聲明DateTime2變量的方式是等價的:ci
declare @dt2 datetime2(7) declare @dt2 datetime2
爲DateTime2類型的變量賦值,須要使用SysDateTime()和SysUTCDateTime(),這兩個函數返回值的類型是DateTime2(7)。rem
declare @dt2 datetime2 set @dt2=SYSDATETIME()
3,Date數據類型文檔
Date數據類型只存儲日期,不存儲時間,僅須要3B的存儲空間,默認的數據格式是yyyy-MM-dd,支持的日期範圍從0001-01-01到9999-12-31
能夠使用日期字符串,getdate()等函數爲Date類型的變量賦值:
declare @d date set @d='2015-07-02' set @d=getdate() set @d=SYSDATETIME()
4,Time類型
Time(n)數據類型只存儲時間,不存儲日期,須要5B的存儲空間。Time(n)小數秒精度n的默認值是7,默認的數據格式是hh:mm:ss.nnnnnnn:
time [ (fractional second precision) ]
推薦使用時間字符串和sysdatetime()函數爲Time類型的變量賦值,不推薦使用GetDate()函數,GetDate()函數返回的是DateTime類型,時間部分的小數位精度是3,若是對時間的精度要求高,請使用時間字符串和sysdatetime()函數爲Time類型的變量賦值。
--declare @t time(7) DECLARE @t time set @t='13:48:43.2840467' set @t=SYSDATETIME() --not recommend set @t=GETDATE()
4,DateTime數據類型
DateTime數據類型存儲日期和時間,其存儲空間是固定的8個字節,默認的數據格式是yyyy-MM-dd hh:mm:ss.nnn,表示從1753年1月1日到9999年12月31日的日期和時間數據,精確度爲3.33毫秒(0.00333秒),也就是說,DateTime表示的日期範圍從公元1753年1月1日00:00:00.000 到9999年12月31日23:59:59.997 ,精確到3.33毫秒。
在DateTime使用的8個字節中,實際上,SQL Server用兩個4 字節的整數內部存儲 datetime 數據類型的值。第一個 4 字節存儲基礎日期(即 1900 年 1 月 1 日)以前或以後的天數。基礎日期是系統參考日期,不容許出現早於 1753 年 1 月 1 日的 date 值。當第一個4 字節爲0 時,表示的日期是1900 年1 月1 日;在基礎日期以前的日期,第一個4字節的值是負數,在基礎日期以後的日期,第一個4字節的值是正數。另一個 4 字節存儲以10/3 毫秒數所表明的天天的時間。
declare @dt datetime
使用GetDate()和GetUTCDate()爲DateTime類型的變量賦值,這兩個函數返回值的類型是DateTime
declare @dt datetime set @dt=getdate()
鑑於DateTime的秒精確度(精確度爲3)沒有DateTime2(n)高,而且佔用的存儲空間也比DateTime2(n)高,因此,建議在產品環境中使用DateTime2(n)來代替DateTime類型。
DateTimeOffset(n)數據類型由三部分構成:date、time和 offset(時區偏移),包含了日期、時間和時區數據,其日期和時間使用是本地時間。在本地時間的基礎上,使用時區偏移量(offset)來計算UTC時間,所以,DateTimeOffset(n)能夠同時表示本地時間和UTC時間,默認的顯示文本是:YYYY-MM-DD hh:mm:ss[.nnnnnnn] [{+|-}hh:mm],默認值是1900-01-01 00:00:00 00:00。
DateTimeOffset(n)可以表示的日期、時間和時區範圍是:
小數秒的精度會影響變量佔用的存儲空間的大小:
時區偏移的格式爲:[+|-] hh:mm,hh 表示的小時範圍是00-14,mm 表示的分鐘範圍是00-59,把DateTimeOffset時間中的UTC時間 和 時區偏移量 進行算術運算,能夠獲得本地時間。
1,返回本地時間的DateTimeOffset
返回本地的時間和時區,本地時間是2018-08-29 11:11:29.5765832,本地所在的時區是東八區:
SELECT SYSDATETIMEOFFSET ( )
2,把DateTime2時間轉換爲DateTimeOffset時間
向DateTime2時間中添加時區信息:
TODATETIMEOFFSET ( expression , time_zone )
參數註釋:
例如,使用SYSDATETIME獲得本地的DateTime2,添加時區(東八區),獲得的包含時區信息的DateTimeOffset:
SELECT TODATETIMEOFFSET(SYSDATETIME(),'+08:00'),SYSDATETIMEOFFSET()
3,切換時區
把DateTimeOffset類型的數據切換到指定的時區,在轉換過程當中,UTC時間是固定的,依據固定的UTC時間,切換到特定時區的本地時間:
SWITCHOFFSET ( DATETIMEOFFSET, time_zone )
參數註釋:
例如,把本地時間的時區東八區切換到東七區:
DECLARE @remote DATETIMEOFFSET DECLARE @local DATETIMEOFFSET SET @local = SYSDATETIMEOFFSET() SET @remote = SWITCHOFFSET (@local, '+07:00') SELECT @remote AS remote_time,@local AS local_time
能夠看到,東7區的時間比東8區的時間晚一個小時。
4,丟棄時區信息
DateTime2表示的是本地時間,DateTimeOffset表示的是本地時間和本地的時區,若是數據不須要考慮時區信息,那麼能夠直接把DateTimeOffset時間賦值給DateTime2時,SQL Server執行隱式轉換,把時區信息丟棄,只把本地時間賦值給DateTime2:
DECLARE @datetimeoffset DATETIMEOFFSET(4) DECLARE @datetime2 DATETIME2(3)=@datetimeoffset; SET @datetimeoffset= '2012-10-25 12:24:32.1277 +01:00' SET @datetime2=@datetimeoffset SELECT @datetimeoffset AS '@datetimeoffset', @datetime2 AS '@datetime2';
DataLength能過返回任意數據類型的變量所佔用的字節數量,從下圖中能夠看到,datetime佔用的存儲空間太大,精度不高,datetime2完勝datetime,在產品環境中,推薦使用datetime2:
declare @dt1 datetime declare @dt2 datetime2(2) declare @dt3 datetime2(4) set @dt1=getdate() set @dt2=getdate() set @dt3=SYSDATETIME() select DATALENGTH(@dt1),DATALENGTH(@dt2),DATALENGTH(@dt3),@dt1,@dt2,@dt3
若是對time的要求不是很高,保留2位毫秒,使用datetime2(2),比其餘類型節省存儲空間。
本地時間:世界的每一個地區都有本身的本地時間,整個地球分爲二十四時區,每一個時區都有本身的本地時間。
UTC時間:在國際無線電通訊中,爲統一而廣泛使用一個標準時間,稱爲通用協調時(UTC, Universal Time Coordinated)。UTC時間和英國倫敦的本地時間相同。UTC時間在世界各地都是相同的,可是不一樣的時區,本地時間各不相同。根據UTC時間和所在的時區,可以計算出本地時間。
1,獲取本地時間和UTC時間
在SQL Sever中,GetDate()返回的是本地時間,GetUTCDate()返回的是UTC時間,返回的數據類型是DateTime;SysDateTime() 返回的是本地時間,SysUTCDateTime() 返回的是UTC時間,返回的數據類型是DateTime2(7)。
在不一樣的時區,UTC時間相同,可是本地時間不一樣。本地時間是Server上顯示的系統時間,在OS中變動時區(time zone),可以修改本地時間和GetDate()的返回值。本地時間是根據UTC時間和OS設置的時區推導出來的。
結論:GetDate() 和SysDateTime() 返回的是本地Server的Date和Time,這個值跟SQL Server實例本地主機的OS有關,跟OS顯示的時間是相同的。
2,SQL Agent 執行Job的時間
在SQL Server Agent中使用的時間是本地時間,Job的執行時間是本地時間。
參考文檔: