DATE
、DATETIME
和 TIMESTAMP
类型是相关的。本节介绍它们的特征、相似之处和区别。MySQL 识别多种格式的 DATE
、DATETIME
和 TIMESTAMP
值,如 第 11.1.3 节“日期和时间文字” 中所述。对于 DATE
和 DATETIME
范围描述,““支持”” 表示虽然较早的值可能有效,但不能保证。
DATE
类型用于具有日期部分但没有时间部分的值。MySQL 以 '
格式检索和显示 YYYY-MM-DD
'DATE
值。支持的范围是从 '1000-01-01'
到 '9999-12-31'
。
DATETIME
类型用于包含日期和时间部分的值。MySQL 以 '
格式检索和显示 YYYY-MM-DD hh:mm:ss
'DATETIME
值。支持的范围是从 '1000-01-01 00:00:00'
到 '9999-12-31 23:59:59'
。
TIMESTAMP
数据类型用于包含日期和时间部分的值。TIMESTAMP
的范围是从 UTC 时间 '1970-01-01 00:00:01'
到 '2038-01-19 03:14:07'
。
DATETIME
或 TIMESTAMP
值可以包含一个尾随的小数秒部分,精度最高为微秒(6 位数字)。特别是,插入到 DATETIME
或 TIMESTAMP
列中的值中的任何小数部分都会被存储,而不是被丢弃。包含小数部分后,这些值的格式为 '
,YYYY-MM-DD hh:mm:ss
[.fraction
]'DATETIME
值的范围是从 '1000-01-01 00:00:00.000000'
到 '9999-12-31 23:59:59.499999'
,TIMESTAMP
值的范围是从 '1970-01-01 00:00:01.000000'
到 '2038-01-19 03:14:07.499999'
。小数部分应始终用小数点与时间的其余部分分开;不识别任何其他小数秒分隔符。有关 MySQL 中小数秒支持的信息,请参见 第 13.2.6 节“时间值中的小数秒”。
TIMESTAMP
和 DATETIME
数据类型提供自动初始化和更新为当前日期和时间。有关更多信息,请参见 第 13.2.5 节“TIMESTAMP 和 DATETIME 的自动初始化和更新”。
MySQL 在存储时将 TIMESTAMP
值从当前时区转换为 UTC,并在检索时从 UTC 转换回当前时区。(这不会发生在其他类型上,例如 DATETIME
。)默认情况下,每个连接的当前时区是服务器的时间。可以为每个连接设置时区。只要时区设置保持不变,您就会得到与存储的值相同的值。如果您存储一个 TIMESTAMP
值,然后更改时区并检索该值,则检索到的值将与存储的值不同。发生这种情况是因为在两个方向上都没有使用相同的时区进行转换。当前时区可用作 time_zone
系统变量的值。有关更多信息,请参见 第 7.1.15 节“MySQL 服务器时区支持”。
将 TIMESTAMP
或 DATETIME
值插入表时,可以指定时区偏移量。有关更多信息和示例,请参见 第 11.1.3 节“日期和时间文字”。
如果 SQL 模式允许,无效的 DATE
、DATETIME
或 TIMESTAMP
值将转换为相应类型的““零””值('0000-00-00'
或 '0000-00-00 00:00:00'
)。确切行为取决于是否启用了严格 SQL 模式和 NO_ZERO_DATE
SQL 模式;请参见 第 7.1.11 节“服务器 SQL 模式”。
您可以使用 CAST()
和 AT TIME ZONE
运算符检索 TIMESTAMP
值时,将它们转换为 UTC DATETIME
值,如下所示
mysql> SELECT col,
> CAST(col AT TIME ZONE INTERVAL '+00:00' AS DATETIME) AS ut
> FROM ts ORDER BY id;
+---------------------+---------------------+
| col | ut |
+---------------------+---------------------+
| 2020-01-01 10:10:10 | 2020-01-01 15:10:10 |
| 2019-12-31 23:40:10 | 2020-01-01 04:40:10 |
| 2020-01-01 13:10:10 | 2020-01-01 18:10:10 |
| 2020-01-01 10:10:10 | 2020-01-01 15:10:10 |
| 2020-01-01 04:40:10 | 2020-01-01 09:40:10 |
| 2020-01-01 18:10:10 | 2020-01-01 23:10:10 |
+---------------------+---------------------+
有关语法和更多示例的完整信息,请参见 CAST()
函数的描述。
请注意 MySQL 中日期值解释的某些属性
对于指定为字符串的值,MySQL 允许使用““宽松””格式,其中任何标点符号都可以用作日期部分或时间部分之间的分隔符。在某些情况下,这种语法可能会产生误导。例如,像
'10:11:12'
这样的值由于带有:
,看起来像一个时间值,但如果在日期上下文中使用,则会被解释为年份'2010-11-12'
。值'10:45:15'
将转换为'0000-00-00'
,因为'45'
不是有效的月份。日期和时间部分与小数秒部分之间唯一识别的分隔符是小数点。
服务器要求月份和日期值有效,而不仅仅是在 1 到 12 和 1 到 31 的范围内。如果禁用了严格模式,则无效日期(例如
'2004-04-31'
)将转换为'0000-00-00'
,并生成警告。如果启用了严格模式,则无效日期会生成错误。要允许此类日期,请启用ALLOW_INVALID_DATES
。有关更多信息,请参见 第 7.1.11 节“服务器 SQL 模式”。MySQL 不接受在日期或月份列中包含零的
TIMESTAMP
值,也不接受不是有效日期的值。此规则的唯一例外是特殊的““零””值'0000-00-00 00:00:00'
,如果 SQL 模式允许此值的话。确切行为取决于是否启用了严格 SQL 模式和NO_ZERO_DATE
SQL 模式;请参见 第 7.1.11 节“服务器 SQL 模式”。包含两位数年份值的日期不明确,因为世纪未知。MySQL 使用以下规则解释两位数年份值
00-69
范围内的年份值将变为2000-2069
。70-99
范围内的年份值将变为1970-1999
。
另请参见 第 13.2.9 节“日期中的两位数年份”。