處理日期和時間數據--日期和時間函數


  本節介紹一些對日期和時間數據類型進行操作的函數,包括GETDATE、CURRENT_TIMESTAP、GETUTCDATE、SYSDATETIME、SYSUTCDATETIME、SYSDATETIMEOFFSET、CAST、CONVERT、SWITCHOFFSET、TODATETIMEOFFSET、DATEADD、DATEDIFF、DATEPART、YEAR、MONTH、DAY,以及DATENAME。注意,SYSDATETIME、SYSUTCDATETIME、SYSDATETIMEOFFSET、SWITCHOFFSET,以及TODATETIMEOFFSET是SQL Server 2008中新增的,其他幾個函數在SQL Server 2008之前的版本中也可以使用。不過,SQL Server 2008對原有的幾個函數進行了改進,以支持新的日期和時間數據類型,以及新的日期和時間組成部分。

日期和時間函數

  以下幾個不帶參數的函數可以返回SQL Server實例所在系統的當前日期和時間:GETDATE、CURRENT_TIMESTAMP、GETUTCDATE、SYSDATETIME、SYSUTCDATETIME,以及SYSDATETIMEOFFSET。下表列舉了這些函數的一些信息。

函數

返回類型

描述

是否是SQL Server 2008新加的

GETDATE

DATETIME

當前日期和時間

CURRENT_TIMESTAMP

DATETIME

與GETDATE相同,而且是ANSI SQL

GETUTCDATE

DATETIME

以UTC格式表示的當前日期和時間

SYSDATETIME

DATETIME2

當前日期和時間

SYSUTCDATETIME

DATETIME2

以UTC格式表示的當前日期和時間

SYSDATETIMEOFFSET

DATETIMEOFFSET

當前日期和時間,包含時區偏移量

注意,除了ANSI函數CURRENT_TIMESTAMP以外,對於不需要參數的函數,在調用它們時都必須多加一對空的圓括號。此外,因為CURRENT_TIMESTAMP和GETDATE返回的內容相同,但前者是標准SQL,所以推薦優先選用CURRENT_TIMESTAMP。我們應該盡量遵循一條實踐原則:當完成同樣的事情有多種選擇,而且它們之間在功能和性能上都沒有區別,但只有一個是標准SQL,其他都不是時,我們應該偏向選擇使用標准SQL。

  以下代碼演示了取得當前日期和時間函數的用法:

1 SELECT
2 GETDATE () AS [ GETDATE ] ,
3 CURRENT_TIMESTAMP AS [ CURRENT_TIMESTAMP ] ,
4 GETUTCDATE() AS [ GETUTCDATE ] ,
5 SYSDATETIME() AS [ SYSDATETIME ] ,
6 SYSUTCDATETIME() AS [ SYSUTCDATETIME ] ,
7 SYSDATETIMEOFFSET() AS [ SYSDATETIMEOFFSET ] ;

  或許你會發現,SQL Server 2008中的函數都不是只返回當前系統日期或只返回當前系統時間。不過,通過把CURRENT_TIMESTAMP或SYSDATETIME轉換為DATE或TIME,可以容易地做到這一點,如下所示:

1 SELECT
2 CAST (SYSDATETIME() AS DATE) AS [ Current_date ] ,
3 CAST (SYSDATETIME() AS TIME) AS [ Current_time ] ;

CAST和CONVERT函數

  CAST和CONVERT函數用於轉換值的數據類型。

語法

CAST(value AS datatype)

CONVERT(datatype,value [,style_number])

  這兩個函數都可以將輸入的值轉換為指定的數據類型。在一些情況下,還能用CONVERT提供的第三個參數來指定轉換的樣式。例如,當把字符串轉換成日期和時間數據類型(或者進行反向轉換)時,style樣式值可以指定字符串的格式。例如,樣式值101表示'MM/DD/YYYY',而103則表示'DD/MM/YYYY'。有關樣式值和它們各自含義的完整列表,可以在SQL Server聯機叢書的“CAST和CONVERT”一節中找到相關的內容。當把字符串轉換成某些日期和時間數據類型時,一些字符串格式是依賴於語言的。這里推薦要么使用一種獨立於語言的格式,要么使用CONVERT函數,顯示地指定要用的樣式值。這樣,無論登錄時用的語言是什么,SQL Server對代碼的解釋方式都是一樣的。

  注意,CAST是ANSI標准SQL,而CONVERT不是;所以,除非需要使用樣式值,否則推薦優先使用CAST函數,以保證代碼盡可能與標准兼容。

  以下代碼把字符串文字'20090212'轉換成一個DATE數據類型的值,其實只能提取其當前的系統日期:

1 SELECT CAST ( ' 20090212 ' AS DATE);

  以下代碼把當前系統日期和時間值轉換成一個TIME數據類型的值,其實只能提取其當前的系統時間:

1 SELECT CAST (SYSDATETIME() AS TIME);

  還記得DATE和TIME是SQL Server 2008新引入的數據類型吧。前面介紹過,如果在SQL Server 2008之前的版本中只想用日期或時間,就必須把DATETIME或SMALLDATETIME值中不相關的部分設置為“0”。換句話說,要只使用日期,就得把時間部分設置為午夜;要只使用時間,就得把日期設置為基礎日期1900年1月1日。稍后將會介紹把給定的日期和時間值(比如CURRENT_TIMESTAMP)中不相關的部分設置為0的技巧。

  以下代碼用樣式值112('YYYYMMDD'),把當前日期和時間值轉換為CHAR(8):

1 SELECT CONVERT ( CHAR ( 8 ), CURRENT_TIMESTAMP , 112 );

  例如,如果當前日期是2009年2月12日,這一代碼將返回'20090212'。記住該樣式是語言無關的,所以當用代碼把結果再轉換回DATETIME類型時,得到的當前日期的時間部分將是午夜:

1 SELECT CAST ( CONVERT ( CHAR ( 8 ), CURRENT_TIMESTAMP , 112 ) AS DATETIME );

  類似地,要把日期部分設置為基礎日期,可以先用樣式114值('hh:mm:ss.nnn')把當前日期和時間值轉換為CHAR(12):

1 SELECT CONVERT ( CHAR ( 12 ), CURRENT_TIMESTAMP , 114 );

  當用代碼把結果再轉換回DATETIME時,得到的當前的日期部分將是基礎日期:

1 SELECT CAST ( CONVERT ( CHAR ( 12 ), CURRENT_TIMESTAMP , 114 ) AS DATETIME );

SWITCHOFFSET函數

  SWITCHOFFSET函數可以按指定的時區對輸入的DATETIMEOFFSET值進行調整。

語法

SWITCHOFFSET(datetimeoffset_value,time_zone)

  例如,以下代碼將當前系統時間的datetimeoffset值按時區-05:00進行調整:

1 SELECT SWITCHOFFSET(SYSDATETIMEOFFSET(), ' -05:00 ' );

  如果當前系統的datetimeoffset值是February 12,2009 10:00:00.0000000 -08:00,這段代碼將返回以下值:February 12,2009 13:00:00.0000000 -05:00。

  而以下代碼則將當前的datetimeoffset值調整為UTC時間:

1 SELECT SWITCHOFFSET(SYSDATETIMEOFFSET(), ' +00:00 ' );

  假設當前的datetimeoffset值為前面提到的那個值,該代碼將返回以下值:

February 12,2009 18:00:00.0000000 +00:00。

TODATETIMEOFFSET函數

語法

TODATETIMEOFFSET(date_and_time_value,time_zone)

  這個函數與SWITCHOFFSET函數的區別有兩點。首先,它可以接受的輸入不限於datetimeoffset值,而是支持任何日期和時間數據類型。其次,它不是根據輸入值的原始值和指定的時區之間的差值來調整時間,而只是簡單地用指定的時區將輸入的日期和時間值作為datetimeoffset值返回。例如,如果當前系統的datetimeoffset值是February 12,2009 10:00:00.0000000 -08:00,運行以下代碼:

1 SELECT TODATETIMEOFFSET(SYSDATETIMEOFFSET(), ' -05:00 ' );

會得到以下值:February 12,2009 10:00:00.0000000 -05:00。還記得前面的SWITCHOFFSET函數返回值是February 12,2009 13:00:00.0000000 -05:00吧,因為它是根據輸入的時區(-08:00)和指定的時區(-05:00)之間的時區差來調整時間的。

  如前所述,TODATETIMEOFFSET函數可以支持任何日期和時間數據類型作為輸入。例如,以下代碼以當前系統日期和時間值作為輸入,將其更改為時區是-05:00的datetimeoffset值:

1 SELECT TODATETIMEOFFSET(SYSDATETIME(), ' -05:00 ' );

DATEADD函數

  DATEADD函數可以將指定日期的部分作為單位,為輸入的日期和時間值增加指定的數量。

語法

DATEADD(part,n,dt_val)

  日期部分的有效值包括year、quarter、month、dayofyear、day、week、weekday、hour、minute、second、millisecond、microsecond,以及nanosecond。最后兩個是SQL Server 2008新增加的。也可以按縮寫格式來指定這些時間部分,例如用yy代替year。要了解相關的細節,請參考SQL Server聯機叢書。

  該函數返回值的類型與輸入的日期和時間值的類型相同。如果輸入的是一個字符串文字,輸出的則是DATETIME。

例如,以下代碼為“2009年2月12日”增加1年:

1 SELECT DATEADD ( year , 1 , ' 20090212 ' );

DATEDIFF函數

  DATEDIFF返回兩個日期和時間值之間相差的指定部分的計數。

語法

DATEDIFF(part,dt_val1,dt_val2)

  例如,以下代碼返回兩個值之間相差的天數:

1 SELECT DATEADD ( day , DATEDIFF ( day , ' 20010101 ' , CURRENT_TIMESTAMP ), ' 20010101 ' );

  在SQL Server 2008之前的版本中,可以用以下代碼將當前系統日期和時間值中的時間部分設置為午夜:

1 SELECT DATEADD ( month , DATEDIFF ( month , ' 20010101 ' , CURRENT_TIMESTAMP ), ' 20010101 ' );

  這段代碼首先用DATEDIFF函數計算一個錨點(anchor)日期的午夜值(在這個例子中是'20010101')與當前日期和時間之間相差的總天數(也稱為不同的diff值)。接着,再用DATEADD函數為錨點日期增加上一步得到的diff天。這樣就可以得到當前系統日期在午夜的時間值。

  有趣的是,如果在這個表達式中用month(月)取代day(天)來作為計數單位,並確保使用的錨點日期是某個月的第1天(如我們這個例子所示),最后得到的結果將是當前月份的第1天:

1 SELECT DATEADD ( month , DATEDIFF ( month , ' 20010101 ' , CURRENT_TIMESTAMP ), ' 20010101 ' );

  類似地,用year(年)作為計數單位,並用某年的第1天作為錨點日期,最后得到的將是當前年的第1天。

  如果想要得到當前月或當前年的最后一天,只要簡單地把錨點日期修改為月或年的最后1天。例如,以下表達式返回當前月份的最后1天:

1 SELECT DATEADD ( MONTH , DATEDIFF ( month , ' 19991231 ' , CURRENT_TIMESTAMP ), ' 19991231 ' );

DATEPART函數

  DATEPART函數返回一個表示給定日期和時間值的指定部分的整數。

語法

DATEPART(part,dt_val)

  part參數的有效值包括year、quarter、month、dayofyear、day、week、weekday、hour、minute、second、millisecond、microsecond、nanosecond、TZoffset,以及ISO_WEEK。最后4個part參數值是SQL Server 2008中新增的。如前所述,日期和時間部分的名稱也可以使用縮寫格式,如用yy代替year、用mm代替month、用dd代替day,等等。作為例子,以下代碼返回輸入值的月份部分:

1 SELECT DATEPART ( month , ' 20090212 ' );

  這一代碼將返回整數2.

YEAR、MONTH和DAY函數

  YEAR、MONTH,以及DAY函數是DATEPART函數的簡略版本,它們分別返回一個代表輸入日期和時間值中年、月、日部分的整數。

語法

YEAR(dt_val)

MONTH(dt_val)

DAY(dt_val)

例如,以下代碼提取出輸入值的日、月、年部分:

1 SELECT DAY ( ' 20090212 ' ) AS theday,
2 MONTH ( ' 20090212 ' ) AS themonth,
3 YEAR ( ' 20090212 ' ) AS theyear;

DATENAME函數

  DATENAME函數返回一個表示給定日期和時間值的指定部分的字符串。

語法

DATENAME(part,dt_val)

  這個函數與DATEPART類似,它們的part輸入參數的有效值都是相同的。不過,DATENAME返回的是代表請求部分的名字,而不是數字。例如,以下代碼返回給定輸入值的月份的名稱:

1 SELECT DATENAME ( month , ' 20090212 ' );

  回想一下,對於同樣的輸入,前面的DATEPART返回的是整數2。而DATENAME返回的是月份的名稱,該名稱是依賴於語言的。如果當前會話的語言是某種英語,函數調用的返回值將是'February'。如果請求的部分沒有名稱,只是一個數字值(比如年份),則DATENAME函數將它的數字值作為字符串而返回。例如,以下代碼返回'2009':

1 SELECT DATENAME ( year , ' 20090212 ' );

ISDATE函數

  ISDATE接受一個字符串作為輸入,如果能把這個字符串轉換為日期和時間數據類型的值,則返回值1;如果不能,則返回值0。

語法

ISDATE(string)

例如,以下代碼返回1:

1 SELECT ISDATE ( ' 20090212 ' );

而以下代碼則返回0:

1 SELECT ISDATE ( ' 20090230 ' );

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM