用于表示时间值的日期和时间数据类型有 DATE
、TIME
、DATETIME
、TIMESTAMP
和 YEAR
。每种时间类型都有一个有效值范围,以及一个当您指定 MySQL 无法表示的无效值时可以使用的 “零” 值。TIMESTAMP
和 DATETIME
类型具有特殊的自动更新行为,如 第 13.2.5 节“TIMESTAMP 和 DATETIME 的自动初始化和更新” 中所述。
有关时间数据类型的存储需求信息,请参见 第 13.7 节“数据类型存储需求”。
有关对时间值进行操作的函数的说明,请参见 第 14.7 节“日期和时间函数”。
在使用日期和时间类型时,请牢记以下一般注意事项
MySQL 以标准输出格式检索给定日期或时间类型的值,但它会尝试解释您提供的输入值的各种格式(例如,当您指定要分配给日期或时间类型或与之比较的值时)。有关日期和时间类型的允许格式的说明,请参见 第 11.1.3 节“日期和时间文字”。预计您提供的值是有效的。如果您使用其他格式的值,可能会出现不可预知的结果。
尽管 MySQL 尝试解释几种格式的值,但日期部分必须始终按年-月-日顺序给出(例如,
'98-09-04'
),而不是其他地方常用的月-日-年或日-月-年顺序(例如,'09-04-98'
、'04-09-98'
)。要将其他顺序的字符串转换为年-月-日顺序,STR_TO_DATE()
函数可能会有用。包含两位数年份值的日期不明确,因为世纪未知。MySQL 使用以下规则解释两位数年份值
70-99
范围内的年份值变为1970-1999
。00-69
范围内的年份值变为2000-2069
。
另请参见 第 13.2.9 节“日期中的两位数年份”。
从一种时间类型到另一种时间类型的转换根据 第 13.2.8 节“日期和时间类型之间的转换” 中的规则进行。
如果日期或时间值在数值上下文中使用,MySQL 会自动将其转换为数字,反之亦然。
默认情况下,当 MySQL 遇到日期或时间类型的值超出范围或对该类型无效时,它会将该值转换为该类型的 “零” 值。例外情况是,超出范围的
TIME
值会被截断为TIME
范围的相应端点。通过将 SQL 模式设置为适当的值,您可以更准确地指定您希望 MySQL 支持哪种日期。(请参阅 第 7.1.11 节“服务器 SQL 模式”。)您可以通过启用
ALLOW_INVALID_DATES
SQL 模式来使 MySQL 接受某些日期,例如'2009-11-31'
。当您想将用户指定(例如,在 Web 表单中)的 “可能错误的” 值存储在数据库中以供将来处理时,这很有用。在此模式下,MySQL 仅验证月份是否在 1 到 12 的范围内,以及日期是否在 1 到 31 的范围内。MySQL 允许您在
DATE
或DATETIME
列中存储日期为零或月份和日期为零的日期。这对于需要存储您可能不知道确切日期的出生日期的应用程序很有用。在这种情况下,您只需将日期存储为'2009-00-00'
或'2009-01-00'
。但是,对于此类日期,您不应期望对需要完整日期的函数(例如DATE_SUB()
或DATE_ADD()
)获得正确的结果。要禁止日期中的零月份或日期部分,请启用NO_ZERO_IN_DATE
模式。MySQL 允许您将
'0000-00-00'
的 “零” 值存储为 “虚拟日期”。 在某些情况下,这比使用NULL
值更方便,并且使用更少的数据和索引空间。要禁止'0000-00-00'
,请启用NO_ZERO_DATE
模式。通过 Connector/ODBC 使用的 “零” 日期或时间值会自动转换为
NULL
,因为 ODBC 无法处理此类值。
下表显示了每种类型的 “零” 值的格式。“零” 值很特殊,但您可以使用表中显示的值显式存储或引用它们。您也可以使用值 '0'
或 0
来实现这一点,这些值更容易编写。对于包含日期部分的时间类型(DATE
、DATETIME
和 TIMESTAMP
),使用这些值可能会产生警告或错误。确切的行为取决于是否启用了严格模式和 NO_ZERO_DATE
SQL 模式;请参阅 第 7.1.11 节“服务器 SQL 模式”。