|
15.3 时间数据
这一块很不好说清楚,也不打算把所有的时间类型列出来,只把主要的类型列出来。以下的都是自己的观点,如果有错误请指出。
MySQL日期和时间类型
· DATE
日期。支持的范围为'1000-01-01'到'9999-12-31'。MySQL以'YYYY-MM-DD'格式显示DATE值,但允许使用字符串或数字为DATE列分配值。
· DATETIME
日期和时间的组合。支持的范围是'1000-01-01 00:00:00'到'9999-12-31 23:59:59'。MySQL以'YYYY-MM-DD HH:MM:SS'格式显示DATETIME值,
但允许使用字符串或数字为DATETIME列分配值。
curdate()返回日期型数据 'YYYY-MM-DD'
now()返回日期时间型数据 'YYYY-MM-DD HH:MM:SS'
· TIMESTAMP[(M)]
时间戳。范围是'1970-01-01 00:00:00'到2037年。
TIMESTAMP列用于INSERT或UPDATE操作时记录日期和时间。如果你不分配一个值,表中的第一个TIMESTAMP列自动设置为最近操作的日期和时间
。也可以通过分配一个NULL值,将TIMESTAMP列设置为当前的日期和时间。TIMESTAMP值返回后显示为'YYYY-MM-DD HH:MM:SS'格式的字符串,显
示宽度固定为19个字符。如果想要获得数字值,应在TIMESTAMP 列添加+0。
例子:
mysql> insert into t(test_date,test_datetime,test_timestamp) values(curdate(),now(),null);
Query OK, 1 row affected (0.03 sec)
mysql> select * from t;
+----+------------+---------------------+---------------------+
| id | test_date | test_datetime | test_timestamp |
+----+------------+---------------------+---------------------+
| 1 | 2007-11-02 | 2007-11-02 14:37:31 | 2007-11-02 14:37:31 |
+----+------------+---------------------+---------------------+
1 row in set (0.02 sec)
mysql> insert into t(test_date,test_datetime,test_timestamp) values(curdate(),now(),null);
Query OK, 1 row affected (0.03 sec)
mysql> insert into t(test_date,test_datetime,test_timestamp) values(curdate(),now(),null);
Query OK, 1 row affected (0.03 sec)
mysql> insert into t(test_date,test_datetime,test_timestamp) values(curdate(),now(),null);
Query OK, 1 row affected (0.08 sec)
mysql> insert into t(test_date,test_datetime) values(curdate(),now());
Query OK, 1 row affected (0.05 sec)
mysql> select * from t;
+----+------------+---------------------+---------------------+
| id | test_date | test_datetime | test_timestamp |
+----+------------+---------------------+---------------------+
| 1 | 2007-11-02 | 2007-11-02 14:37:31 | 2007-11-02 14:37:31 |
| 2 | 2007-11-02 | 2007-11-02 14:37:44 | 2007-11-02 14:37:44 |
| 3 | 2007-11-02 | 2007-11-02 14:37:46 | 2007-11-02 14:37:46 |
| 4 | 2007-11-02 | 2007-11-02 14:37:48 | 2007-11-02 14:37:48 |
| 5 | 2007-11-02 | 2007-11-02 14:38:15 | 2007-11-02 14:38:15 |
+----+------------+---------------------+---------------------+
5 rows in set (0.00 sec)
mysql> select id,test_date,test_datetime,test_timestamp+0 from t;
+----+------------+---------------------+------------------+
| id | test_date | test_datetime | test_timestamp+0 |
+----+------------+---------------------+------------------+
| 1 | 2007-11-02 | 2007-11-02 14:37:31 | 20071102143731 |
| 2 | 2007-11-02 | 2007-11-02 14:37:44 | 20071102143744 |
| 3 | 2007-11-02 | 2007-11-02 14:37:46 | 20071102143746 |
| 4 | 2007-11-02 | 2007-11-02 14:37:48 | 20071102143748 |
| 5 | 2007-11-02 | 2007-11-02 14:38:15 | 20071102143815 |
+----+------------+---------------------+------------------+
mysql> insert into t(test_date,test_datetime) values('1999-12-22','1999-12-22');
Query OK, 1 row affected (0.03 sec)
mysql> select id,test_date,test_datetime,test_timestamp+0 from t;
+----+------------+---------------------+------------------+
| id | test_date | test_datetime | test_timestamp+0 |
+----+------------+---------------------+------------------+
| 1 | 2007-11-02 | 2007-11-02 14:37:31 | 20071102143731 |
| 2 | 2007-11-02 | 2007-11-02 14:37:44 | 20071102143744 |
| 3 | 2007-11-02 | 2007-11-02 14:37:46 | 20071102143746 |
| 4 | 2007-11-02 | 2007-11-02 14:37:48 | 20071102143748 |
| 5 | 2007-11-02 | 2007-11-02 14:38:15 | 20071102143815 |
| 6 | 1999-12-22 | 1999-12-22 00:00:00 | 20071102145216 |
+----+------------+---------------------+------------------+
6 rows in set (0.00 sec)
· TIME
时间。范围是'-838:59:59'到'838:59:59'。MySQL以'HH:MM:SS'格式显示TIME值,但允许使用字符串或数字为TIME列分配值。
· YEAR[(2|4)]
两位或四位格式的年。默认是四位格式。在四位格式中,允许的值是1901到2155和0000。在两位格式中,允许的值是70到69,表示从1970年到
2069年。MySQL以YYYY 格式显示YEAR值,但允许使用字符串或数字为YEAR列分配值。
oracle的时间类型,date,timestamp和interval.
oracle的date类型就相当于mysql的date+datetime的集合。
timestamp和mysql的timestamp是完全不同的概念,oracle的timestamp是date的扩张,支持时区和小数秒,精度默认值是6,即6位的小数秒。
interval固定的时间量,INTERVAL YEAR TO MONTH,INTERVAL DAY TO SECOND,YEAR精度默认值是2,DAY是2,SECOND是6。这个类型mysql没有
。
oracle>create table t(t_date date,t_timestamp timestamp,t_interval INTERVAL YEAR TO MONTH);
Table created.
oracle>insert into t values(sysdate,systimestamp,numtoyminterval(5,'year'));
1 row created.
oracle>select * from t;
T_DATE T_TIMESTAMP T_INTERVAL
--------- ------------------------------ ------------------------------
05-NOV-07 05-NOV-07 03.27.34.698096 PM +05-00
oracle>insert into t values('1999-12-22','1999-12-22',numtoyminterval(5,'year'));
insert into t values('1999-12-22','1999-12-22',numtoyminterval(5,'year'))
*
ERROR at line 1:
ORA-01861: literal does not match format string
oracle不能像myslq一样把字符自动转化为日期格式,必须使用函数
oracle提供了一些有用的函数来完成字符串和日期类型之间的转换:
TO_DATE
TO_TIMESTAMP
TO_TIMESTAMP_TZ
TO_YMINTERVAL
TO_DSINTERVAL
NUMTOYMINTERVAL
NUMTODSINTERVAL
TO_CHAR
函数的使用可以查手册。
oracle>insert into t values(to_date('1999-12-22 14:30:00','yyyy-mm-dd hh24:mi:ss'),to_timestamp('1999-12-22
14:30:30.45','yyyy-mm-dd hh24:mi:ss.ff'),null);
1 row created.
oracle>select * from t;
T_DATE T_TIMESTAMP T_INTERVAL
--------- ------------------------------ ------------------------------
05-NOV-07 05-NOV-07 03.34.38.344712 PM +05-00
22-DEC-99 22-DEC-99 02.30.30.450000 PM
显示不是我们想要的格式,可以根据自己的需要使用to_char函数。
oracle>select to_char(t_date,'yyyy-mm-dd hh24:mi:ss') t_date,to_char(t_timestamp,'yyyy-mm-dd hh24:mi:ss:ff')
t_timestamp,t_interval from t;
T_DATE T_TIMESTAMP T_INTERVAL
-------------------------------------- ---------------------------------------- ------------------------------
2007-11-05 15:34:38 2007-11-05 15:34:38:344712 +05-00
1999-12-22 14:30:00 1999-12-22 14:30:30:450000
可能我们实际中用的很多的是需要得到2个时间之差,这2个数据库都有自己的函数来实现:
mysql> create table t3(date1 datetime,date2 datetime);
Query OK, 0 rows affected (0.16 sec)
mysql> insert into t3 values('1999-12-22 14:30:00',now());
Query OK, 1 row affected (0.08 sec)
mysql> select * from t3;
+---------------------+---------------------+
| date1 | date2 |
+---------------------+---------------------+
| 1999-12-22 14:30:00 | 2007-11-06 10:47:25 |
+---------------------+---------------------+
1 row in set (0.00 sec)
mysql> insert into t3 values('2007-10-21 14:30:00',now());
Query OK, 1 row affected (0.06 sec)
mysql> select timediff(date2,date1) from t3;
+-----------------------+
| timediff(date2,date1) |
+-----------------------+
| 838:59:59 |
| 380:34:01 |
+-----------------------+
2 rows in set, 1 warning (0.00 sec)
mysql> select * from t3;
+---------------------+---------------------+
| date1 | date2 |
+---------------------+---------------------+
| 1999-12-22 14:30:00 | 2007-11-06 10:47:25 |
| 2007-10-21 14:30:00 | 2007-11-06 11:04:01 |
+---------------------+---------------------+
2 rows in set (0.00 sec)
mysql> insert into t3 values('2000-10-21 14:30:00',now());
Query OK, 1 row affected (0.03 sec)
mysql> select * from t3;
+---------------------+---------------------+
| date1 | date2 |
+---------------------+---------------------+
| 1999-12-22 14:30:00 | 2007-11-06 10:47:25 |
| 2007-10-21 14:30:00 | 2007-11-06 11:04:01 |
| 2000-10-21 14:30:00 | 2007-11-06 11:05:47 |
+---------------------+---------------------+
3 rows in set (0.00 sec)
mysql> select date2-date1 from t3;
+--------------------+
| date2-date1 |
+--------------------+
| 79883961725.000000 |
| 84967401.000000 |
| 70084967547.000000 |
+--------------------+
3 rows in set (0.00 sec)
这个看不太明白什么意思。。。
mysql> select timediff(date2,date1) from t3;
+-----------------------+
| timediff(date2,date1) |
+-----------------------+
| 838:59:59 |
| 380:34:01 |
| 838:59:59 |
+-----------------------+
3 rows in set, 2 warnings (0.02 sec)
838:59:59这个时间差明显是不对的,估计是timediff函数的一个上限值,也就是说超过这个差距timediff函数就不能正确使用。
mysql> SELECT UNIX_TIMESTAMP(date2)-UNIX_TIMESTAMP(date1) from t3;
+---------------------------------------------+
| UNIX_TIMESTAMP(date2)-UNIX_TIMESTAMP(date1) |
+---------------------------------------------+
| 248473045 |
| 1370041 |
| 222208547 |
+---------------------------------------------+
3 rows in set (0.00 sec)
秒数是对的,但是显然我们不想看到这样的结果,这样的结果我我们没有任何意义,但是怎么转化成时间差多少年、月、日、小时呢?
mysql> SELECT SEC_TO_TIME(UNIX_TIMESTAMP(date2)-UNIX_TIMESTAMP(date1)) from t3;
+----------------------------------------------------------+
| SEC_TO_TIME(UNIX_TIMESTAMP(date2)-UNIX_TIMESTAMP(date1)) |
+----------------------------------------------------------+
| 838:59:59 |
| 380:34:01 |
| 838:59:59 |
+----------------------------------------------------------+
3 rows in set, 2 warnings (0.00 sec)
结果和timediff一样,难道是mysql数据库的限制?是的,前面我们介绍了
· TIME
时间。范围是'-838:59:59'到'838:59:59'。MySQL以'HH:MM:SS'格式显示TIME值,但允许使用字符串或数字为TIME列分配值。
oracle中如何得到时间差?
oracle>create table t3(date1 date,date2 date);
Table created.
oracle>insert into t3 values(to_date('1999-12-22 14:30:00','yyyy-mm-dd hh24:mi:ss'),sysdate);
1 row created.
oracle>insert into t3 values(to_date('2007-10-21 14:30:00','yyyy-mm-dd hh24:mi:ss'),sysdate);
1 row created.
oracle>insert into t3 values(to_date('2000-10-21 14:30:00','yyyy-mm-dd hh24:mi:ss'),sysdate);
1 row created.
oracle>select to_char(date1,'yyyy-mm-dd hh24:mi:ss') date1,to_char(date2,'yyyy-mm-dd hh24:mi:ss') date2 from t3;
DATE1 DATE2
-------------------------------------- --------------------------------------
1999-12-22 14:30:00 2007-11-07 10:34:06
2007-10-21 14:30:00 2007-11-07 10:35:25
2000-10-21 14:30:00 2007-11-07 10:35:55
oracle>select date2-date1 from t3;
DATE2-DATE1
-----------
2876.83618
16.8370949
2572.83744
数据是没错,但是也不是我们想要的格式。
oracle>select months_between(date2,date1) from t3;
MONTHS_BETWEEN(DATE2,DATE1)
---------------------------
94.5108445
.543132094
84.5431433
也一样。
oracle>select numtoyminterval(months_between(date2,date1),'month') years_months,numtodsinterval(date2-add_months(date1,trunc
(months_between(date2,date1))),'day') days_hours from t3;
YEARS_MONTHS DAYS_HOURS
------------------------------ ---------------------------------------------------------------------------
+000000007-10 +000000015 20:04:06.000000000
+000000000-00 +000000016 20:05:25.000000000
+000000007-00 +000000016 20:05:55.000000000
OK,可以很明显,第一行记录是7年10个月15天20小时4分6秒。这里myslq没有的interval类型就起作用了。 |
|