datetime 显示为'YYYY-MM-DD HH:MM:SS'格式,范围为'1000-01-01 00:00:00'到'9999-12-31 23:59:59'
date 显示为'YYYY-MM-DD'格式,范围为'1001-01-01'到'9999-12-31'
timestamp 范围从'1970-01-01 00:00:01'UTC 到'2038-01-09 03:14:07'UTC
datetime和timestamp比较
datetime和timestamp 相同点:
显示格式相同,TIMESTAMP列的显示格式与DATETIME列相同。换句话说,显示宽度固定在19字符,并且格式为YYYY-MM-DD HH:MM:SS。
datetime和timestamp不同点:
1)范围
datetime 以'YYYY-MM-DD HH:MM:SS'格式检索和显示DATETIME值。支持的范围为'1000-01-01 00:00:00'到'9999-12-31 23:59:59'TIMESTAMP值不能早于1970或晚于2037.
2)储存
TIMESTAMP
1.4个字节储存(Time stamp value is stored in 4 bytes)
2.值以UTC格式保存( it stores the number of milliseconds)
3.时区转化 ,存储时对当前的时区进行转换,检索时再转换回当前的时区。
datetime
1.8个字节储存(8 bytes storage)
2.实际格式储存(Just stores what you have stored and retrieves the same thing which you have stored.)
3.与时区无关(It has nothing to deal with the TIMEZONE and Conversion.)
其它相关介绍
1. 指定值
指定datetime值时,可以用'2009-01-01 11:20:30','2009/01/01 11*20*30','2009*01*01 11^20^30','2009@01@01 11+20+30'等,效果是一样的。
指定date值时,与上类似。
指定datetime值时,也可以用字符串'YYYYMMDDHHMMSS'或'YYMMDDHHMMSS'格式,如'20090101112030'或 '090101112030',但'20090101119030'(分钟为90)会被解析为“零”值:'0000-00-00 00:00:00'。
指定date值时,与上类似。
指定datetime值时,也可以用数字YYYYMMDDHHMMSS或YYMMDDHHMMSS格式,如20090101112030或 090101112030。
指定date值时,与上类似。
指定datetime、date或timestamp值时,也可以用now()或current_date的值。
指定datetime、date或timestamp值时,月、日、时、分、秒,若小于10,可以只写1位,如'2009-01-01 11:30:30'与'2009-1-1 11:30:30'一样。
用数字指定时间时,可以为6、8、12或14位,6位表示YYMMDD,8位表示YYYYMMDD,12位表示YYMMDDHHMMSS,14位表示 YYYYMMDDHHMMSS。
用不带分割符的字符串指定时间时,如果字符串为8位或14位的,那么认为年份为YYYY,否则认为年份为YY,之后按顺序解析月日时分秒。
2. 不同类型转换
date值赋给datetime或timestamp时,时间部分为'00:00:00'。
datetime或timestamp值赋给date时,时间部分被去掉。
转换时注意其表示范围有所不同,超出范围的将被转为“零”值。
3. 注意'10:11:12'会被转为'2010-11-12 00:00:00'或'2010-11-12'。
4. timestamp类型
从当前时区转成UTC保存,要读取时,再从UTC转成当前时区。(不发生在datetime类型上)。
当前时区对应time_zone系统变量(缺省值为'System'表示用系统变量system_time_zone的值)
系统变量system_time_zone的值在启动MySQL时指定,一般去TZ环境变量,或执行mysqld_safe时用--timezone选 项。
(linux 安 装时挑选时区,安装后时区保存在/etc/sysconfig/clock文件里。)
若将timestamp类型字段定义为default current_timestamp,那么插入一条记录时,该timestamp字段自动被赋值为当前时间。
若将timestamp类型字段定义为on update current_timestamp,那么修改一条记录时,该timestamp字段自动被修改为当前时间。
在一个表里面的timestamp字段只能有下面4种定义:
1). 是default current_timestamp
插入时系统自动赋值,插入时若在SQL 语句中指定该字段的值,则用SQL语句中的指定值。
修改时时间值不自动改变,但可以在SQL语句中指定其值。
2). 是on update current_timestamp
插入时系统不自动赋值(字段为“零”值),但可以在SQL语句中指定该字段的值。
修改时,系统自动赋值,但若SQL语句中指定其值,则用SQL语句中的指定值。
3).两个都有default current_timestamp on update current_timestamp
如果timestamp后面啥都不写,也相当于2个都有。
插入修改时系统自动赋值,SQL语句中若指定,则用SQL语句中的指定值。
4).如果default 后面写个常数,如default 20090101010000,那么插入时即为这个值。其他与上面类似。
另外,一个表里面,如果想定义第2个timestamp字段,而且想让第2个字段有系统自动修改的机制,那么之前的那个字段一定要赋予default 常数(即上面第4点),然后,再给这个新的timestamp字段进行如上abc的定义,区别是这个新的timestamp字段不能后面啥不都写,如果啥都不写,那么插入和修改时系统不会自动赋值。依次类推,再想定义第3个timestamp字段,而且想让第3个字段有系统自动修改的机制,那么之前第2个timestamp字段一定要赋予default 常数(即上面第4点),然后,再给这个新的timestamp字段进行如上abc的定义,区别跟前面一样。
上述current_timestamp还可以用它的同义词 current_timestamp(),now(),localtime,localtime(),localtimestamp,localtimestamp() 代替。
timestamp字段缺省不允许空值,如果指定它的值为null,实际上就是用当前时间值赋给他了。
但是,可以这样定义:
col1 timestamp null default null, 注释:该字段可以为null,插入时缺省就是null,如果赋值null,那也真是null而不是当前时间值。
col2 timestamp null default 0, 注释:该字段可以null,插入时缺省为0,如果赋值null,那也真是null而不是当前时间值。
如果MySQL服务器以MAXDB SQL模式运行,那么timestamp等同于datetime类型,前面说的timestamp类型的所有描述都消失。
timestamp时间范围测试:
mysql> drop table if exists tt;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> create table tt(time_stamp timestamp);
Query OK, 0 rows affected (0.06 sec)
mysql> insert into tt values(20380119111407);
Query OK, 1 row affected (0.01 sec)
mysql> insert into tt values(20380119111408);
ERROR 1292 (22007): Incorrect datetime value: '20380119111408' for column 'time_
stamp' at row 1
mysql> select * from tt;
+---------------------+
| time_stamp |
+---------------------+
| 2038-01-19 11:14:07 |
+---------------------+
1 row in set (0.00 sec)
然后清空表.
mysql> truncate tt;
Query OK, 15 rows affected (0.03 sec)
mysql> insert into tt values(19700101080001);
Query OK, 1 row affected (0.03 sec)
mysql> insert into tt values(19700101080000);
ERROR 1292 (22007): Incorrect datetime value: '19700101080000' for column 'time_
stamp' at row 1
mysql> select * from tt;
+---------------------+
| time_stamp |
+---------------------+
| 1970-01-01 08:00:01 |
+---------------------+
1 row in set (0.00 sec)
从上面这个实验可以看出,当我插入时间20380119111407时,插入成功.当插入20380119111408时,显示错误.
当我插入时间19700101080001时,插入成功.当插入19700101080000时,显示错误.
接着我又对date和datetime做了实验,发现date的范围是0000-00-00到9999-12-31.
datetime的范围是0000-00-00 00:00:00到9999-12-31 23:59:59.
mysql> drop table tt;
Query OK, 0 rows affected (0.02 sec)
mysql> create table tt(date date);
Query OK, 0 rows affected (0.12 sec)
mysql> insert into tt values("0000-00-00");
Query OK, 1 row affected (0.03 sec)
mysql> select * from tt;
+------------+
| date |
+------------+
| 0000-00-00 |
+------------+
1 row in set (0.00 sec)
mysql> insert into tt values("9999-12-31");
Query OK, 1 row affected (0.02 sec)
mysql> select * from tt;
+------------+
| date |
+------------+
| 0000-00-00 |
| 9999-12-31 |
+------------+
2 rows in set (0.00 sec)
mysql> drop table tt;
Query OK, 0 rows affected (0.02 sec)
mysql> create table tt(date_time datetime);
Query OK, 0 rows affected (0.04 sec)
mysql> insert into tt values("0000-00-00 00:00:00");
Query OK, 1 row affected (0.02 sec)
mysql> insert into tt values("9999-12-31 23:59:59");
Query OK, 1 row affected (0.02 sec)
mysql> select * from tt;
+---------------------+
| date_time |
+---------------------+
| 0000-00-00 00:00:00 |
| 9999-12-31 23:59:59 |
+---------------------+
2 rows in set (0.00 sec)