日期和时间值可以用多种格式表示,例如带引号的字符串或数字,具体取决于值的确切类型和其他因素。例如,在 MySQL 需要日期的上下文中,它将 、 和 中的任何一个解释
'2015-07-21'
为'20150721'
日期20150721
。
本节介绍日期和时间文字可接受的格式。有关时间数据类型的更多信息,例如允许值的范围,请参阅 第 11.2 节,“日期和时间数据类型”。
标准 SQL 需要使用类型关键字和字符串指定时间文字。关键字和字符串之间的空格是可选的。
DATE 'str'
TIME 'str'
TIMESTAMP 'str'
MySQL 可以识别,但与标准 SQL 不同,它不需要 type 关键字。符合标准的应用程序应该包括时间文字的类型关键字。
MySQL 还识别与标准 SQL 语法相对应的 ODBC 语法:
{ d 'str' }
{ t 'str' }
{ ts 'str' }
MySQL 使用类型关键字和 ODBC 构造分别生成DATE
、
TIME
和
DATETIME
值,如果指定,包括尾随的小数秒部分。该
TIMESTAMP
语法
DATETIME
在 MySQL 中生成一个值,因为
DATETIME
其范围更接近于标准 SQL
TIMESTAMP
类型,其年份范围从0001
到
9999
. (MySQL
TIMESTAMP
年份范围是
1970
到2038
。)
MySQL 识别DATE
这些格式的值:
作为 或 格式的字符串。允许使用“宽松”语法,但不推荐使用:任何标点符号都可以用作日期部分之间的分隔符。例如, 、 、 和 是等价的。从 MySQL 8.0.29 开始,使用破折号 () 以外的任何字符作为分隔符都会引发警告,如下所示:
'
YYYY-MM-DD
''
YY-MM-DD
''2012-12-31'
'2012/12/31'
'2012^12^31'
'2012@12@31'
-
mysql> SELECT DATE'2012@12@31'; +------------------+ | DATE'2012@12@31' | +------------------+ | 2012-12-31 | +------------------+ 1 row in set, 1 warning (0.00 sec) mysql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Warning Code: 4095 Message: Delimiter '@' in position 4 in datetime value '2012@12@31' at row 1 is deprecated. Prefer the standard '-'. 1 row in set (0.00 sec)
作为在 或 格式中都没有定界符的字符串,前提是该字符串作为日期有意义。例如,and 被解释为 ,但 它是非法的(它有无意义的月和日部分)并变为 。
'
YYYYMMDD
''
YYMMDD
''20070523'
'070523'
'2007-05-23'
'071332'
'0000-00-00'
作为
YYYYMMDD
或YYMMDD
格式的数字,前提是该数字作为日期有意义。例如,19830905
和830905
被解释为'1983-09-05'
。
MySQL以这些格式
识别DATETIME
和
值:TIMESTAMP
作为或 格式的字符串。MySQL 在这里也允许使用“宽松的”语法,尽管这已被弃用:任何标点符号都可以用作日期部分或时间部分之间的分隔符。例如,、 、 和 是等价的。从 MySQL 8.0.29 开始,在此类值中使用任何字符作为分隔符(日期部分的破折号 ( ) 和时间部分的冒号 ( ) 除外)会引发警告,如下所示:
'
YYYY-MM-DD hh:mm:ss
''
YY-MM-DD hh:mm:ss
''2012-12-31 11:30:45'
'2012^12^31 11+30+45'
'2012/12/31 11*30*45'
'2012@12@31 11^30^45'
-
:
mysql> SELECT TIMESTAMP'2012^12^31 11*30*45'; +--------------------------------+ | TIMESTAMP'2012^12^31 11*30*45' | +--------------------------------+ | 2012-12-31 11:30:45 | +--------------------------------+ 1 row in set, 1 warning (0.00 sec) mysql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Warning Code: 4095 Message: Delimiter '^' in position 4 in datetime value '2012^12^31 11*30*45' at row 1 is deprecated. Prefer the standard '-'. 1 row in set (0.00 sec)
日期和时间部分与小数秒部分之间唯一可识别的分隔符是小数点。
日期和时间部分可以用
T
空格而不是空格分隔。例如,'2012-12-31 11:30:45'
'2012-12-31T11:30:45'
是等价的。以前,MySQL 支持日期和时间值中任意数量的前导和尾随空白字符,以及在
DATETIME
和TIMESTAMP
值的日期和时间部分之间。在 MySQL 8.0.29 及更高版本中,不推荐使用此行为,并且存在过多的空白字符会触发警告,如下所示:mysql> SELECT TIMESTAMP'2012-12-31 11-30-45'; +----------------------------------+ | TIMESTAMP'2012-12-31 11-30-45' | +----------------------------------+ | 2012-12-31 11:30:45 | +----------------------------------+ 1 row in set, 1 warning (0.00 sec) mysql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Warning Code: 4096 Message: Delimiter ' ' in position 11 in datetime value '2012-12-31 11-30-45' at row 1 is superfluous and is deprecated. Please remove. 1 row in set (0.00 sec)
同样从 MySQL 8.0.29 开始,当使用空格字符以外的空白字符时会引发警告,如下所示:
mysql> SELECT TIMESTAMP'2021-06-06 '> 11:15:25'; +--------------------------------+ | TIMESTAMP'2021-06-06 11:15:25' | +--------------------------------+ | 2021-06-06 11:15:25 | +--------------------------------+ 1 row in set, 1 warning (0.00 sec) mysql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Warning Code: 4095 Message: Delimiter '\n' in position 10 in datetime value '2021-06-06 11:15:25' at row 1 is deprecated. Prefer the standard ' '. 1 row in set (0.00 sec)
每个时间值仅引发一个此类警告,即使分隔符、空格或两者可能存在多个问题,如以下一系列语句所示:
mysql> SELECT TIMESTAMP'2012!-12-31 11:30:45'; +----------------------------------+ | TIMESTAMP'2012!-12-31 11:30:45' | +----------------------------------+ | 2012-12-31 11:30:45 | +----------------------------------+ 1 row in set, 1 warning (0.00 sec) mysql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Warning Code: 4095 Message: Delimiter '!' in position 4 in datetime value '2012!-12-31 11:30:45' at row 1 is deprecated. Prefer the standard '-'. 1 row in set (0.00 sec) mysql> SELECT TIMESTAMP'2012-12-31 11:30:45'; +---------------------------------+ | TIMESTAMP'2012-12-31 11:30:45' | +---------------------------------+ | 2012-12-31 11:30:45 | +---------------------------------+ 1 row in set, 1 warning (0.00 sec) mysql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Warning Code: 4096 Message: Delimiter ' ' in position 11 in datetime value '2012-12-31 11:30:45' at row 1 is superfluous and is deprecated. Please remove. 1 row in set (0.00 sec) mysql> SELECT TIMESTAMP'2012-12-31 11:30:45'; +--------------------------------+ | TIMESTAMP'2012-12-31 11:30:45' | +--------------------------------+ | 2012-12-31 11:30:45 | +--------------------------------+ 1 row in set (0.00 sec)
作为在 或 格式中都没有定界符的字符串,前提是该字符串作为日期有意义。例如,and 被解释为 ,但 它是非法的(它有一个无意义的微小部分)并变为。
'
YYYYMMDDhhmmss
''
YYMMDDhhmmss
''20070523091528'
'070523091528'
'2007-05-23 09:15:28'
'071122129015'
'0000-00-00 00:00:00'
作为
YYYYMMDDhhmmss
或YYMMDDhhmmss
格式的数字,前提是该数字作为日期有意义。例如,19830905132800
和830905132800
被解释为'1983-09-05 13:28:00'
。
DATETIME
或
值可以包含
一个TIMESTAMP
尾随小数秒部分,精度可达微秒(6 位)。小数部分应始终用小数点与其余时间分开;不识别其他小数秒定界符。有关 MySQL 中小数秒支持的信息,请参阅
第 11.2.6 节,“时间值中的小数秒”。
包含两位数年份值的日期是不明确的,因为世纪是未知的。MySQL 使用这些规则解释两位数的年份值:
范围内的年份值
70-99
变为1970-1999
.范围内的年份值
00-69
变为2000-2069
.
对于指定为包含日期部分定界符的字符串的值,不必为小于 的月或日值指定两位数10
。
'2015-6-9'
与 相同
'2015-06-09'
。同样,对于指定为包含时间部分分隔符的字符串的值,不必为小于 的小时、分钟或秒值指定两位数10
。
'2015-10-30 1:2:3'
与 相同
'2015-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
,但是天部分完全丢失了。但是,您可以明确指定零值来表示缺少的月份或日期部分。例如,要插入值'1999-03-00'
,请使用
'990300'
。
MySQL 识别TIME
这些格式的值:
作为
'D hh:mm:ss'
格式的字符串。您还可以使用以下 “宽松”语法 之一:'hh:mm:ss'
、、、、 或。这里 代表天,可以有一个从 0 到 34 的值。'hh:mm'
'D hh:mm'
'D hh'
'ss'
D
作为
'hhmmss'
格式中没有分隔符的字符串,前提是它作为时间有意义。例如,'101112'
被理解为'10:11:12'
,但'109712'
它是非法的(它有一个无意义的微小部分)并变成'00:00:00'
。作为
hhmmss
格式中的数字,前提是它作为时间有意义。例如,101112
被理解为'10:11:12'
。还可以理解以下替代格式:ss
,mmss
, 或hhmmss
.
尾随小数秒部分以
'D hh:mm:ss.fraction'
、
'hh:mm:ss.fraction'
、
'hhmmss.fraction'
和
hhmmss.fraction
时间格式识别,其中
fraction
小数部分最高可达微秒(6 位)精度。小数部分应始终用小数点与其余时间分开;不识别其他小数秒定界符。有关 MySQL 中小数秒支持的信息,请参阅
第 11.2.6 节,“时间值中的小数秒”。
对于TIME
指定为包含时间部分定界符的字符串的值,无需为小于 的小时、分钟或秒值指定两位数10
。
'8:3:2'
与 相同
'08:03:02'
。
TIMESTAMP
从 MySQL 8.0.19 开始,您可以在向表中
插入DATETIME
值
时指定时区偏移量。偏移量附加到日期时间文字的时间部分,中间没有空格,并使用与设置time_zone
系统变量相同的格式,但有以下例外:
对于小于 10 的小时值,需要前导零。
该值
'-00:00'
被拒绝。不能使用
'EET'
和 等时区名称;也不能在这种情况下使用。'Asia/Shanghai'
'SYSTEM'
插入的值的月份部分、日期部分或这两个部分不得为零。这是从 MySQL 8.0.22 开始强制执行的,无论服务器 SQL 模式设置如何。
此示例说明使用不同的设置将带有时区偏移的日期时间值插入到TIMESTAMP
和
DATETIME
列中
time_zone
,然后检索它们:
mysql> CREATE TABLE ts (
-> id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> col TIMESTAMP NOT NULL
-> ) AUTO_INCREMENT = 1;
mysql> CREATE TABLE dt (
-> id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> col DATETIME NOT NULL
-> ) AUTO_INCREMENT = 1;
mysql> SET @@time_zone = 'SYSTEM';
mysql> INSERT INTO ts (col) VALUES ('2020-01-01 10:10:10'),
-> ('2020-01-01 10:10:10+05:30'), ('2020-01-01 10:10:10-08:00');
mysql> SET @@time_zone = '+00:00';
mysql> INSERT INTO ts (col) VALUES ('2020-01-01 10:10:10'),
-> ('2020-01-01 10:10:10+05:30'), ('2020-01-01 10:10:10-08:00');
mysql> SET @@time_zone = 'SYSTEM';
mysql> INSERT INTO dt (col) VALUES ('2020-01-01 10:10:10'),
-> ('2020-01-01 10:10:10+05:30'), ('2020-01-01 10:10:10-08:00');
mysql> SET @@time_zone = '+00:00';
mysql> INSERT INTO dt (col) VALUES ('2020-01-01 10:10:10'),
-> ('2020-01-01 10:10:10+05:30'), ('2020-01-01 10:10:10-08:00');
mysql> SET @@time_zone = 'SYSTEM';
mysql> SELECT @@system_time_zone;
+--------------------+
| @@system_time_zone |
+--------------------+
| EST |
+--------------------+
mysql> SELECT col, UNIX_TIMESTAMP(col) FROM dt ORDER BY id;
+---------------------+---------------------+
| col | UNIX_TIMESTAMP(col) |
+---------------------+---------------------+
| 2020-01-01 10:10:10 | 1577891410 |
| 2019-12-31 23:40:10 | 1577853610 |
| 2020-01-01 13:10:10 | 1577902210 |
| 2020-01-01 10:10:10 | 1577891410 |
| 2020-01-01 04:40:10 | 1577871610 |
| 2020-01-01 18:10:10 | 1577920210 |
+---------------------+---------------------+
mysql> SELECT col, UNIX_TIMESTAMP(col) FROM ts ORDER BY id;
+---------------------+---------------------+
| col | UNIX_TIMESTAMP(col) |
+---------------------+---------------------+
| 2020-01-01 10:10:10 | 1577891410 |
| 2019-12-31 23:40:10 | 1577853610 |
| 2020-01-01 13:10:10 | 1577902210 |
| 2020-01-01 05:10:10 | 1577873410 |
| 2019-12-31 23:40:10 | 1577853610 |
| 2020-01-01 13:10:10 | 1577902210 |
+---------------------+---------------------+
选择日期时间值时不会显示偏移量,即使在插入时使用了偏移量也是如此。
支持的偏移值范围是
-13:59
到+14:00
,包括在内。
包含时区偏移量的日期时间文字被准备好的语句接受为参数值。