日期和时间值可以以多种格式表示,例如带引号的字符串或数字,具体取决于值的类型和其他因素。例如,在 MySQL 期望日期的上下文中,它将 '2015-07-21'
、'20150721'
和 20150721
解释为日期。
本节描述日期和时间字面量的可接受格式。有关时间数据类型的更多信息,例如允许值的范围,请参阅 第 13.2 节,“日期和时间数据类型”。
标准 SQL 要求使用类型关键字和字符串指定时间字面量。关键字和字符串之间的空格是可选的。
DATE 'str'
TIME 'str'
TIMESTAMP 'str'
MySQL 识别但不需要类型关键字,标准 SQL 需要类型关键字。为了符合标准,应用程序应该在时间字面量中包含类型关键字。
MySQL 还识别对应于标准 SQL 语法的 ODBC 语法:
{ d 'str' }
{ t 'str' }
{ ts 'str' }
MySQL 使用类型关键字和 ODBC 构造来生成 DATE
、TIME
和 DATETIME
值,包括可选的尾随小数秒部分。如果指定了小数秒部分。TIMESTAMP 语法在 MySQL 中生成 DATETIME
值,因为 DATETIME
的范围更接近标准 SQL TIMESTAMP
类型,其年份范围从 0001
到 9999
。(MySQL 的 TIMESTAMP
年份范围是 1970
到 2038
。)
MySQL 识别 DATE
值在以下格式中:
-
作为字符串,以
'
或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)
-
作为字符串,无分隔符,以
'
或YYYYMMDD
''
格式,前提是字符串作为日期是有意义的。例如,YYMMDD
''20070523'
和'070523'
被解释为'2007-05-23'
,但'071332'
是非法的(它有非法的月份和日部分)并变为'0000-00-00'
。 -
作为一个数字,采用
YYYYMMDD
或YYMMDD
格式,前提是该数字作为日期是有意义的。例如,19830905
和830905
被解释为'1983-09-05'
。
MySQL 识别 DATETIME
和 TIMESTAMP
值在以下格式中:
-
作为一个字符串,采用
'
或YYYY-MM-DD hh:mm:ss
''
格式。MySQL 也允许在这里使用“松散”语法,尽管这已经弃用:任何标点符号都可以用作日期部分或时间部分之间的分隔符。例如,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.3 中,这种行为已经弃用,并且空白字符的存在将触发警告,如下所示: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'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)
-
作为一个字符串,采用
'
或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 中小数秒支持的信息,请参阅 第 13.2.6 节,“时间值中的小数秒”。
包含两个数字年份值的日期是模糊的,因为世纪是未知的。MySQL 使用以下规则来解释两个数字年份值:
-
年份值在
70-99
范围内变为1970-1999
。 -
年份值在
00-69
范围内变为2000-2069
。
另请参阅 第 13.2.9 节,“日期中的两位年份”。
对于指定为字符串的值,包括日期部分分隔符,在月份或日份小于 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'
99
和03
'1999-03-00'
'990300'
。
MySQL识别
TIME
值以下格式:
-
作为字符串在
'D hh:mm:ss'
格式中。你也可以使用以下“relaxed”语法:'hh:mm:ss'
、'hh:mm'
、'D hh:mm'
、'D hh'
或'ss'
。这里D
表示天数,可以从0到34。 -
作为无分隔符的字符串在
'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中小数秒支持的信息,请参阅第13.2.6节,“时间值中的小数秒”。
对于以字符串形式指定的 TIME
值,如果包括时间部分分隔符,那么对于小时、分钟或秒钟值小于 10
的情况,不需要指定两个数字。例如 '8:3:2'
等同于 '08:03:02'
。
在将 TIMESTAMP
和 DATETIME
值插入表中时,可以指定时区偏移量。偏移量附加到 datetime 字面量的时间部分,中间没有空格,使用与设置 time_zone
系统变量相同的格式,以下是例外情况:
-
对于小时值小于 10,需要前导零。
-
值
'-00:00'
将被拒绝。 -
时区名称,如
'EET'
和'Asia/Shanghai'
不能使用;'SYSTEM'
也不能在此上下文中使用。
插入的值不得具有零的月份部分、日部分或两者。无论服务器 SQL 模式设置如何,这都是强制执行的。
以下示例说明了使用不同 time_zone
设置将 datetime 值与时区偏移量插入到 TIMESTAMP
和 DATETIME
列中,然后检索它们:
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 |
+---------------------+---------------------+
即使在插入时使用了偏移量,选择 datetime 值时也不会显示偏移量。
支持的偏移值范围是 -13:59
到 +14:00
,包括两者。
包括时区偏移量的 datetime 字面量可以作为参数值被预备语句接受。