【Mysql 學習】時間型別

楊奇龍發表於2011-01-01

日期時間型別

表示時間值的DATE和時間型別為DATETIME、DATE、TIMESTAMP、TIME和YEAR。
每個時間型別有一個有效值範圍和一個“零”值,當指定不合法的MySQL不能表示的值時使用“零”值。TIMESTAMP型別有專有的自動更新特性,將在後面描述。

  如果試圖插入一個不合法的日期,MySQL將給出警告或錯誤。可以使用ALLOW_INVALID_DATES SQL模式讓MySQL接受某些日期,例如'1999-11-31'。當你想要儲存一個“可能錯誤的”使用者已經在資料庫中指定(例如,以web形式)用於將來處理的值時很有用。在這種模式下,MySQL只驗證月範圍為從0到12,日範圍為從0到31。這些範圍可以包括零,因為MySQL允許在DATE或DATETIME列儲存日/月和日是零的日期。
  這在應用程式需要儲存一個你不知道確切日期的生日時非常有用。在這種情況下,只需要將日期儲存為'1999-00-00'或'1999-01-00'。如果儲存此類日期,DATE_SUB()或DATE_ADD等需要完整日期的函式不會得到正確的結果。(如果你不想在日期中出現零,可以使用NO_ZERO_IN_DATE SQL模式)。

MySQL還允許將'0000-00-00'儲存為"偽日期"(如果不使用NO_ZERO_DATE SQL模式)。這在某些情況下比使用NULL值更方便(並且資料和索引佔用的空間更小)。

將sql_mode系統變數設定為相應模式值,可以更確切你想讓MySQL支援哪種日期。

當使用日期和時間型別時應記住以下幾點:
· MySQL以標準輸出格式檢索給定日期或時間型別的值,但它盡力解釋你指定的各種輸入值格式(例如,當你指定一個分配給或與日期或時間型別進行比較的值時)。只支援下面章節中描述的格式。期望你能提供有效值。如果你使用其它格式的值會發生意想不到的結果。

·包含兩位年值的日期會令人模糊,因為世紀不知道。MySQL使用以下規則解釋兩位年值:
 . 70-99範圍的年值轉換為1970-1999。
 . 00-69範圍的年值轉換為2000-2069。

·儘管MySQL嘗試解釋幾種格式的值,日期總是以年-月-日順序(例如,'98-09-04'),而不是其它地方常用的月-日-年或日-月-年順序(例如,'09-04-98','04-09-98')。

·如果值用於數值上下文中,MySQL自動將日期或時間型別的值轉換為數字,反之亦然。

·當 MySQL遇到一個日期或時間型別的超出範圍或對於該型別不合法的值時(如本節開始所描述),它將該值轉換為該類的"零"值。一個例外是超出範圍的TIME值被裁剪到TIME範圍的相應端點。
下面的表顯示了各類"零"值的格式。請注意如果啟用NO_ZERO_DATE SQL模式,使用這些值會產生警告。
列型別     "零"值
 
DATETIME    '0000-00-00 00:00:00'
DATE        '0000-00-00'
TIMESTAMP   00000000000000
TIME        '00:00:00'
YEAR        0000
 

·"零"值是特殊值,但你可以使用表內顯示的值顯式儲存或引用它們。你也可以使用值'0'或0來儲存或引用,寫起來更容易。

·MyODBC中使用的"零"日期或時間值在MyODBC 2.50.12和以上版本中被自動轉換為NULL,因為ODBC不能處理此類值。
DATETIME、DATE和TIMESTAMP型別 自MySQL 4.1以來的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'。(“支援”表示儘管先前的值可能工作,但沒有保證)。
   當需要日期值而不需要時間部分時應使用DATE型別。MySQL用'YYYY-MM-DD'格式檢索和顯示DATE值。支援的範圍是'1000-01-01'到 '9999-12-31'。
   TIMESTAMP列型別的屬性不固定,取決於MySQL版本和伺服器執行的SQL模式。
可以使用任何常見格式指定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'和 11^30^45'是等價的。

·'YYYY-MM-DD'或'YY-MM-DD'格式的字串。這裡也允許使用“不嚴格的”語法。例如,'98-12-31'、'98.12.31'、'98/12/31'和是等價的。

·'YYYYMMDDHHMMSS'或'YYMMDDHHMMSS'格式的沒有間割符的字串,假定字串對於日期型別是有意義的。例如,'19970523091528'和'970523091528'被解釋為'1997-05-23 09:15:28',但'971122129015'是不合法的(它有一個沒有意義的分鐘部分),將變為'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,不需要指定兩位數。'1979-6-9'與'1979-06-09'是相同的。同樣,對於包括時間部分間割符的字串值,如果時、分和秒的值小於10,不需要指定兩位數。'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位數表示年。其它數字被解釋為彷彿用零填充到了最近的長度。

指定為非限定符字串的值使用給定的長度進行解釋。如果字串為8或14字元長,前4位數表示年。否則,前2位數表示年。從左向右解釋字串內出現的各部分,以發現年、月、日、小時、分和秒值。這說明不應使用少於6字元的字串。例如,如果你指定'9903',認為它表示1999年3月,MySQL將在你的表內插入一個“零”日期值。這是因為年和月值是99和03,但日部分完全丟失,因此該值不是一個合法的日期。但是,可以明顯指定一個零值來代表缺少的月或日部分。例如,可以使用'990300'來插入值'1999-03-00'。

在一定程度上,可以將一個日期型別的值分配給一個不同的日期型別。但是,值可能會更改或丟失一些資訊:

· 如果你為一個DATETIME或TIMESTAMP物件分配一個DATE值,結果值的時間部分被設定為'00:00:00',因為DATE值未包含時間資訊。

· 如果你為一個DATE物件分配一個DATETIME或TIMESTAMP值,結果值的時間部分被刪除,因為DATE值未包含時間資訊。

· 記住儘管可以使用相同的格式指定DATETIME、DATE和TIMESTAMP值,不同型別的值的範圍卻不同。例如,TIMESTAMP值不能早於1970或晚於2037。這說明一個日期,例如'1968-01-01',雖然對於DATETIME或DATE值是有效的,但對於TIMESTAMP值卻無效,如果分配給這樣一個物件將被轉換為0。

當指定日期值時請注意某些缺陷:

·指定為字串的值允許的非嚴格格式可能會欺騙。例如,值'10:11:12'由於‘:’間割符看上去可能象時間值,但如果用於日期上下文值則被解釋為年'2010-11-12'。值'10:45:15'被轉換為'0000-00-00'因為'45'不是合法月。

·在非嚴格模式,MySQL伺服器只對日期的合法性進行基本檢查:年、月和日的範圍分別是1000到9999、00到12和00到31。任何包含超出這些範圍的部分的日期被轉換成'0000-00-00'。請注意仍然允許你儲存非法日期,例如'2002-04-31'。要想確保不使用嚴格模式時日期有效,應檢查應用程式。

在嚴格模式,非法日期不被接受,並且不轉換。


TIMESTAMP列的顯示格式與DATETIME列相同。換句話說,顯示寬度固定在19字元,並且格式為YYYY-MM-DD HH:MM:SS。

MySQL伺服器也可以以MAXDB模式執行。當伺服器以該模式執行時,TIMESTAMP與DATETIME相等。也就是說,如果建立表時伺服器以MAXDB模式執行,TIMESTAMP列建立為DATETIME列。結果是,該列使用DATETIME顯示格式,有相同的值範圍,並且沒有自動對當前的日期和時間進行初始化或更新。

要想啟用MAXDB模式,在啟動伺服器時使用--sql-mode=MAXDB伺服器選項或在執行時透過設定全域性sql_mode變數將SQL伺服器模式設定為MAXDB:

mysql> SET GLOBAL sql_mode=MAXDB;
客戶端可以按照下面方法讓伺服器為它的連線以MAXDB模式執行:

mysql> SET SESSION sql_mode=MAXDB;
 

MySQL不接受在日或月列包括一個零或包含非法日期值的時間戳值。該規則的唯一例外是特殊值'0000-00-00 00:00:00'。

你可以非常靈便地確定什麼時候初始化和更新TIMESTAMP和對哪些列進行初始化和更新:

·你可以將當前的時間戳指定為預設值和自動更新的值。但只能選擇一個,或者兩者都不選。(不可能一個列選擇一個行為而另一個列選擇另一個行為)。

·你可以指定哪個TIMESTAMP列自動初始化或更新為當前的日期和時間。不再需要為第1個TIMESTAMP列。

請注意下面討論所資訊只適用於建立時未啟用MAXDB模式的表的TIMESTAMP列。(如上所述,MAXDB模式使列建立為DATETIME列)。控制TIMESTAMP列的初始化和更新的規則如下所示:

·如果一個表內的第1個TIMESTAMP列指定為一個DEFAULT值,則不能忽略。 預設值可以為CURRENT_TIMESTAMP或常量日期和時間值。

· DEFAULT NULL與第1個TIMESTAMP 列的DEFAULT CURRENT_TIMESTAMP相同。對於其它TIMESTAMP列,DEFAULT NULL被視為DEFAULT 0。

·表內的任何一個TIMESTAMP列可以設定為自動初始化為當前時間戳和/或更新。

·在CREATE TABLE語句中,可以用下面的任何一種方式宣告第1個TIMESTAMP列:
. 用DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP子句,列為預設值使用當前的時間戳,並且自動更新。
.不使用DEFAULT或ON UPDATE子句,與DEFAULT CURRENT_TIMESTAMP ON UPDATECURRENT_TIMESTAMP相同。
. 用DEFAULT CURRENT_TIMESTAMP子句不用ON UPDATE子句,列為預設值使用當前的時間戳但是不自動更新。
. 不用DEFAULT子句但用ON UPDATE CURRENT_TIMESTAMP子句,列有預設值0並自動更新。
. 用常量DEFAULT值,列有給出的 預設值。如果列有一個ON UPDATE CURRENT_TIMESTAMP子句,它自動更新,否則不。

換句話說,你可以為初始值和自動更新的值使用當前的時間戳,或者其中一個使用,或者兩個皆不使用。(例如,你可以指定ON UPDATE來啟用自動更新而不讓列自動初始化)。
·在DEFAULT和ON UPDATE子句中可以使用CURRENT_TIMESTAMP、CURRENT_TIMESTAMP()或者NOW()。它們均具有相同的效果。

兩個屬性的順序並不重要。如果一個TIMESTAMP列同時指定了DEFAULT和ON UPDATE,任何一個可以在另一個的前面。
例子,下面這些語句是等效的:
CREATE TABLE t (ts TIMESTAMP);
CREATE TABLE t (ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                             ON UPDATE CURRENT_TIMESTAMP);
CREATE TABLE t (ts TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
                             DEFAULT CURRENT_TIMESTAMP);
· 要為TIMESTAMP列而不是第1列指定自動預設或更新,必須透過將第1個TIMESTAMP列顯式分配一個常量DEFAULT值來禁用自動初始化和更新。(例如,DEFAULT 0或DEFAULT'2003-01-01 00:00:00')。然後,對於其它TIMESTAMP列,規則與第1個TIMESTAMP列相同,例外情況是不能忽略DEFAULT和ON UPDATE子句。如果這樣做,則不會自動進行初始化或更新。

例如:下面這些語句是等效的:

CREATE TABLE t (
    ts1 TIMESTAMP DEFAULT 0,
    ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                  ON UPDATE CURRENT_TIMESTAMP);
CREATE TABLE t (
    ts1 TIMESTAMP DEFAULT 0,
    ts2 TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
                  DEFAULT CURRENT_TIMESTAMP);
可以對每個連線設定當前的時區,相關描述參見5.10.8節,“MySQL伺服器時區支援”。TIMESTAMP值以UTC格式儲存,儲存時對當前的時區進行轉換,檢索時再轉換回當前的時區。只要時區設定值為常量,便可以得到儲存時的值。如果儲存一個TIMESTAMP值,應更改時區然後檢索該值,它與你儲存的值不同。這是因為在兩個方向的轉換中沒有使用相同的時區。當前的時區可以用作time_zone系統變數的值。

可以在TIMESTAMP列的定義中包括NULL屬性以允許列包含NULL值。例如:
CREATE TABLE t
(
  ts1 TIMESTAMP NULL DEFAULT NULL,
  ts2 TIMESTAMP NULL DEFAULT 0,
  ts3 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
);
如果未指定NULL屬性,將列設定為NULL設定則會將它設定為當前的時間戳。請注意允許NULL值的TIMESTAMP列不會採用當前的時間戳,除非要麼其 預設值定義為CURRENT_TIMESTAMP,或者NOW()或CURRENT_TIMESTAMP被插入到該列內。換句話說,只有使用如下定義建立,定義為 NULL的TIMESTAMP列才會自動更新:

CREATE TABLE t (ts NULLDEFAULT CURRENT_TIMESTAMP);
否則-也就是說,如果使用NULL而不是DEFAULT TIMESTAMP來定義TIMESTAMP列,如下所示...

CREATE TABLE t1 (ts NULL DEFAULT NULL);
CREATE TABLE t2 (ts NULL DEFAULT '0000-00-00 00:00:00');
...則必須顯式插入一個對應當前日期和時間的值。例如:

INSERT INTO t1 VALUES (NOW());
INSERT INTO t2 VALUES (CURRENT_TIMESTAMP);

TIME型別

MySQL以'HH:MM:SS'格式檢索和顯示TIME值(或對於大的小時值採用'HHH:MM:SS'格式)。TIME值的範圍可以從'-838:59:59'到'838:59:59'。小時部分會因此大的原因是TIME型別不僅可以用於表示一天的時間(必須小於24小時),還可能為某個事件過去的時間或兩個事件之間的時間間隔(可以大於24小時,或者甚至為負)。
你可以用各種格式指定TIME值:

·'D HH:MM:SS.fraction'格式的字串。還可以使用下面任何一種“非嚴格”語法:'HH:MM:SS.fraction'、'HH:MM:SS'、'HH:MM'、'D HH:MM:SS'、'D HH:MM'、'D HH'或'SS'。這裡D表示日,可以取0到34之間的值。請注意MySQL還不儲存分數。

·'HHMMSS'格式的沒有間割符的字串,假定是有意義的時間。例如,'101112'被理解為'10:11:12',但'109712'是不合法的(它有一個沒有意義的分鐘部分),將變為'00:00:00'。

·HHMMSS格式的數值,假定是有意義的時間。例如,101112被理解為'10:11:12'。下面格式也可以理解:SS、MMSS、HHMMSS、HHMMSS.fraction。請注意MySQL還不儲存分數。

·函式返回的結果,其值適合TIME上下文,例如CURRENT_TIME。
  對於指定為包括時間部分間割符的字串的TIME值,如果時、分或者秒值小於10,則不需要指定兩位數。'8:3:2'與'08:03:02'相同。
為TIME列分配簡寫值時應注意。沒有冒號,MySQL解釋值時假定最右邊的兩位表示秒。(MySQL解釋TIME值為過去的時間而不是當天的時間)。例如,你可能認為'1112'和1112表示'11:12:00'(11點過12分),但MySQL將它們解釋為'00:11:12'(11分,12 秒)。同樣,'12'和12 被解釋為 '00:00:12'。相反,TIME值中使用冒號則肯定被看作當天的時間。也就是說,'11:12'表示'11:12:00',而不是'00:11:12'。
超出TIME範圍但合法的值被裁為範圍最接近的端點。例如,'-850:00:00'和'850:00:00'被轉換為'-838:59:59'和'838:59:59'。
無效TIME值被轉換為'00:00:00'。請注意由於'00:00:00'本身是一個合法TIME值,只從表內儲存的一個'00:00:00'值還不能說出原來的值是 '00:00:00'還是不合法的值。

YEAR型別
YEAR型別是一個單位元組型別用於表示年。

MySQL以YYYY格式檢索和顯示YEAR值。範圍是1901到2155。

可以指定各種格式的YEAR值:

·四位字串,範圍為'1901'到'2155'。

·四位數字,範圍為1901到2155。

·兩位字串,範圍為'00'到'99'。'00'到'69'和'70'到'99'範圍的值被轉換為2000到2069和1970到1999範圍的YEAR值。

· 兩位整數,範圍為1到99。1到69和70到99範圍的值被轉換為2001到2069和1970到1999範圍的YEAR值。請注意兩位整數範圍與兩位字串範圍稍有不同,因為你不能直接將零指定為數字並將它解釋為2000。你必須將它指定為一個字串'0'或'00'或它被解釋為0000。

· 函式返回的結果,其值適合YEAR上下文,例如NOW()。

非法YEAR值被轉換為0000。

 

mysql> create table t (d date, t time ,dt datetime );
Query OK, 0 rows affected (0.01 sec)

mysql> desc t;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| d     | date     | YES  |     | NULL    |       |
| t     | time     | YES  |     | NULL    |       |
| dt    | datetime | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.02 sec)

mysql> insert into t values (now(),now(),now());
Query OK, 1 row affected (0.00 sec)

mysql> select * from t;
+------------+----------+---------------------+
| d          | t        | dt                  |
+------------+----------+---------------------+
| 2011-01-01 | 07:55:56 | 2011-01-01 07:55:56 |
+------------+----------+---------------------+
1 row in set (0.00 sec)

mysql> show create table t \G;
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE `t` (
  `d` date default NULL,
  `t` time default NULL,
  `dt` datetime default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

ERROR:
No query specified

mysql> create test (id1 timestamp);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'test (id1 timestamp)' at line 1
mysql> create table  test (id1 timestamp);
Query OK, 0 rows affected (0.02 sec)

mysql> desc test;
+-------+-----------+------+-----+-------------------+-------+
| Field | Type      | Null | Key | Default           | Extra |
+-------+-----------+------+-----+-------------------+-------+
| id1   | timestamp | YES  |     | CURRENT_TIMESTAMP |       |
+-------+-----------+------+-----+-------------------+-------+
1 row in set (0.00 sec)

mysql> insert into tset value (nul);
ERROR 1146 (42S02): Table 'test.tset' doesn't exist
mysql> insert into tset value (null);
ERROR 1146 (42S02): Table 'test.tset' doesn't exist
mysql> insert into test values (null);
Query OK, 1 row affected (0.00 sec)

mysql> select id1 from test;
+---------------------+
| id1                 |
+---------------------+
| 2011-01-01 08:00:43 |
+---------------------+
1 row in set (0.00 sec)

mysql> alter table test  add id2 timestamp;
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> show create table test \G;
*************************** 1. row ***************************
       Table: test
Create Table: CREATE TABLE `test` (
  `id1` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  `id2` timestamp NOT NULL default '0000-00-00 00:00:00'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

ERROR:
No query specified

mysql> alter table test modify id2 timestamp default current_timestamp;
ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
mysql> alter table test modify id2 datetime default null;
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> desc test;
+-------+-----------+------+-----+-------------------+-------+
| Field | Type      | Null | Key | Default           | Extra |
+-------+-----------+------+-----+-------------------+-------+
| id1   | timestamp | YES  |     | CURRENT_TIMESTAMP |       |
| id2   | datetime  | YES  |     | NULL              |       |
+-------+-----------+------+-----+-------------------+-------+
2 rows in set (0.01 sec)

mysql> show variables like 'time_zone';
+---------------+--------+
| Variable_name | Value  |
+---------------+--------+
| time_zone     | SYSTEM |
+---------------+--------+
1 row in set (0.01 sec)

mysql> select id1,id2 from test;
+---------------------+---------------------+
| id1                 | id2                 |
+---------------------+---------------------+
| 2011-01-01 08:00:43 | 0000-00-00 00:00:00 |
+---------------------+---------------------+
1 row in set (0.01 sec)

mysql> insert into test values (now(),now());
Query OK, 1 row affected (0.00 sec)

mysql> select id1,id2 from test;
+---------------------+---------------------+
| id1                 | id2                 |
+---------------------+---------------------+
| 2011-01-01 08:00:43 | 0000-00-00 00:00:00 |
| 2011-01-01 08:05:51 | 2011-01-01 08:05:51 |
+---------------------+---------------------+
2 rows in set (0.00 sec)

mysql> set time_zone ='+10:00';
Query OK, 0 rows affected (0.03 sec)

mysql> select id1,id2 from test;
+---------------------+---------------------+
| id1                 | id2                 |
+---------------------+---------------------+
| 2011-01-01 10:00:43 | 0000-00-00 00:00:00 |
| 2011-01-01 10:05:51 | 2011-01-01 08:05:51 |
+---------------------+---------------------+
2 rows in set (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> drop table  t;
Query OK, 0 rows affected (0.00 sec)

mysql> create table t (ts timsstamp);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'timsstamp)' at line 1
mysql> create table t (ts timestamp);
Query OK, 0 rows affected (0.02 sec)

mysql> desc t;
+-------+-----------+------+-----+-------------------+-------+
| Field | Type      | Null | Key | Default           | Extra |
+-------+-----------+------+-----+-------------------+-------+
| ts    | timestamp | YES  |     | CURRENT_TIMESTAMP |       |
+-------+-----------+------+-----+-------------------+-------+
1 row in set (0.00 sec)

mysql> insert into t values (19700101080001);
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select ts from t;
+---------------------+
| ts                  |
+---------------------+
| 0000-00-00 00:00:00 |
+---------------------+
1 row in set (0.00 sec)

mysql> set time_zone ='+08:00';
Query OK, 0 rows affected (0.01 sec)

mysql> select ts from t;
+---------------------+
| ts                  |
+---------------------+
| 0000-00-00 00:00:00 |
+---------------------+
1 row in set (0.00 sec)

mysql> delete from t;
Query OK, 1 row affected (0.00 sec)

mysql> insert into t values (19700101080001);
Query OK, 1 row affected (0.00 sec)

mysql> select ts from t;
+---------------------+
| ts                  |
+---------------------+
| 1970-01-01 08:00:01 |
+---------------------+
1 row in set (0.01 sec)

mysql> insert into t values (19700101080000);
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select ts from t;
+---------------------+
| ts                  |
+---------------------+
| 1970-01-01 08:00:01 |
| 0000-00-00 00:00:00 |
+---------------------+
2 rows in set (0.01 sec)

mysql> insert into t values ('2038-01-19 11:14:07');
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> select ts from t;
+---------------------+
| ts                  |
+---------------------+
| 1970-01-01 08:00:01 |
| 0000-00-00 00:00:00 |
| 0000-00-00 00:00:00 |
+---------------------+
3 rows in set (0.00 sec)

mysql> insert into t values ('2038-01-19 08:14:07');
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> select ts from t;
+---------------------+
| ts                  |
+---------------------+
| 1970-01-01 08:00:01 |
| 0000-00-00 00:00:00 |
| 0000-00-00 00:00:00 |
| 0000-00-00 00:00:00 |
+---------------------+
4 rows in set (0.00 sec)

mysql> insert into t values ('2038-01-01 08:14:07');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select ts from t;
+---------------------+
| ts                  |
+---------------------+
| 1970-01-01 08:00:01 |
| 0000-00-00 00:00:00 |
| 0000-00-00 00:00:00 |
| 0000-00-00 00:00:00 |
| 0000-00-00 00:00:00 |
+---------------------+
5 rows in set (0.00 sec)

--
mysql> create table t (dt datetime);
Query OK, 0 rows affected (0.01 sec)

mysql> insert into t values ('2007:9:3 12-10-03');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t values ('2007-9-3 12+10+03');
Query OK, 1 row affected (0.01 sec)

mysql> insert into t values (20070903121003);
Query OK, 1 row affected (0.00 sec)

mysql> select dt from t;
+---------------------+
| dt                  |
+---------------------+
| 2007-09-03 12:10:03 |
| 2007-09-03 12:10:03 |
| 2007-09-03 12:10:03 |
+---------------------+
3 rows in set (0.01 sec)

Y2K事宜和日期型別
MySQL本身對於2000年(Y2K)是安全的(參見1.4.5節,“2000年相容性”),但輸入給MySQL的值可能不安全。任何包含兩位年值的輸入都會令人模糊,因為世紀不知道。這些值必須解釋為四位形式,因為MySQL內部使用四位來儲存年。
對於DATETIME、DATE、TIMESTAMP和YEAR型別,MySQL使用以下規則解釋含模糊年值的日期:
·00-69範圍的年值轉換為2000-2069。
·70-99範圍的年值轉換為1970-1999。

請記住這些規則只是合理猜測資料值表示什麼。如果MySQL使用的啟發不能產生正確的值,你應提供包含四位年值的確切輸入。
ORDER BY可以正確排序有兩位年的TIMESTAMP或YEAR值。
部分函式如MIN()和MAX()將TIMESTAMP或YEAR轉換為一個數字。這說明使用有兩位年值的值,這些函式不能工作正確。在這種情況下的修復方法是將TIMESTAMP或YEAR轉換為四位年格式或使用MIN(DATE_ADD(TIMESTAMP,INTERVAL 0 DAYS))。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22664653/viewspace-683136/,如需轉載,請註明出處,否則將追究法律責任。

相關文章