12.5. 日期和时间函数
本章论述了一些可用于操作时间值的函数。关于每个时间和日期类型具有的值域及指定值的有效格式,请参见 11.3节,“日期和时间类型” 。
下面的例子使用了时间函数。以下询问选择了最近的 30 天内所有带有date_col 值的记录:
mysql> SELECT something FROM tbl_name
-> WHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY) <= date_col ;
注意,这个询问也能选择将来的日期记录。
用于日期值的函数通常会接受时间日期值而忽略时间部分。而用于时间值的函数通常接受时间日期值而忽略日期部分。
返回各自当前日期或时间的函数在每次询问执行开始时计算一次。这意味着在一个单一询问中,对诸如NOW() 的函数多次访问总是会得到同样的结果( 未达到我们的目的,单一询问也包括对存储程序或触发器和被该程序/ 触发器调用的所有子程序的调用 ) 。这项原则也适用于 CURDATE() 、 CURTIME() 、 UTC_DATE() 、 UTC_TIME() 、UTC_TIMESTAMP() ,以及所有和它们意义相同的函数。
CURRENT_TIMESTAMP() 、 CURRENT_TIME() 、 CURRENT_DATE() 以及FROM_UNIXTIME() 函数返回连接当前时区内的值,这个值可用作time_zone 系统变量的值。此外, UNIX_TIMESTAMP() 假设其参数为一个当前时区的时间日期值。请参见 5.10.8节,“MySQL服务器时区支持” 。
以下函数的论述中返回值的范围会请求完全日期。 若一个日期为“零” 值,或者是一个诸如'2001-11-00' 之类的不完全日期, 提取部分日期值的函数可能会返回 0 。 例如, DAYOFMONTH('2001-11-00') 会返回0 。
- ADDDATE(date ,INTERVAL expr type ) ADDDATE(expr ,days )
当被第二个参数的INTERVAL 格式激活后, ADDDATE() 就是DATE_ADD() 的同义词。相关函数SUBDATE() 则是DATE_SUB() 的同义词。对于INTERVAL 参数上的信息 ,请参见关于DATE_ADD() 的论述。
mysql> SELECT DATE_ADD('1998-01-02', INTERVAL 31 DAY);
-> '1998-02-02'
mysql> SELECT ADDDATE('1998-01-02', INTERVAL 31 DAY);
-> '1998-02-02'
若 days 参数只是整数值,则 MySQL 5.1 将其作为天数值添加至 expr 。
mysql> SELECT ADDDATE('1998-01-02', 31);
-> '1998-02-02'
- ADDTIME(expr ,expr2 )
ADDTIME() 将 expr2 添加至expr 然后返回结果。 expr 是一个时间或时间日期表达式,而expr2 是一个时间表达式。
mysql> SELECT ADDTIME('1997-12-31 23:59:59.999999',
-> '1 1:1:1.000002');
-> '1998-01-02 01:01:01.000001'
mysql> SELECT ADDTIME('01:00:00.999999', '02:00:00.999998');
-> '03:00:01.999997'
- CONVERT_TZ(dt ,from_tz ,to_tz )
CONVERT_TZ() 将时间日期值dt 从from_tz 给出的时区转到to_tz 给出的时区,然后返回结果值。关于可能指定的时区的详细论述,请参见 5.10.8节,“MySQL服务器时区支持” 。若自变量无效,则这个函数会返回 NULL 。
在从若from_tz 到UTC 的转化过程中,该值超出 TIMESTAMP 类型的被支持范围,那么转化不会发生。关于 TIMESTAMP 范围的论述,请参见 11.1.2节,“日期和时间类型概述” 。
mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET');
-> '2004-01-01 13:00:00'
mysql> SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');
-> '2004-01-01 22:00:00'
注释 : 若要使用诸如 'MET' 或 'Europe/Moscow' 之类的指定时间区,首先要设置正确的时区表。详细说明见 5.10.8节,“MySQL服务器时区支持” 。
- CURDATE()
将当前日期按照'YYYY-MM-DD' 或YYYYMMDD 格式的值返回,具体格式根据函数用在字符串或是数字语境中而定。
mysql> SELECT CURDATE();
-> '1997-12-15'
mysql> SELECT CURDATE() + 0;
-> 19971215
- CURRENT_DATE CURRENT_DATE()
CURRENT_DATE 和CURRENT_DATE() 是的同义词.
- CURTIME()
将当前时间以'HH:MM:SS' 或 HHMMSS 的格式返回, 具体格式根据函数用在字符串或是数字语境中而定。
mysql> SELECT CURTIME();
-> '23:50:26'
mysql> SELECT CURTIME() + 0;
-> 235026
- CURRENT_TIME, CURRENT_TIME()
CURRENT_TIME 和CURRENT_TIME() 是CURTIME() 的同义词。
- CURRENT_TIMESTAMP, CURRENT_TIMESTAMP()
CURRENT_TIMESTAMP 和 CURRENT_TIMESTAMP() 是NOW() 的同义词。
- DATE(expr )
提取日期或时间日期表达式expr 中的日期部分。
mysql> SELECT DATE('2003-12-31 01:02:03');
-> '2003-12-31'
- DATEDIFF(expr ,expr2 )
DATEDIFF() 返回起始时间 expr 和结束时间expr2 之间的天数。Expr 和expr2 为日期或 date-and-time 表达式。计算中只用到这些值的日期部分。
mysql> SELECT DATEDIFF('1997-12-31 23:59:59','1997-12-30');
-> 1
mysql> SELECT DATEDIFF('1997-11-30 23:59:59','1997-12-31');
-> -31
- DATE_ADD(date ,INTERVAL expr type ) DATE_SUB(date ,INTERVAL expr type )
这些函数执行日期运算。 date 是一个 DATETIME 或DATE 值,用来指定起始时间。 expr 是一个表达式,用来指定从起始日期添加或减去的时间间隔值。 Expr 是一个字符串; 对于负值的时间间隔,它可以以一个 ‘- ’开头。 type 为关键词,它指示了表达式被解释的方式。
关键词INTERVA 及 type 分类符均不区分大小写。
以下表显示了type 和expr 参数的关系:
type 值 |
预期的 expr 格式 |
MICROSECOND |
MICROSECONDS |
SECOND |
SECONDS |
MINUTE |
MINUTES |
HOUR |
HOURS |
DAY |
DAYS |
WEEK |
WEEKS |
MONTH |
MONTHS |
QUARTER |
QUARTERS |
YEAR |
YEARS |
SECOND_MICROSECOND |
'SECONDS.MICROSECONDS' |
MINUTE_MICROSECOND |
'MINUTES.MICROSECONDS' |
MINUTE_SECOND |
'MINUTES:SECONDS' |
HOUR_MICROSECOND |
'HOURS.MICROSECONDS' |
HOUR_SECOND |
'HOURS:MINUTES:SECONDS' |
HOUR_MINUTE |
'HOURS:MINUTES' |
DAY_MICROSECOND |
'DAYS.MICROSECONDS' |
DAY_SECOND |
'DAYS HOURS:MINUTES:SECONDS' |
DAY_MINUTE |
'DAYS HOURS:MINUTES' |
DAY_HOUR |
'DAYS HOURS' |
YEAR_MONTH |
'YEARS-MONTHS' |
MySQL 允许任何expr 格式中的标点分隔符。表中所显示的是建议的 分隔符。若 date 参数是一个 DATE 值,而你的计算只会包括 YEAR 、MONTH 和DAY 部分( 即, 没有时间部分), 其结果是一个DATE 值。否则,结果将是一个 DATETIME 值。
若位于另一端的表达式是一个日期或日期时间值 , 则INTERVAL expr type 只允许在 + 操作符的两端。对于 –操作符, INTERVAL expr type 只允许在其右端,原因是从一个时间间隔中提取一个日期或日期时间值是毫无意义的。 ( 见下面的例子)。
mysql> SELECT '1997-12-31 23:59:59' + INTERVAL 1 SECOND;
-> '1998-01-01 00:00:00'
mysql> SELECT INTERVAL 1 DAY + '1997-12-31';
-> '1998-01-01'
mysql> SELECT '1998-01-01' - INTERVAL 1 SECOND;
-> '1997-12-31 23:59:59'
mysql> SELECT DATE_ADD('1997-12-31 23:59:59',
-> INTERVAL 1 SECOND);
-> '1998-01-01 00:00:00'
mysql> SELECT DATE_ADD('1997-12-31 23:59:59',
-> INTERVAL 1 DAY);
-> '1998-01-01 23:59:59'
mysql> SELECT DATE_ADD('1997-12-31 23:59:59',
-> INTERVAL '1:1' MINUTE_SECOND);
-> '1998-01-01 00:01:00'
mysql> SELECT DATE_SUB('1998-01-01 00:00:00',
-> INTERVAL '1 1:1:1' DAY_SECOND);
-> '1997-12-30 22:58:59'
mysql> SELECT DATE_ADD('1998-01-01 00:00:00',
-> INTERVAL '-1 10' DAY_HOUR);
-> '1997-12-30 14:00:00'
mysql> SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
-> '1997-12-02'
mysql> SELECT DATE_ADD('1992-12-31 23:59:59.000002',
-> INTERVAL '1.999999' SECOND_MICROSECOND);
-> '1993-01-01 00:00:01.000001'
若你指定了一个过于短的时间间隔值 ( 不包括type 关键词所预期的所有时间间隔部分), MySQL 假定你已经省去了时间间隔值的最左部分。 例如,你指定了一种类型的DAY_SECOND, expr 的值预期应当具有天、 小时、分钟和秒部分。若你指定了一个类似 '1:10' 的值, MySQL 假定天和小时部分不存在,那么这个值代表分和秒。换言之, '1:10' DAY_SECOND 被解释为相当于 '1:10' MINUTE_SECOND 。这相当于 MySQL 将TIME 值解释为所耗费的时间而不是日时的解释方式。
假如你对一个日期值添加或减去一些含有时间部分的内容,则结果自动转化为一个日期时间值:
mysql> SELECT DATE_ADD('1999-01-01', INTERVAL 1 DAY);
-> '1999-01-02'
mysql> SELECT DATE_ADD('1999-01-01', INTERVAL 1 HOUR);
-> '1999-01-01 01:00:00'
假如你使用了格式严重错误的日期, 则结果为 NULL 。假如你添加了 MONTH 、YEAR_MONTH 或YEAR ,而结果日期中有一天的日期大于添加的月份的日期最大限度,则这个日期自动被调整为添加月份的最大日期:
mysql> SELECT DATE_ADD('1998-01-30', INTERVAL 1 MONTH);
-> '1998-02-28'
- DATE_FORMAT(date ,format )
根据format 字符串安排date 值的格式。
以下说明符可用在 format 字符串中:
说明符 |
说明 |
%a |
工作日的缩写名称 (Sun..Sat) |
%b |
月份的缩写名称 ( Jan .. Dec ) |
%c |
月份,数字形式 ( 0 .. 12 ) |
%D |
带有英语后缀的该月日期 ( 0th , 1st , 2nd , 3rd , ...) |
%d |
该月日期 , 数字形式 ( 00 .. 31 ) |
%e |
该月日期 , 数字形式 ( 0 .. 31 ) |
%f |
微秒 ( 000000 .. 999999 ) |
%H |
小时 ( 00 .. 23 ) |
%h |
小时 ( 01 .. 12 ) |
%I |
小时 ( 01 .. 12 ) |
%i |
分钟 , 数字形式 ( 00 .. 59 ) |
%j |
一年中的天数 ( 001 .. 366 ) |
%k |
小时 ( 0 .. 23 ) |
%l |
小时 ( 1 .. 12 ) |
%M |
月份名称 ( January .. December ) |
%m |
月份 , 数字形式 ( 00 .. 12 ) |
%p |
上午(AM )或下午( PM ) |
%r |
时间 , 12 小时制 ( 小时hh: 分钟mm: 秒数ss 后加 AM 或 PM ) |
%S |
秒 ( 00 .. 59 ) |
%s |
秒 ( 00 .. 59 ) |
%T |
时间 , 24 小时制 ( 小时hh: 分钟mm: 秒数ss ) |
%U |
周 ( 00 .. 53 ), 其中周日为每周的第一天 |
%u |
周 ( 00 .. 53 ), 其中周一为每周的第一天 |
%V |
周 ( 01 .. 53 ), 其中周日为每周的第一天 ; 和 %X 同时使用 |
%v |
周 ( 01 .. 53 ), 其中周一为每周的第一天 ; 和 %x 同时使用 |
%W |
工作日名称 ( 周日 .. 周六 ) |
%w |
一周中的每日 ( 0 = 周日 .. 6 = 周六 ) |
%X |
该周的年份,其中周日为每周的第一天 , 数字形式 ,4 位数 ; 和 %V 同时使用 |
%x |
该周的年份,其中周一为每周的第一天 , 数字形式 ,4 位数 ; 和 %v 同时使用 |
%Y |
年份 , 数字形式 ,4 位数 |
%y |
年份 , 数字形式 (2 位数 ) |
%% |
‘ % ’文字字符 |
所有其它字符都被复制到结果中, 无需作出解释。
注意, ‘% ’字符要求在格式指定符之前。
月份和日期说明符的范围从零开始,原因是 MySQL 允许存储诸如 '2004-00-00' 的不完全日期.
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
-> 'Saturday October 1997'
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
-> '22:23:00'
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
'%D %y %a %d %m %b %j');
-> '4th 97 Sat 04 10 Oct 277'
mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
'%H %k %I %r %T %S %w');
-> '22 22 10 10:23:00 PM 22:23:00 00 6'
mysql> SELECT DATE_FORMAT('1999-01-01', '%X %V');
-> '1998 52'
- DAY(date )
DAY() 和DAYOFMONTH() 的意义相同。
- DAYNAME(date )
返回date 对应的工作日名称。
mysql> SELECT DAYNAME('1998-02-05');
-> ' 周四'
- DAYOFMONTH(date )
返回date 对应的该月日期,范围是从 1 到31 。
mysql> SELECT DAYOFMONTH('1998-02-03');
-> 3
- DAYOFWEEK(date )
返回date (1 = 周日, 2 = 周一, ..., 7 = 周六) 对应的工作日索引。这些索引值符合 ODBC 标准。
mysql> SELECT DAYOFWEEK('1998-02-03');
-> 3
- DAYOFYEAR(date )
返回date 对应的一年中的天数,范围是从 1 到366 。
mysql> SELECT DAYOFYEAR('1998-02-03');
-> 34
- EXTRACT(type FROM date )
EXTRACT() 函数所使用的时间间隔类型说明符同 DATE_ADD() 或DATE_SUB() 的相同, 但它从日期中提取其部分,而不是执行日期运算。
mysql> SELECT EXTRACT(YEAR FROM '1999-07-02');
-> 1999
mysql> SELECT EXTRACT(YEAR_MONTH FROM '1999-07-02 01:02:03');
-> 199907
mysql> SELECT EXTRACT(DAY_MINUTE FROM '1999-07-02 01:02:03');
-> 20102
mysql> SELECT EXTRACT(MICROSECOND
-> FROM '2003-01-02 10:30:00.00123');
-> 123
- FROM_DAYS(N )
给定一个天数 N , 返回一个DATE 值。
mysql> SELECT FROM_DAYS(729669);
-> '1997-10-07'
使用 FROM_DAYS() 处理古老日期时,务必谨慎。他不用于处理阳历出现前的日期(1582) 。请参见 12.6节,“MySQL使用什么日历?” 。
- FROM_UNIXTIME(unix_timestamp ) , FROM_UNIXTIME(unix_timestamp ,format )
返回'YYYY-MM-DD HH:MM:SS' 或YYYYMMDDHHMMSS 格式值的unix_timestamp 参数表示,具体格式取决于该函数是否用在字符串中或是数字语境中。
若format 已经给出,则结果的格式是根据format 字符串而定。 format 可以包含同DATE_FORMAT() 函数输入项列表中相同的说明符。
mysql> SELECT FROM_UNIXTIME(875996580);
-> '1997-10-04 22:23:00'
mysql> SELECT FROM_UNIXTIME(875996580) + 0;
-> 19971004222300
mysql> SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(),
-> '%Y %D %M %h:%i:%s %x');
-> '2003 6th August 06:22:58 2003'
- GET_FORMAT(DATE|TIME|DATETIME, 'EUR'|'USA'|'JIS'|'ISO'|'INTERNAL')
返回一个格式字符串。这个函数在同DATE_FORMAT() 及STR_TO_DATE() 函数结合时很有用。
第一个参数的3 个可能值和第二个参数的5 个可能值产生 15 个可能格式字符串 ( 对于使用的说明符,请参见DATE_FORMAT() 函数说明表 ) 。
函数调用 |
结果 |
GET_FORMAT(DATE,'USA') |
'%m.%d.%Y' |
GET_FORMAT(DATE,'JIS') |
'%Y-%m-%d' |
GET_FORMAT(DATE,'ISO') |
'%Y-%m-%d' |
GET_FORMAT(DATE,'EUR') |
'%d.%m.%Y' |
GET_FORMAT(DATE,'INTERNAL') |
'%Y%m%d' |
GET_FORMAT(DATETIME,'USA') |
'%Y-%m-%d-%H.%i.%s' |
GET_FORMAT(DATETIME,'JIS') |
'%Y-%m-%d %H:%i:%s' |
GET_FORMAT(DATETIME,'ISO') |
'%Y-%m-%d %H:%i:%s' |
GET_FORMAT(DATETIME,'EUR') |
'%Y-%m-%d-%H.%i.%s' |
GET_FORMAT(DATETIME,'INTERNAL') |
'%Y%m%d%H%i%s' |
GET_FORMAT(TIME,'USA') |
'%h:%i:%s %p' |
GET_FORMAT(TIME,'JIS') |
'%H:%i:%s' |
GET_FORMAT(TIME,'ISO') |
'%H:%i:%s' |
GET_FORMAT(TIME,'EUR') |
'%H.%i.%S' |
GET_FORMAT(TIME,'INTERNAL') |
'%H%i%s' |
ISO 格式为ISO 9075, 而非ISO 8601.
也可以使用TIMESTAMP, 这时GET_FORMAT() 的返回值和DATETIME 相同。
mysql> SELECT DATE_FORMAT('2003-10-03',GET_FORMAT(DATE,'EUR'));
-> '03.10.2003'
mysql> SELECT STR_TO_DATE('10.31.2003',GET_FORMAT(DATE,'USA'));
-> '2003-10-31'
或见 13.5.3节,“SET语法” 。
- HOUR(time )
返回time 对应的小时数。对于日时值的返回值范围是从 0 到 23 。
mysql> SELECT HOUR('10:05:03');
-> 10
然而, TIME 值的范围实际上非常大, 所以HOUR 可以返回大于23 的值。
mysql> SELECT HOUR('272:59:59');
-> 272
- LAST_DAY(date )
获取一个日期或日期时间值,返回该月最后一天对应的值。若参数无效,则返回NULL 。
mysql> SELECT LAST_DAY('2003-02-05');
-> '2003-02-28'
mysql> SELECT LAST_DAY('2004-02-05');
-> '2004-02-29'
mysql> SELECT LAST_DAY('2004-01-01 01:01:01');
-> '2004-01-31'
mysql> SELECT LAST_DAY('2003-03-32');
-> NULL
- LOCALTIME, LOCALTIME()
LOCALTIME 及 LOCALTIME() 和NOW() 具有相同意义。
- LOCALTIMESTAMP, LOCALTIMESTAMP()
LOCALTIMESTAMP 和LOCALTIMESTAMP() 和NOW() 具有相同意义。
- MAKEDATE(year ,dayofyear )
给出年份值和 一年中的天数 值,返回一个日期。dayofyear 必须大于 0 ,否则结果为 NULL 。
mysql> SELECT MAKEDATE(2001,31), MAKEDATE(2001,32);
-> '2001-01-31', '2001-02-01'
mysql> SELECT MAKEDATE(2001,365), MAKEDATE(2004,365);
-> '2001-12-31', '2004-12-30'
mysql> SELECT MAKEDATE(2001,0);
-> NULL
- MAKETIME(hour ,minute ,second )
返回由hour 、 minute 和second 参数计算得出的时间值。
mysql> SELECT MAKETIME(12,15,30);
-> '12:15:30'
- MICROSECOND(expr )
从时间或日期时间表达式expr 返回微秒值,其数字范围从 0 到 999999 。
mysql> SELECT MICROSECOND('12:00:00.123456');
-> 123456
mysql> SELECT MICROSECOND('1997-12-31 23:59:59.000010');
-> 10
- MINUTE(time )
返回 time 对应的分钟数, 范围是从 0 到 59 。
mysql> SELECT MINUTE('98-02-03 10:05:03');
-> 5
- MONTH(date )
返回date 对应的月份,范围时从 1 到 12 。
mysql> SELECT MONTH('1998-02-03');
-> 2
- MONTHNAME(date )
返回date 对应月份的全名。
mysql> SELECT MONTHNAME('1998-02-05');
-> 'February '
- NOW()
返回当前日期和时间值,其格式为 'YYYY-MM-DD HH:MM:SS' 或YYYYMMDDHHMMSS , 具体格式取决于该函数是否用在字符串中或数字语境中。
mysql> SELECT NOW();
-> '1997-12-15 23:50:26'
mysql> SELECT NOW() + 0;
-> 19971215235026
在一个存储程序或触发器内, NOW() 返回一个常数时间,该常数指示了该程序或触发语句开始执行的时间。这同SYSDATE() 的运行有所不同。
- PERIOD_ADD(P ,N )
添加 N 个月至周期P ( 格式为YYMM 或YYYYMM) ,返回值的格式为 YYYYMM 。注意周期参数 P 不是 日期值。
mysql> SELECT PERIOD_ADD(9801,2);
-> 199803
- PERIOD_DIFF(P1 ,P2 )
返回周期P1 和 P2 之间的月份数。P1 和P2 的格式应该为YYMM 或YYYYMM 。注意周期参数 P1 和P2 不是 日期值。
mysql> SELECT PERIOD_DIFF(9802,199703);
-> 11
- QUARTER(date )
返回date 对应的一年中的季度值,范围是从 1 到 4 。
mysql> SELECT QUARTER('98-04-01');
-> 2
- SECOND(time )
返回time 对应的秒数, 范围是从 0 到59 。
mysql> SELECT SECOND('10:05:03');
-> 3
- SEC_TO_TIME(seconds )
返回被转化为小时、 分钟和秒数的seconds 参数值, 其格式为 'HH:MM:SS' 或HHMMSS ,具体格式根据该函数是否用在字符串或数字语境中而定。
mysql> SELECT SEC_TO_TIME(2378);
-> '00:39:38'
mysql> SELECT SEC_TO_TIME(2378) + 0;
-> 3938
- STR_TO_DATE(str ,format )
这是DATE_FORMAT() 函数的倒转。它获取一个字符串 str 和一个格式字符串format 。若格式字符串包含日期和时间部分,则 STR_TO_DATE() 返回一个 DATETIME 值, 若该字符串只包含日期部分或时间部分,则返回一个 DATE 或TIME 值。
str 所包含的日期、时间或日期时间值应该在format 指示的格式中被给定。对于可用在format 中的说明符,请参见DATE_FORMAT() 函数说明表。 所有其它的字符被逐字获取,因此不会被解释。若 str 包含一个非法日期、时间或日期时间值,则 STR_TO_DATE() 返回NULL 。同时,一个非法值会引起警告。
对日期值部分的范围检查在 11.3.1节,“DATETIME、DATE和TIMESTAMP类型” 有详细说 明。其意义是, 例如, 只要具体日期部分的范围时从 1 到 31 之间,则允许一个日期中的具体日期部分大于一个月中天数值。并且,允许“零”日期或带有0 值部分的日期。
mysql> SELECT STR_TO_DATE('00/00/0000', '%m/%d/%Y');
-> '0000-00-00'
mysql> SELECT STR_TO_DATE('04/31/2004', '%m/%d/%Y');
-> '2004-04-31'
- SUBDATE(date ,INTERVAL expr type ) SUBDATE(expr ,days )
当被第二个参数的 INTERVAL 型式调用时, SUBDATE() 和DATE_SUB() 的意义相同。对于有关INTERVAL 参数的信息, 见有关 DATE_ADD() 的讨论。
mysql> SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
-> '1997-12-02'
mysql> SELECT SUBDATE('1998-01-02', INTERVAL 31 DAY);
-> '1997-12-02'
第二个形式允许对days 使用整数值。在这些情况下,它被算作由日期或日期时间表达式 expr 中提取的天数。
mysql> SELECT SUBDATE('1998-01-02 12:00:00', 31);
-> '1997-12-02 12:00:00'
注意 不能使用格式 "%X%V" 来将一个 year-week 字符串转化为一个日期,原因是当一个星期跨越一个月份界限时,一个年和星期的组合不能标示一个唯一的年和月份。若要将year-week 转化为一个日期,则也应指定具体工作日:
mysql> select str_to_date('200442 Monday', '%X%V %W');
-> 2004-10-18
- SUBTIME(expr ,expr2 )
SUBTIME() 从expr 中提取expr2 ,然后返回结果。expr 是一个时间或日期时间表达式,而xpr2 是一个时间表达式。
mysql> SELECT SUBTIME('1997-12-31 23:59:59.999999','1 1:1:1.000002');
-> '1997-12-30 22:58:58.999997'
mysql> SELECT SUBTIME('01:00:00.999999', '02:00:00.999998');
-> '-00:59:59.999999'
- SYSDATE()
返回当前日期和时间值,格式为'YYYY-MM-DD HH:MM:SS' 或YYYYMMDDHHMMSS , 具体格式根据函数是否用在字符串或数字语境而定。
在一个存储程序或触发器中, SYSDATE() 返回其执行的时间, 而非存储成都或触发语句开始执行的时间。这个NOW() 的运作有所不同。
- TIME(expr )
提取一个时间或日期时间表达式的时间部分,并将其以字符串形式返回。
mysql> SELECT TIME('2003-12-31 01:02:03');
-> '01:02:03'
mysql> SELECT TIME('2003-12-31 01:02:03.000123');
-> '01:02:03.000123'
- TIMEDIFF(expr ,expr2 )
TIMEDIFF() 返回起始时间 expr 和结束时间expr2 之间的时间。 expr 和expr2 为时间或 date-and-time 表达式, 两个的类型必须一样。
mysql> SELECT TIMEDIFF('2000:01:01 00:00:00',
-> '2000:01:01 00:00:00.000001');
-> '-00:00:00.000001'
mysql> SELECT TIMEDIFF('1997-12-31 23:59:59.000001',
-> '1997-12-30 01:01:01.000002');
-> '46:58:57.999999'
- TIMESTAMP(expr ) , TIMESTAMP(expr ,expr2 )
对于一个单参数, 该函数将日期或日期时间表达式 expr 作为日期时间值返回. 对于两个参数, 它将时间表达式 expr2 添加到日期或日期时间表达式 expr 中,将theresult 作为日期时间值返回。
mysql> SELECT TIMESTAMP('2003-12-31');
-> '2003-12-31 00:00:00'
mysql> SELECT TIMESTAMP('2003-12-31 12:00:00','12:00:00');
-> '2004-01-01 00:00:00'
- TIMESTAMPADD(interval ,int_expr ,datetime_expr )
将整型表达式int_expr 添加到日期或日期时间表达式 datetime_expr 中。 int_expr 的单位被时间间隔参数给定,该参数必须是以下值的其中一个: FRAC_SECOND 、SECOND 、 MINUTE 、 HOUR 、 DAY 、 WEEK 、 MONTH 、 QUARTER 或 YEAR 。
可使用所显示的关键词指定Interval 值,或使用SQL_TSI_ 前缀。例如, DAY 或SQL_TSI_DAY 都是正确的。
mysql> SELECT TIMESTAMPADD(MINUTE,1,'2003-01-02');
-> '2003-01-02 00:01:00'
mysql> SELECT TIMESTAMPADD(WEEK,1,'2003-01-02');
-> '2003-01-09'
- TIMESTAMPDIFF(interval ,datetime_expr1 ,datetime_expr2 )
返回日期或日期时间表达式datetime_expr1 和datetime_expr2 the 之间的整数差。其结果的单位由interval 参数给出。interval 的法定值同TIMESTAMPADD() 函数说明中所列出的相同。
mysql> SELECT TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');
-> 3
mysql> SELECT TIMESTAMPDIFF(YEAR,'2002-05-01','2001-01-01');
-> -1
- TIME_FORMAT(time ,format )
其使用和 DATE_FORMAT() 函数相同, 然而format 字符串可能仅会包含处理小时、分钟和秒的格式说明符。其它说明符产生一个NULL 值或0 。
若time value 包含一个大于23 的小时部分,则 %H 和 %k 小时格式说明符会产生一个大于0..23 的通常范围的值。另一个小时格式说明符产生小时值模数12 。
mysql> SELECT TIME_FORMAT('100:00:00', '%H %k %h %I %l');
-> '100 100 04 04 4'
- TIME_TO_SEC(time )
返回已转化为秒的time 参数。
mysql> SELECT TIME_TO_SEC('22:23:00');
-> 80580
mysql> SELECT TIME_TO_SEC('00:39:38');
-> 2378
- TO_DAYS(date )
给定一个日期date , 返回一个天数 ( 从年份0 开始的天数 ) 。
mysql> SELECT TO_DAYS(950501);
-> 728779
mysql> SELECT TO_DAYS('1997-10-07');
-> 729669
TO_DAYS() 不用于阳历出现(1582) 前的值,原因是当日历改变时,遗失的日期不会被考虑在内。请参见 12.6节,“MySQL使用什么日历?” 。
请记住, MySQL 使用 11.3节,“日期和时间类型” 中的规则将日期中的二位数年份值转化为四位。例如, '1997-10-07' 和 '97-10-07' 被视为同样的日期:
mysql> SELECT TO_DAYS('1997-10-07'), TO_DAYS('97-10-07');
-> 729669, 729669
对于1582 年之前的日期( 或许在其它地区为下一年 ), 该函数的结果实不可靠的。详见 12.6节,“MySQL使用什么日历?” 。
- UNIX_TIMESTAMP(), UNIX_TIMESTAMP(date )
若无参数调用,则返回一个Unix timestamp ('1970-01-01 00:00:00' GMT 之后的秒数) 作为无符号整数。若用date 来调用UNIX_TIMESTAMP() ,它会将参数值以'1970-01-01 00:00:00' GMT 后的秒数的形式返回。date 可以是一个DATE 字符串、一个 DATETIME 字符串、一个 TIMESTAMP 或一个当地时间的YYMMDD 或YYYMMDD 格式的数字。
mysql> SELECT UNIX_TIMESTAMP();
-> 882226357
mysql> SELECT UNIX_TIMESTAMP('1997-10-04 22:23:00');
-> 875996580
当 UNIX_TIMESTAMP 被用在 TIMESTAMP 列时, 函数直接返回内部时戳值, 而不进行任何隐含的 “string-to-Unix-timestamp ”转化。假如你向UNIX_TIMESTAMP() 传递一个溢出日期,它会返回 0, 但请注意只有基本范围检查会被履行 ( 年份从1970 到 2037 , 月份从01 到12, 日期从 01 到31) 。
假如你想要减去 UNIX_TIMESTAMP() 列, 你或许希望删去带符号整数的结果。请参见 12.8节,“Cast函数和操作符” 。
- UTC_DATE, UTC_DATE()
返回当前 UTC 日期值,其格式为 'YYYY-MM-DD' 或 YYYYMMDD ,具体格式取决于函数是否用在字符串或数字语境中。
mysql> SELECT UTC_DATE(), UTC_DATE() + 0;
-> '2003-08-14', 20030814
- UTC_TIME, UTC_TIME()
返回当前 UTC 值,其格式为 'HH:MM:SS' 或HHMMSS ,具体格式根据该函数是否用在字符串或数字语境而定。
mysql> SELECT UTC_TIME(), UTC_TIME() + 0;
-> '18:07:53', 180753
- UTC_TIMESTAMP, UTC_TIMESTAMP()
返回当前UTC 日期及时间值,格式为 'YYYY-MM-DD HH:MM:SS' 或YYYYMMDDHHMMSS ,具体格式根据该函数是否用在字符串或数字语境而定。
mysql> SELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0;
-> '2003-08-14 18:08:04', 20030814180804
- WEEK(date [,mode ])
该函数返回date 对应的星期数。WEEK() 的双参数形式允许你指定该星期是否起始于周日或周一, 以及返回值的范围是否为从0 到53 或从1 到53 。若 mode 参数被省略,则使用default_week_format 系统自变量的值。请参见 5.3.3节,“服务器系统变量” 。
以下表说明了mode 参数的工作过程:d
|
第一天 |
|
|
Mode |
工作日 |
范围 |
Week 1 为第一周 ... |
0 |
周日 |
0-53 |
本年度中有一个周日 |
1 |
周一 |
0-53 |
本年度中有3 天以上 |
2 |
周日 |
1-53 |
本年度中有一个周日 |
3 |
周一 |
1-53 |
本年度中有3 天以上 |
4 |
周日 |
0-53 |
本年度中有3 天以上 |
5 |
周一 |
0-53 |
本年度中有一个周一 |
6 |
周日 |
1-53 |
本年度中有3 天以上 |
7 |
周一 |
1-53 |
本年度中有一个周一 |
mysql> SELECT WEEK('1998-02-20');
-> 7
mysql> SELECT WEEK('1998-02-20',0);
-> 7
mysql> SELECT WEEK('1998-02-20',1);
-> 8
mysql> SELECT WEEK('1998-12-31',1);
-> 53
注意,假如有一个日期位于前一年的最后一周, 若你不使用2 、3 、6 或7 作为mode 参数选择,则MySQL 返回 0 :
mysql> SELECT YEAR('2000-01-01'), WEEK('2000-01-01',0);
-> 2000, 0
有人或许会提出意见,认为 MySQL 对于WEEK() 函数应该返回 52 ,原因是给定的日期实际上发生在1999 年的第52 周。我们决定返回0 作为代替的原因是我们希望该函数能返回“给定年份的星期数”。这使得WEEK() 函数在同其它从日期中抽取日期部分的函数结合时的使用更加可靠。
假如你更希望所计算的关于年份的结果包括给定日期所在周的第一天,则应使用 0 、2 、5 或 7 作为mode 参数选择。
mysql> SELECT WEEK('2000-01-01',2);
-> 52
作为选择,可使用 YEARWEEK() 函数:
mysql> SELECT YEARWEEK('2000-01-01');
-> 199952
mysql> SELECT MID(YEARWEEK('2000-01-01'),5,2);
-> '52'
- WEEKDAY(date )
返回date (0 = 周一, 1 = 周二, ... 6 = 周日) 对应的工作日索引 weekday index for
mysql> SELECT WEEKDAY('1998-02-03 22:23:00');
-> 1
mysql> SELECT WEEKDAY('1997-11-05');
-> 2
- WEEKOFYEAR(date )
将该日期的阳历周以数字形式返回,范围是从1 到53 。它是一个兼容度函数,相当于WEEK(date ,3) 。
mysql> SELECT WEEKOFYEAR('1998-02-20');
-> 8
- YEAR(date )
返回date 对应的年份, 范围是从1000 到9999 。
mysql> SELECT YEAR('98-02-03');
-> 1998
- YEARWEEK(date ), YEARWEEK(date ,start )
返回一个日期对应的年或周。start 参数的工作同 start 参数对 WEEK() 的工作相同。结果中的年份可以和该年的第一周和最后一周对应的日期参数有所不同。
mysql> SELECT YEARWEEK('1987-01-01');
-> 198653
注意,周数和WEEK() 函数队可选参数0 或 1 可能会返回的(0) w 有所不同,原因是此时 WEEK() 返回给定年份的语境中的周。
-
-> '1997-10-07'