用于表示时间值的日期和时间数据类型有 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 模式”。