1.datetime类型用在需要同时包含日期和时间信息的值时。MySQL检索并且以'YYYY-MM-DD HH:MM:SS'格式显示datetime值,支持的范围是'1000-01-01 00:00:00'到'9999-12-31 23:59:59'
2.date类型用在你仅需要日期值时,没有时间部分。MySQL检索并且以'YYYY-MM-DD'格式显示date值,支持的范围是'1000-01-01'到'9999-12-31'
3.timestamp列类型提供一种类型,你可以使用它自动地用当前的日期和时间标记insert或update操作。如果你有多个timestamp列,只有第一个自动更新。
自动更新第一个timestamp列在下列任何条件下发生:
(1)列没有明确地在一个insert或load data infile语句中指定
(2)列没有明确地在一个update语句中指定且一些另外的列改变值(注意一个UPDATE
设置一个列为它已经有的值,这将不引起TIMESTAMP
列被更新,因为如果你设置一个列为它当前的值,MySQL为了效率而忽略更改。)
(3)你明确地设定TIMESTAMP
列为NULL
.
除第一个以外的TIMESTAMP
列也可以设置到当前的日期和时间,只要将列设为NULL
,或NOW()
。
通过明确地设置希望的值,你可以设置任何TIMESTAMP
列为不同于当前日期和时间的值,即使对第一个TIMESTAMP
列也是这样。例如,如果,当你创建一个行时,你想要一个TIMESTAMP
被设置到当前的日期和时间,但在以后无论何时行被更新时都不改变,你可以使用这个属性:
- 让MySQL在行被创建时设置列,这将初始化它为当前的日期和时间。
- 当你执行随后的对该行中其他列的更改时,明确设定
TIMESTAMP
列为它的当前值。
另一方面,你可能发现,当行被创建并且远离随后的更改时,很容易用一个你用NOW()
初始化的DATETIME
列。
TIMESTAMP
值可以从1970的某时的开始一直到2037年,精度为一秒,其值作为数字显示。
在MySQL检索并且显示TIMESTAMP
值取决于显示尺寸的格式如下表。“完整”TIMESTAMP
格式是14位,但是TIMESTAMP
列可以用更短的显示尺寸创造:
列类型 | 显示格式 |
TIMESTAMP(14) | YYYYMMDDHHMMSS |
TIMESTAMP(12) | YYMMDDHHMMSS |
TIMESTAMP(10) | YYMMDDHHMM |
TIMESTAMP(8) | YYYYMMDD |
TIMESTAMP(6) | YYMMDD |
TIMESTAMP(4) | YYMM |
TIMESTAMP(2) | YY |
所有的TIMESTAMP
列都有同样的存储大小,不考虑显示尺寸。最常见的显示尺寸是6、8、12、和14。你可以在表创建时间指定一个任意的显示尺寸,但是值0或比14大被强制到14。在从1~13范围的奇数值尺寸被强制为下一个更大的偶数。
使用一个常用的格式集的任何一个,你可以指定DATETIME
、DATE
和TIMESTAMP
值:
'YYYY-MM-DD HH:MM:SS'
或'YY-MM-DD HH:MM:SS'
格式的一个字符串。允许一种“宽松”的语法--任何标点可用作在日期部分和时间部分之间的分隔符。例如,'98-12-31 11:30:45'
、'98.12.31 11+30+45'
、'98/12/31 11*30*45'
和'98@12@31 11^30^45'
是等价的。'YYYY-MM-DD'
或'YY-MM-DD'
格式的一个字符串。允许一种“宽松”的语法。例如,'98-12-31'
,'98.12.31'
,'98/12/31'
和'98@12@31'
是等价的。'YYYYMMDDHHMMSS'
或'YYMMDDHHMMSS'
格式的没有任何分隔符的一个字符串,例如,'19970523091528'
和'970523091528'
被解释为'1997-05-23 09:15:28'
,但是'971122459015'
是不合法的(它有毫无意义的分钟部分)且变成'0000-00-00 00:00:00'
。'YYYYMMDD'
或'YYMMDD'
格式的没有任何分隔符的一个字符串,如果字符串认为是一个日期。例如,'19970523'
和'970523'
被解释作为'1997-05-23'
,但是'971332'
是不合法的( 它有无意义的月和天部分)且变成'0000-00-00'
。YYYYMMDDHHMMSS
或YYMMDDHHMMSS
格式的一个数字,如果数字认为是一个日期。例如,19830905132800
和830905132800
被解释作为'1983-09-05 13:28:00'
。YYYYMMDD
或YYMMDD
格式的一个数字,如果数字认为是一个日期。例如,19830905
和830905
被解释作为'1983-09-05'
。- 一个返回值可以在一个
DATETIME
,DATE
或TIMESTAMP
上下文环境中接受的函数,例如NOW()
或CURRENT_DATE
。
不合法DATETIME
, DATE
或TIMESTAMP
值被变换到适当类型的“零”值('0000-00-00 00:00:00'
, '0000-00-00'
或00000000000000
)。
对于包括的日期部分分隔符的指定为字符串的值,不必要为小于10
的月或天的值指定2位数字,'1979-6-9'
与'1979-06-09'
是一样的。同样, 对于包括的时间部分分隔符的指定为字符串的值,不必为小于10
的小时、月或秒指定2位数字,'1979-10-30 1:2:3'
与'1979-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
,但是日期部分丢失(零),因此该值不是一个合法的日期。
TIMESTAMP
列使用被指定的值的完整精度的存储合法的值,不考虑显示大小。这有几个含意:
- 总是指定年,月,和日,即使你的列类型是
TIMESTAMP(4)
或TIMESTAMP(2)
。否则,值将不是一个合法的日期并且0
将被存储。 - 如果你使用
ALTER TABLE
拓宽一个狭窄的TIMESTAMP
列,以前被“隐蔽”的信息将被显示。 - 同样,缩小一个
TIMESTAMP
列不会导致信息失去,除了感觉上值在显示时,较少的信息被显示出。 - 尽管
TIMESTAMP
值被存储为完整精度,直接操作存储值的唯一函数是UNIX_TIMESTAMP()
,其他函数操作在格式化了的检索的值上,这意味着你不能使用函数例如HOUR()
或SECOND()
,除非TIMESTAMP
值的相关部分被包含在格式化的值中。例如,一个TIMESTAMP
列的HH
部分部被显示,除非显示大小至少是10,因此在更短的TIMESTAMP
值上试试使用HOUR()
产生一个无意义的结果。
在某种程度上,你可以把一种日期类型的值赋给一个不同的日期类型的对象。然而,这可能值有一些改变或信息的损失:
- 如果你将一个
DATE
值赋给一个DATETIME
或TIMESTAMP
对象,结果值的时间部分被设置为'00:00:00'
,因为DATE
值不包含时间信息。 - 如果你将一个
DATETIME
或TIMESTAMP
值赋给一个DATE
对象,结果值的时间部分被删除,因为DATE
类型不存储时间信息。 - 记住,尽管
DATETIME
,DATE
和TIMESTAMP
值全都可以用同样的格式集来指定,但所有类型不都有同样的值范围。例如,TIMESTAMP
值不能比1970
早或比2037
网晚,这意味着,一个日期例如'1968-01-01'
,当作为一个DATETIME
或DATE
值合法时,它不是一个正确TIMESTAMP
值,并且如果赋值给这样一个对象,它将被变换到0
。
当指定日期值时,当心某些缺陷:
- 允许作为字符串指定值的宽松格式能被欺骗。例如,值例如
'10:11:12'
可能看起来像时间值,因为“:”分隔符,但是如果在一个日期中使用,上下文将作为年份被解释成'2010-11-12'
。值'10:45:15'
将被变换到'0000-00-00'
,因为'45'
不是一个合法的月份。 - 以2位数字指定的年值是模糊的,因为世纪是未知的。MySQL使用下列规则解释2位年值:
- 在
00-69
范围的年值被变换到2000-2069
。 - 在范
70-99
围的年值被变换到1970-1999
。
- 在
TIME
类型
MySQL检索并以'HH:MM:SS'
格式显示TIME
值(或对大小时值,'HHH:MM:SS'
格式)。TIME
值的范围可以从'-838:59:59'
到'838:59:59'
。小时部分可能很大的的原因是TIME
类型不仅可以被使用在表示一天的时间(它必须是不到24个小时),而且用在表示在2个事件之间经过的时间或时间间隔(它可以是比24个小时大些,或甚至是负值)。
你能用多中格式指定TIME
值:
- 作为
'HH:MM:SS'
格式的一个字符串。“宽松”的语法被允许--任何标点符号可用作时间部分的分隔符,例如,'10:11:12'
和'10.11.12'
是等价的。 - 作为没有分隔符的
'HHMMSS'
格式的一个字符串,如果它作为一个时间解释。例如,'101112'
被理解为'10:11:12'
,但是'109712'
是不合法的(它有无意义的分钟部分)并变成'00:00:00'
。 - 作为
HHMMSS
格式的一个数字,如果它能解释为一个时间。例如,101112
被理解为'10:11:12'
。 - 返回值可在一个
TIME
上下文接受的函数,例如CURRENT_TIME
。
对于作为包括一个时间分隔符的字符串被指定的TIME
值,不必为小于10
的小时、分钟或秒值指定2位数字,'8:3:2'
与'08:03:02'
是一样的。
将“短的”TIME
值赋值给一个TIME
行列是要格外小心。MySQL使用最右位代表秒的假设来解释值。(MySQL将TIME
值解释为经过的时间,而非作为一天的时间 )例如,你可能想到'11:12'
、'1112'
和1112
意味着'11:12:00'
(11点12分),但是MySQL解释他们为'00:11:12'
(11分12秒)。同样,'12'
和12
被解释为'00:00:12'
。
但是超出TIME
范围之外的值是样合法的,它被剪切到范围适当的端点值。例如,'-850:00:00'
和'850:00:00'
被变换到'-838:59:59'
和'838:59:59'
。
不合法的TIME
值被变换到'00:00:00'
。注意,既然'00:00:00'
本身是一个合法的TIME
值,没有其他方法区分表中存储的一个'00:00:00'
值,原来的值是否被指定为'00:00:00'
或它是否是不合法的。