MySQL數據庫中的Date,DateTime和TimeStamp類型詳解 DATETIME, DATE和TIMESTAMP類型是相關的。本文描述他們的特征,他們是如何類似的而又不同的。 DATETIME類型用在你需要同時包含日期和時間信息的值時。MySQL檢索並且以'YYYY-MM-DD HH:MM:SS'格式顯示DATETIME值,支持的范圍是'1000-01-01 00:00:00'到'9999-12-31 23:59:59'。(“支持”意味著盡管更早的值可能工作,但不能保證他們可以。) www.2cto.com DATE類型用在你僅需要日期值時,沒有時間部分。MySQL檢索並且以'YYYY-MM-DD'格式顯示DATE值,支持的范圍是'1000-01-01'到'9999-12-31'。 TIMESTAMP列類型提供一種類型,你可以使用它自動地用當前的日期和時間標記INSERT或UPDATE的操作。如果你有多個TIMESTAMP列,只有第一個自動更新。 自動更新第一個TIMESTAMP列在下列任何條件下發生: 列沒有明確地在一個INSERT或LOAD DATA INFILE語句中指定。 列沒有明確地在一個UPDATE語句中指定且一些另外的列改變值。(注意一個UPDATE設置一個列為它已經有的值,這將不引起TIMESTAMP列被更新,因為如果你設置一個列為它當前的值,MySQL為了效率而忽略更改。) 你明確地設定TIMESTAMP列為NULL. 除第一個以外的TIMESTAMP列也可以設置到當前的日期和時間,只要將列設為NULL,或NOW()。 通過明確地設置希望的值,你可以設置任何TIMESTAMP列為不同於當前日期和時間的值,即使對第一個TIMESTAMP列也是這樣。例如,如果,當你創建一個行時,你想要一個TIMESTAMP被設置到當前的日期和時間,但在以後無論何時行被更新時都不改變,你可以使用這個屬性: www.2cto.com 讓MySQL在行被創建時設置列,這將初始化它為當前的日期和時間。 當你執行隨後的對該行中其他列的更改時,明確設定TIMESTAMP列為它的當前值。 另一方面,你可能發現,當行被創建並且遠離隨後的更改時,很容易用一個你用NOW()初始化的DATETIME列。 TIMESTAMP值可以從1970的某時的開始一直到2037年,精度為一秒,其值作為數字顯示。 在MySQL檢索並且顯示TIMESTAMP值取決於顯示尺寸的格式如下表。“完整”TIMESTAMP格式是14位,但是TIMESTAMP列可以用更短的顯示尺寸創造: 列類型 顯示格式 TIMESTAMP(14) YYYYMMDDHHMMSS TIMESTAMP(12) YYMMDDHHMMSS TIMESTAMP(10) YYMMDDHHMM TIMESTAMP(8) YYYYMMDD TIMESTAMP(6) YYMMDD TIMESTAMP(4) YYMM TIMESTAMP(2) YY 所有的TIMESTAMP列都有同樣的存儲大小,不考慮顯示尺寸。最常見的顯示尺寸是6、8、12、和14。你可以在表創建時間指定一個任意的顯示尺寸,但是值0或比14大被強制到14。在從1~13范圍的奇數值尺寸被強制為下一個更大的偶數。 使用一個常用的格式集的任何一個,你可以指定DATETIME、DATE和TIMESTAMP值: 'YYYY-MM-DD HH:MM:SS'或'YY-MM-DD HH:MM:SS'格式的一個字符串。允許一種“寬松”的語法--任何標點可用作在日期部分和時間部分之間的分隔符。例如,'98-12-31 11:30:45'、'98.12.31 11+30+45'、'98/12/31 11*30*45'和'98@12@31 11^30^45'是等價的 'YYYY-MM-DD'或'YY-MM-DD'格式的一個字符串。允許一種“寬松”的語法。例如,'98-12-31', '98.12.31', '98/12/31'和'98@12@31'是等價的。 www.2cto.com 'YYYYMMDDHHMMSS'或'YYMMDDHHMMSS'格式的沒有任何分隔符的一個字符串,例如,'19970523091528'和'970523091528'被解釋為'1997-05-23 09:15:28',但是'971122459015'是不合法的(它有毫無意義的分鐘部分)且變成'0000-00-00 00:00:00'。 'YYYYMMDD'或'YYMMDD'格式的沒有任何分隔符的一個字符串,如果字符串認為是一個日期。例如,'19970523'和'970523'被解釋作為'1997-05-23',但是'971332'是不合法的( 它有無意義的月和天部分)且變成'0000-00-00'。 YYYYMMDDHHMMSS或YYMMDDHHMMSS格式的一個數字,如果數字認為是一個日期。例如,19830905132800和830905132800被解釋作為'1983-09-05 13:28:00'。 YYYYMMDD或YYMMDD格式的一個數字,如果數字認為是一個日期。例如,19830905和830905被解釋作為'1983-09-05'。 一個返回值可以在一個DATETIME, DATE或TIMESTAMP上下文環境中接受的函數,例如NOW()或CURRENT_DATE。 不合法DATETIME, DATE或TIMESTAMP值被變換到適當類型的“零”值('0000-00-00 00:00:00', '0000-00-00'或00000000000000)。 對於包括的日期部分分隔符的指定為字符串的值,不必要為小於10的月或天的值指定2位數字,'1979-6-9'與'1979-06-09'是一樣的。同樣, 對於包括的時間部分分隔符的指定為字符串的值,不必為小於10的小時、月或秒指定2位數字,'1979-10-30 1:2:3'與'1979-10-30 01:02:03'是一樣的。 指定為數字應該是6、8、12或14位長。如果數字是8或14位長,它被假定以YYYYMMDD或YYYYMMDDHHMMSS格式並且年份由頭4位數字給出。如果數字是6或12位長,它被假定是以YYMMDD或YYMMDDHHMMSS格式且年份由頭2位數字給出。不是這些長度之一的數字通過填補前頭的零到最接近的長度來解釋。 www.2cto.com 指定為無分隔符的字符串用它們給定的長度來解釋。如果字符串長度是8或14個字符,年份被假定頭4個字符給出,否則年份被假定由頭2個字符給出。對於字符串中呈現的多個部分,字符串從左到右邊被解釋,以找出年、月、日、小時、分鐘和秒值,這意味著,你不應該使用少於 6 個字符的字符串。例如,如果你指定'9903',認為將代表1999年3月,你會發現MySQL把一個“零”日期插入到你的表中,這是因為年份和月份值99和03,但是日期部分丟失(零),因此該值不是一個合法的日期。 TIMESTAMP列使用被指定的值的完整精度的存儲合法的值,不考慮顯示大小。這有幾個含意: 總是指定年,月,和日,即使你的列類型是TIMESTAMP(4)或TIMESTAMP(2)。否則,值將不是一個合法的日期並且0將被存儲。 如果你使用ALTER TABLE拓寬一個狹窄的TIMESTAMP列,以前被“隱蔽”的信息將被顯示。 同樣,縮小一個TIMESTAMP列不會導致信息失去,除了感覺上值在顯示時,較少的信息被顯示出。 盡管TIMESTAMP值被存儲為完整精度,直接操作存儲值的唯一函數是Unix_TIMESTAMP(),其他函數操作在格式化了的檢索的值上,這意味著你不能使用函數例如HOUR()或SECOND(),除非TIMESTAMP值的相關部分被包含在格式化的值中。例如,一個TIMESTAMP列的HH部分部被顯示,除非顯示大小至少是10,因此在更短的TIMESTAMP值上試試使用HOUR()產生一個無意義的結果。 在某種程度上,你可以把一種日期類型的值賦給一個不同的日期類型的對象。然而,這可能值有一些改變或信息的損失: 如果你將一個DATE值賦給一個DATETIME或TIMESTAMP對象,結果值的時間部分被設置為'00:00:00',因為DATE值不包含時間信息。 如果你將一個DATETIME或TIMESTAMP值賦給一個DATE對象,結果值的時間部分被刪除,因為DATE類型不存儲時間信息。 記住,盡管DATETIME, DATE和TIMESTAMP值全都可以用同樣的格式集來指定,但所有類型不都有同樣的值范圍。例如,TIMESTAMP值不能比1970早或比2037網晚,這意味著,一個日期例如'1968-01-01',當作為一個DATETIME或DATE值合法時,它不是一個正確TIMESTAMP值,並且 如果賦值給這樣一個對象,它將被變換到0。 www.2cto.com 當指定日期值時,當心某些缺陷: 允許作為字符串指定值的寬松格式能被欺騙。例如,值例如'10:11:12'可能看起來像時間值,因為“:”分隔符,但是如果在一個日期中使用,上下文將作為年份被解釋成'2010-11-12'。值'10:45:15'將被變換到'0000-00-00',因為'45'不是一個合法的月份。 以2位數字指定的年值是模糊的,因為世紀是未知的。MySQL使用下列規則解釋2位年值: 在00-69范圍的年值被變換到2000-2069。 在70-99范圍的年值被變換到1970-1999。 摘自 Hurry的專欄