首页 > 数据库 > > 12.7 date 和 time 函数
参考官方文档:
这是一个使用日期函数的示例。 以下查询选择具有date_col值在最近30天内的所有行:
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()假定它的参数是当前时区中的日期时间值。
某些日期函数可以与“零”日期或不完全日期(如“2001-11-00”)一起使用,而其他日期函数则不能。 提取日期部分的函数通常与不完全日期一起工作,因此可以返回0,否则得到非零值。 例如:
mysql> SELECT DAYOFMONTH('2001-11-00'), MONTH('2005-00-00');
-> 0, 0
其他函数需要完整的日期,并在不完全日期返回NULL。 这些包括执行日期算术的函数或将日期的部分映射到名称的函数。 例如:
CONVERT_TZ(), DATE_ADD(), DATE_SUB(), DAYOFYEAR(), LAST_DAY() (允许一天的一部分零), TIMESTAMPDIFF(), TO_DAYS(), TO_SECONDS(), WEEK(), WEEKDAY(), WEEKOFYEAR(), YEARWEEK().
支持TIME,DATETIME和TIMESTAMP值的小数秒,精度高达微秒。 带时态参数的函数接受小数秒的值。 时间函数的返回值包括适当的小数秒。
ADDDATE(date,INTERVALexprunit),ADDDATE(expr,days)
当用第二个参数的INTERVAL形式调用时,ADDDATE()是DATE_ADD()的同义词。 相关函数SUBDATE()是DATE_SUB()的同义词。 有关INTERVAL单元参数的信息,请参阅关于DATE_ADD()的讨论。
mysql> SELECT DATE_ADD('2008-01-02', INTERVAL 31 DAY);
-> '2008-02-02'
mysql> SELECT ADDDATE('2008-01-02', INTERVAL 31 DAY);
-> '2008-02-02'
当使用第二个参数的天数形式调用时,MySQL将其视为要添加到expr的整数天。
mysql> SELECT ADDDATE('2008-01-02', 31);
-> '2008-02-02'
--这里如果是负数值,表示减多少天。
ADDTIME(expr1,expr2)
ADDTIME()将expr2添加到expr1并返回结果。 expr1是时间或日期时间表达式,expr2是时间表达式。
mysql> SELECT ADDTIME('2007-12-31 23:59:59.999999', '1 1:1:1.000002');
-> '2008-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.1.10节“MySQL服务器时区支持”中所述进行指定。 如果参数无效,此函数返回NULL。
如果该值在从from_tz转换为UTC时超出了TIMESTAMP类型的支持范围,则不会发生转换。 第11.1.2节“日期和时间类型概述”中介绍了TIMESTAMP范围。
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.1.10节“MySQL服务器时区支持”。
CURDATE()
将当前日期作为'YYYY-MM-DD'或YYYYMMDD格式的值返回,具体取决于该函数是在字符串还是数字上下文中使用。
mysql> SELECT CURDATE();
-> '2008-06-13'
mysql> SELECT CURDATE() + 0;
-> 20080613
--如果 和数字运算日期天数,那么返回的是数字类型的格式值。
CURRENT_DATE, CURRENT_DATE()
CURRENT_DATE和CURRENT_DATE()是CURDATE()的同义词。
CURRENT_TIME, CURRENT_TIME([fsp])
CURRENT_TIME和CURRENT_TIME()是CURTIME()的同义词。
CURRENT_TIMESTAMP,CURRENT_TIMESTAMP([fsp])
CURRENT_TIMESTAMP和CURRENT_TIMESTAMP()是NOW()的同义词。
CURTIME([fsp])
根据函数是在字符串还是数字上下文中使用,以“HH:MM:SS”或HHMMSS格式的值返回当前时间。 该值以当前时区表示。
如果给出的fsp参数指定从0到6的分数秒精度,则返回值包含该许多数字的小数部分。
mysql> SELECT CURTIME();
-> '23:50:26'
mysql> SELECT CURTIME() + 0; -
> 235026.000000
DATE(expr)
提取日期或日期时间表达式expr的日期部分。
mysql> SELECT DATE('2003-12-31 01:02:03');
-> '2003-12-31'
DATEDIFF(expr1,expr2)
DATEDIFF()返回expr1 - expr2,表示为从一个日期到另一个日期的值。 expr1和expr2是日期或日期和时间表达式。 计算中只使用数值的日期部分。
mysql> SELECT DATEDIFF('2007-12-31 23:59:59','2007-12-30');
-> 1
mysql> SELECT DATEDIFF('2010-11-30 23:59:59','2010-12-31');
-> -31
DATE_ADD(date,INTERVAL expr unit),DATE_SUB(date,INTERVAL expr unit)
这些函数执行日期算术。 date参数指定开始日期或日期时间值。 expr是一个表达式,指定要从开始日期添加或减去的时间间隔值。 expr是一个字符串; 它可能以 - 的负数间隔。 unit是一个关键字,用于指示表达式应被解释的单位。
INTERVAL关键字和unit说明符不区分大小写。
下表显示了每个单位值的expr参数的预期形式。

返回值取决于参数:
如果第一个参数是DATETIME(或TIMESTAMP)值,或者第一个参数是DATE,并且单位值使用HOURS,MINUTES或SECONDS,则为DATETIME。
否则是字符串
为了确保结果是DATETIME,可以使用CAST()将第一个参数转换为DATETIME。
MySQL允许在expr格式中使用任何标点分隔符。 表中显示的是建议的分隔符。 如果date参数是DATE值并且您的计算仅包含YEAR,MONTH和DAY部分(即没有时间部分),则结果为DATE值。 否则,结果是一个DATETIME值。
日期运算也可以使用INTERVAL和+或 - 运算符一起执行:
date + INTERVAL expr unit
date - INTERVAL expr unit
如果另一侧的表达式是date或datetime值,则INTERVAL expr unit在+运算符的任一侧都是允许的。 对于 - 运算符,只允许在右侧使用INTERVAL expr单元,因为从 interval 中减去日期或日期时间值是没有意义的。
mysql> SELECT '2008-12-31 23:59:59' + INTERVAL 1 SECOND;
-> '2009-01-01 00:00:00'
mysql> SELECT INTERVAL 1 DAY + '2008-12-31';
-> '2009-01-01'
mysql> SELECT '2005-01-01' - INTERVAL 1 SECOND;
-> '2004-12-31 23:59:59'
mysql> SELECT DATE_ADD('2000-12-31 23:59:59', INTERVAL 1 SECOND);
-> '2001-01-01 00:00:00'
mysql> SELECT DATE_ADD('2010-12-31 23:59:59', INTERVAL 1 DAY);
-> '2011-01-01 23:59:59'
mysql> SELECT DATE_ADD('2100-12-31 23:59:59', INTERVAL '1:1' MINUTE_SECOND);
-> '2101-01-01 00:01:00'
mysql> SELECT DATE_SUB('2005-01-01 00:00:00', INTERVAL '1 1:1:1' DAY_SECOND);
-> '2004-12-30 22:58:59'
mysql> SELECT DATE_ADD('1900-01-01 00:00:00', INTERVAL '-1 10' DAY_HOUR);
-> '1899-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'
如果您指定的间隔值太短(不包括unit关键字所期望的所有间隔部分),MySQL会假定您已经忽略了间隔值的最左边部分。 例如,如果您指定DAY_SECOND的单位,则expr的值预计会有天,小时,分钟和秒部分。 如果你指定了一个像'1:10'这样的值,那么MySQL假定缺少日期和小时部分,并且该值表示分钟和秒。 换句话说,'1:10'DAY_SECOND被解释为'1:10'MINUTE_SECOND。 这类似于MySQL将TIME值解释为表示经过时间而不是一天的时间的方式。
由于expr被视为字符串,因此如果使用INTERVAL指定非字符串值,请注意。 例如,如果间隔指定符为HOUR_MINUTE,则6/4的计算结果为1.5000,并被视为1小时,5000分钟:
mysql> SELECT 6/4;
-> 1.5000
mysql> SELECT DATE_ADD('2009-01-01', INTERVAL 6/4 HOUR_MINUTE);
-> '2009-01-04 12:20:00'
为了确保按照您的预期解释区间值,可以使用CAST()操作。 将6/4视为1小时5分钟,将其转换为具有单个小数位的DECIMAL值:
mysql> SELECT CAST(6/4 AS DECIMAL(3,1));
-> 1.5
mysql> SELECT DATE_ADD('1970-01-01 12:00:00', INTERVAL CAST(6/4 AS DECIMAL(3,1)) HOUR_MINUTE);
-> '1970-01-01 13:05:00'
如果添加或减去包含时间部分的日期值,结果会自动转换为日期时间值:
mysql> SELECT DATE_ADD('2013-01-01', INTERVAL 1 DAY);
-> '2013-01-02'
mysql> SELECT DATE_ADD('2013-01-01', INTERVAL 1 HOUR);
-> '2013-01-01 01:00:00'
如果您添加MONTH,YEAR_MONTH或YEAR且结果日期的日期大于新月份的最大日期,则该日期将调整为新月份中的最大日期:
mysql> SELECT DATE_ADD('2009-01-30', INTERVAL 1 MONTH);
-> '2009-02-28'
日期算术运算需要完整的日期,并且不适用于诸如'2006-07-00'之类的不完整日期或格式错误的日期:
mysql> SELECT DATE_ADD('2006-07-00', INTERVAL 1 DAY);
-> NULL mysql> SELECT '2005-03-32' + INTERVAL 1 MONTH;
-> NULL
DATE_FORMAT(date,format)
根据格式字符串格式化日期值。
格式字符串中可以使用以下说明符。 格式说明符字符前需要%字符。
Specifier
Description
%a
Abbreviated weekday name (Sun..Sat)
%b
Abbreviated month name (Jan..Dec)
%c
Month, numeric (0..12)
%D
Day of the month with English suffix (0th, 1st, 2nd, 3rd, …)
%d
Day of the month, numeric (00..31)
%e
Day of the month, numeric (0..31)
%f
Microseconds (000000..999999)
%H
Hour (00..23)
%h
Hour (01..12)
%I
Hour (01..12)
%i
Minutes, numeric (00..59)
%j
Day of year (001..366)
%k
Hour (0..23)
%l
Hour (1..12)
%M
Month name (January..December)
%m
Month, numeric (00..12)
%p
AM or PM
%r
Time, 12-hour (hh:mm:ss followed by AM or PM)
%S
Seconds (00..59)
%s
Seconds (00..59)
%T
Time, 24-hour (hh:mm:ss)
%U
Week (00..53), where Sunday is the first day of the week;WEEK() mode 0
%u
Week (00..53), where Monday is the first day of the week;WEEK() mode 1
%V
Week (01..53), where Sunday is the first day of the week;WEEK() mode 2; used with %X
%v
Week (01..53), where Monday is the first day of the week;WEEK() mode 3; used with %x
%W
Weekday name (Sunday..Saturday)
%w
Day of the week (0=Sunday..6=Saturday)
%X
Year for the week where Sunday is the first day of the week, numeric, four digits; used with %V
%x
Year for the week, where Monday is the first day of the week, numeric, four digits; used with %v
%Y
Year, numeric, four digits
%y
Year, numeric (two digits)
%%
A literal % character
%x
x, for any “x” not listed above
由于MySQL允许存储诸如“2014-00-00”之类的不完整日期,因此月份和日期说明符的范围从零开始。
用于日期和月份名称和缩写的语言由lc_time_names系统变量(第10.15节“MySQL服务器区域设置支持”)的值控制。
对于%U,%u,%V和%v说明符,请参阅WEEK()函数的说明以获取关于模式值的信息。 该模式会影响星期编号的发生。
DATE_FORMAT()返回一个字符串,其中包含由character_set_connection和collation_connection给出的字符集和排序规则,以便它可以返回包含非ASCII字符的月份和星期几名称。
mysql> SELECT DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y');
-> 'Sunday October 2009'
mysql> SELECT DATE_FORMAT('2007-10-04 22:23:00', '%H:%i:%s');
-> '22:23:00'
mysql> SELECT DATE_FORMAT('1900-10-04 22:23:00','%D %y %a %d %m %b %j');
-> '4th 00 Thu 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'
mysql> SELECT DATE_FORMAT('2006-06-00', '%d');
-> '00'
DATE_SUB(date,INTERVALexprunit)
请参阅DATE_ADD()的说明。
DAY(date)
DAY()是DAYOFMONTH()的同义词。
DAYNAME(date)
返回日期的工作日名称。 用于名称的语言由lc_time_names系统变量的值控制(第10.15节“MySQL服务器区域设置支持”)。
mysql> SELECT DAYNAME('2007-02-03');
-> 'Saturday'
DAYOFMONTH(date)
返回日期的月份的day,范围为1到31,或者对于日期(例如“0000-00-00”或“2008-00-00”)的日期为零的日期返回0。
mysql> SELECT DAYOFMONTH('2007-02-03');
-> 3
DAYOFWEEK(date)
返回日期的工作日索引(1 =星期日,2 =星期一,...,7 =星期六)。 这些索引值对应于ODBC标准。
mysql> SELECT DAYOFWEEK('2007-02-03');
-> 7
DAYOFYEAR(date)
返回日期的一年中的一天,范围为1到366。
mysql> SELECT DAYOFYEAR('2007-02-03');
-> 34
EXTRACT(unitFROMdate)
EXTRACT()函数使用与DATE_ADD()或DATE_SUB()相同类型的单位说明符,但从日期中提取部分而不是执行日期算术。
mysql> SELECT EXTRACT(YEAR FROM '2009-07-02');
-> 2009
mysql> SELECT EXTRACT(YEAR_MONTH FROM '2009-07-02 01:02:03');
-> 200907
mysql> SELECT EXTRACT(DAY_MINUTE FROM '2009-07-02 01:02:03');
-> 20102
mysql> SELECT EXTRACT(MICROSECOND FROM '2003-01-02 10:30:00.000123');
-> 123
FROM_DAYS(N)
给定第N天,返回DATE值。
mysql> SELECT FROM_DAYS(730669);
-> '2000-07-03'
在旧日期中谨慎使用FROM_DAYS()。 它不适用于公历出现之前的值(1582)。
FROM_UNIXTIME(unix_timestamp),FROM_UNIXTIME(unix_timestamp,format)
根据函数是在字符串还是数字上下文中使用,以“YYYY-MM-DD HH:MM:SS”或YYYYMMDDHHMMSS格式返回unix_timestamp参数的表示形式。 该值以当前时区表示。 unix_timestamp是一个内部时间戳值,例如由UNIX_TIMESTAMP()函数产生的值。
如果给出格式,则结果将根据格式字符串格式化,格式字符串的使用方式与DATE_FORMAT()函数的条目中列出的方式相同。
mysql> SELECT FROM_UNIXTIME(1447430881);
-> '2015-11-13 10:08:01'
mysql> SELECT FROM_UNIXTIME(1447430881) + 0;
-> 20151113100801
mysql> SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(), '%Y %D %M %h:%i:%s %x');
-> '2015 13th November 10:08:01 2015'
注意:如果使用UNIX_TIMESTAMP()和FROM_UNIXTIME()在TIMESTAMP值和Unix时间戳值之间进行转换,则转换是有损的,因为映射在两个方向上都不是一一对应的。 有关详细信息,请参阅UNIX_TIMESTAMP()函数的说明。
GET_FORMAT({DATE|TIME|DATETIME}, {'EUR'|'USA'|'JIS'|'ISO'|'INTERNAL'})
返回格式字符串。 此函数与DATE_FORMAT()和STR_TO_DATE()函数结合使用非常有用。
第一个和第二个参数的可能值导致几种可能的格式字符串(对于使用的说明符,请参阅DATE_FORMAT()函数描述中的表格)。 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'
HOUR(time)
返回时间的小时。 对于时间值,返回值的范围是0到23。 但是,TIME值的范围实际上要大得多,所以HOUR可以返回大于23的值。
mysql> SELECT HOUR('10:05:03');
-> 10
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([fsp])
LOCALTIME和LOCALTIME()是NOW()的同义词。
LOCALTIMESTAMP, LOCALTIMESTAMP([fsp])
LOCALTIMESTAMP和LOCALTIMESTAMP()是NOW()的同义词。
MAKEDATE(year,dayofyear)
返回给定年份和日期值的日期。 dayofyear必须大于0或结果为NULL。
mysql> SELECT MAKEDATE(2011,31), MAKEDATE(2011,32); -> '2011-01-31', '2011-02-01'
mysql> SELECT MAKEDATE(2011,365), MAKEDATE(2014,365);
-> '2011-12-31', '2014-12-31'
mysql> SELECT MAKEDATE(2011,0);
-> NULL
MAKETIME(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('2009-12-31 23:59:59.000010');
-> 10
MINUTE(time)
返回时间分钟,范围为0到59
mysql> SELECT MINUTE('2008-02-03 10:05:03');
-> 5
MONTH(date)
返回日期的月份,1月至12月的范围为1至12,对于包含月份为零的日期(如“0000-00-00”或“2008-00-00”),返回0。
mysql> SELECT MONTH('2008-02-03');
-> 2
MONTHNAME(date)
返回日期的月份的全名。 用于名称的语言由lc_time_names系统变量的值控制
mysql> SELECT MONTHNAME('2008-02-03');
-> 'February'
NOW([fsp])
根据函数是在字符串还是数字上下文中使用,将当前日期和时间返回为'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式的值。 该值以当前时区表示。
如果给出的fsp参数指定从0到6的分数秒精度,则返回值包含该许多数字的小数部分。
mysql> SELECT NOW();
-> '2007-12-15 23:50:26'
mysql> SELECT NOW() + 0;
-> 20071215235026.000000
NOW()返回一个常量时间,表示语句开始执行的时间。 (在存储的函数或触发器中,NOW()返回函数或触发语句开始执行的时间。)这与SYSDATE()的行为不同,后者返回执行的确切时间。
mysql> SELECT NOW(), SLEEP(2), NOW();
+---------------------+----------+---------------------+
| NOW() | SLEEP(2) | NOW() |
+---------------------+----------+---------------------+
| 2006-04-12 13:47:36 | 0 | 2006-04-12 13:47:36 |
+---------------------+----------+---------------------+
mysql> SELECT SYSDATE(), SLEEP(2), SYSDATE();
+---------------------+----------+---------------------+
| SYSDATE() | SLEEP(2) | SYSDATE() |
+---------------------+----------+---------------------+
| 2006-04-12 13:47:44 | 0 | 2006-04-12 13:47:46 |
+---------------------+----------+---------------------+
另外,SET TIMESTAMP语句影响NOW()返回的值,但不影响SYSDATE()。 这意味着二进制日志中的时间戳设置对SYSDATE()的调用没有影响。 将时间戳设置为非零值会导致每个随后的NOW()调用返回该值。 将时间戳设置为零将取消此效果,以便NOW()再次返回当前的日期和时间。
PERIOD_ADD(P,N)
将N个月添加到P(格式为YYMM或YYYYMM)。 以YYYYMM格式返回一个值。 请注意,周期参数P不是日期值。
mysql> SELECT PERIOD_ADD(200801,2);
-> 200803
PERIOD_DIFF(P1,P2)
返回期间P1和P2之间的月数。 P1和P2的格式应该是YYMM或YYYYMM。 请注意,周期参数P1和P2不是日期值。
mysql> SELECT PERIOD_DIFF(200802,200703);
-> 11
QUARTER(date)
返回日期的一年中的季度,范围为1到4。
mysql> SELECT QUARTER('2008-04-01');
-> 2
SECOND(time)
返回time的秒数,范围从0-59
mysql> SELECT SECOND('10:05:03'); -> 3
SEC_TO_TIME(seconds)
返回秒参数,将其转换为小时,分钟和秒,作为TIME值。 结果的范围受限于TIME数据类型的范围。 如果参数与该范围之外的值相对应,则会发生警告。
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和格式字符串格式。 如果格式字符串同时包含日期和时间部分,则STR_TO_DATE()返回DATETIME值;如果字符串仅包含日期或时间部分,则返回DATE或TIME值。 如果从str中提取的日期,时间或日期时间值不合法,则STR_TO_DATE()返回NULL并产生警告。
服务器扫描str尝试匹配format。 格式字符串可以包含以%开头的文字字符和格式说明符。 格式中的文字字符必须在字符串中匹配。 格式中的格式说明符必须与str中的日期或时间部分匹配。 对于格式中可以使用的说明符,请参阅DATE_FORMAT()函数说明。
mysql> SELECT STR_TO_DATE('01,5,2013','%d,%m,%Y');
-> '2013-05-01'
mysql> SELECT STR_TO_DATE('May 1, 2013','%M %d,%Y');
-> '2013-05-01'
扫描从str的开始处开始,如果发现格式不匹配,则失败。 str结尾的额外字符被忽略。
mysql> SELECT STR_TO_DATE('a09:30:17','a%h:%i:%s');
-> '09:30:17'
mysql>SELECT STR_TO_DATE('a09:30:17','%h:%i:%s');
-> NULL
mysql> SELECT STR_TO_DATE('09:30:17a','%h:%i:%s');
-> '09:30:17'
未指定的日期或时间部分的值为0,因此在str中未完整指定的值会产生一些或全部部分设置为0的结果:
mysql> SELECT STR_TO_DATE('abc','abc');
-> '0000-00-00'
mysql> SELECT STR_TO_DATE('9','%m');
-> '0000-09-00'
mysql> SELECT STR_TO_DATE('9','%s');
-> '00:00:09'
日期值部分的范围检查如第11.3.1节“DATE,DATETIME和TIMESTAMP类型”中所述。 这意味着,例如,除非SQL模式被设置为禁止这些值,否则允许“零”日期或部分值为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'
如果启用NO_ZERO_DATE或NO_ZERO_IN_DATE SQL模式,则不允许零日期或部分日期。 在这种情况下,STR_TO_DATE()返回NULL并生成警告:
mysql> SET sql_mode = '';
mysql> SELECT STR_TO_DATE('15:35:00', '%H:%i:%s');
+-------------------------------------+
| STR_TO_DATE('15:35:00', '%H:%i:%s') |
+-------------------------------------+
| 15:35:00 |
+-------------------------------------+
mysql> SET sql_mode = 'NO_ZERO_IN_DATE';
mysql> SELECT STR_TO_DATE('15:35:00', '%h:%i:%s');
+-------------------------------------+
| STR_TO_DATE('15:35:00', '%h:%i:%s') |
+-------------------------------------+
| NULL |
+-------------------------------------+
mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
Level: Warning
Code: 1411
Message: Incorrect datetime value: '15:35:00' for function str_to_date
注意:
您无法使用格式“%X%V”将年-周字符串转换为日期,因为如果该周与月份边界交叉,年份和周的组合不会唯一标识年份和月份。 要将年-周转换为日期,您还应该指定星期几:
mysql> SELECT STR_TO_DATE('200442 Monday', '%X%V %W');
-> '2004-10-18'
SUBDATE(date,INTERVALexprunit),SUBDATE(expr,days)
当用第二个参数的INTERVAL形式调用时,SUBDATE()是DATE_SUB()的同义词。 有关INTERVAL单元参数的信息,请参阅关于DATE_ADD()的讨论。
mysql> SELECT DATE_SUB('2008-01-02', INTERVAL 31 DAY);
-> '2007-12-02'
mysql> SELECT SUBDATE('2008-01-02', INTERVAL 31 DAY);
-> '2007-12-02'
第二种形式允许使用天数的整数值。 在这种情况下,它被解释为从日期或日期时间表达式expr中减去的天数。
mysql> SELECT SUBDATE('2008-01-02 12:00:00', 31);
-> '2007-12-02 12:00:00'
SUBTIME(expr1,expr2)
SUBTIME()返回表达式expr1 - expr2,其格式与expr1相同。 expr1是时间或日期时间表达式,expr2是时间表达式。
mysql> SELECT SUBTIME('2007-12-31 23:59:59.999999','1 1:1:1.000002');
-> '2007-12-30 22:58:58.999997'
mysql> SELECT SUBTIME('01:00:00.999999', '02:00:00.999998');
-> '-00:59:59.999999'
SYSDATE([fsp])
根据函数是在字符串还是数字上下文中使用,将当前日期和时间返回为'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式的值。
如果给出的fsp参数指定从0到6的分数秒精度,则返回值包含该数字的小数部分。
SYSDATE()返回它执行的时间。 这与NOW()的行为不同,后者返回一个指示语句开始执行的时间的常量时间。 (在存储函数或触发器中,NOW()返回函数或触发语句开始执行的时间。)
mysql> SELECT NOW(), SLEEP(2), NOW();
+---------------------+----------+---------------------+
| NOW() | SLEEP(2) | NOW() |
+---------------------+----------+---------------------+
| 2006-04-12 13:47:36 | 0 | 2006-04-12 13:47:36 |
+---------------------+----------+---------------------+
mysql> SELECT SYSDATE(), SLEEP(2), SYSDATE();
+---------------------+----------+---------------------+
| SYSDATE() | SLEEP(2) | SYSDATE() |
+---------------------+----------+---------------------+
| 2006-04-12 13:47:44 | 0 | 2006-04-12 13:47:46 |
+---------------------+----------+---------------------+
因为SYSDATE()即使在同一个语句中也可以返回不同的值,并且不受SET TIMESTAMP影响,所以如果使用基于语句的二进制日志记录,则它是不确定的,因此对于复制不安全。 如果这是一个问题,您可以使用基于行的日志记录
或者,您可以使用--sysdate-is-now选项来使SYSDATE()成为NOW()的别名。 如果master和slave都使用此选项,则此功能起作用。
SYSDATE()的不确定性也意味着索引不能用于评估引用它的表达式。
TIME(expr)
提取time或datetime表达式expr的时间部分并将其作为字符串返回。
这个函数对于基于语句的复制是不安全的。 如果在binlog_format设置为STATEMENT时使用此函数,则会记录一条警告。
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(expr1,expr2)
TIMEDIFF()返回表达为expr1 - expr2的时间值。 expr1和expr2是时间或日期和时间表达式,但都必须是相同的类型。
TIMEDIFF()返回的结果仅限于TIME值允许的范围。 或者,您可以使用函数TIMESTAMPDIFF()和UNIX_TIMESTAMP(),它们都返回整数。
mysql> SELECT TIMEDIFF('2000:01:01 00:00:00','2000:01:01 00:00:00.000001');
-> '-00:00:00.000001'
mysql> SELECT TIMEDIFF('2008-12-31 23:59:59.000001','2008-12-30 01:01:01.000002');
-> '46:58:57.999999'
TIMESTAMP(expr), TIMESTAMP(expr1,expr2)
使用单个参数,此函数将date或datetime表达式expr作为日期时间值返回。 使用两个参数,它将时间表达式expr2添加到日期或日期时间表达式expr1,并将结果作为日期时间值返回。
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(unit,interval,datetime_expr)
将整数间隔表达式或datetime表达式datetime_expr添加到date。 间隔的单位由单位参数给出,它应该是以下值之一:MICROSECOND(微秒),SECOND,MINUTE,HOUR,DAY,WEEK,MONTH,QUARTER或YEAR。
unit值可以使用其中一个关键字指定,或使用前缀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(unit,datetime_expr1,datetime_expr2)
返回datetime_expr2 - datetime_expr1,其中datetime_expr1和datetime_expr2是日期或日期时间表达式。 一个表达可以是日期,另一个是日期时间; 在必要时日期值被视为具有时间部分'00:00:00'的日期时间。 结果的单位(整数)由单位参数给出。 unit的合法值与TIMESTAMPADD()函数描述中列出的相同
mysql> SELECT TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');
-> 3
mysql> SELECT TIMESTAMPDIFF(YEAR,'2002-05-01','2001-01-01');
-> -1
mysql> SELECT TIMESTAMPDIFF(MINUTE,'2003-02-01','2003-05-01 12:05:55');
-> 128885
注意:
当使用2个参数调用时,此函数的date或datetime参数的顺序与TIMESTAMP()函数的顺序相反。
TIME_FORMAT(time,format)
这与DATE_FORMAT()函数类似,但format字符串可能只包含小时,分钟,秒和微秒的格式说明符。 其他说明符产生一个NULL值或0。
如果time值包含大于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)
返回时间参数,转换为秒。
mysql> SELECT TIME_TO_SEC('22:23:00');
-> 80580
mysql> SELECT TIME_TO_SEC('00:39:38');
-> 2378
TO_DAYS(date)
给定一个日期日期,返回一个日期号(从0年开始的天数)。
mysql> SELECT TO_DAYS(950501);
-> 728779
mysql> SELECT TO_DAYS('2007-10-07');
-> 733321
TO_DAYS()不适用于公历出现之前的值(1582),因为它没有考虑到日历更改时丢失的日期。 对于1582年之前的日期(以及可能在其他地区的较晚一年),此功能的结果不可靠。 有关详细信息,请参见第12.8节“MySQL使用的日历”。
请记住,MySQL使用第11.3节“日期和时间类型”中的规则将日期中的两位数年份值转换为四位数形式。 例如,'2008-10-07'和'08-10-07'被视为相同的日期:
mysql> SELECT TO_DAYS('2008-10-07'), TO_DAYS('08-10-07'); -> 733687, 733687
在MySQL中,零日期被定义为'0000-00-00',即使这个日期本身被认为是无效的。 这意味着对于'0000-00-00'和'0000-01-01',TO_DAYS()返回如下所示的值:
mysql> SELECT TO_DAYS('0000-00-00');
+-----------------------+
| to_days('0000-00-00') |
+-----------------------+
| NULL |
+-----------------------+
1 row in set, 1 warning (0.00 sec)
mysql> SHOW WARNINGS;
+---------+------+----------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------+
| Warning | 1292 | Incorrect datetime value: '0000-00-00' |
+---------+------+----------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT TO_DAYS('0000-01-01');
+-----------------------+
| to_days('0000-01-01') |
+-----------------------+
| 1 |
+-----------------------+
1 row in set (0.00 sec)
无论是否启用ALLOW_INVALID_DATES SQL服务器模式,情况都是如此。
TO_SECONDS(expr)
给定日期或日期时间表达式,返回自第0年以来的秒数。如果expr不是有效的日期或日期时间值,则返回NULL。
mysql> SELECT TO_SECONDS(950501);
-> 62966505600
mysql> SELECT TO_SECONDS('2009-11-29');
-> 63426672000
mysql> SELECT TO_SECONDS('2009-11-29 13:43:32');
-> 63426721412
mysql> SELECT TO_SECONDS( NOW() );
-> 63426721458
与TO_DAYS()类似,TO_SECONDS()不适用于公历日历(1582年)出现之前的值,因为它不考虑日历更改时丢失的日期。 对于1582年之前的日期(以及可能在其他地区的较晚一年),此功能的结果不可靠。
像TO_DAYS(),TO_SECONDS()一样,使用第11.3节“日期和时间类型”中的规则将日期中的两位数年份值转换为四位数形式。
在MySQL中,零日期被定义为'0000-00-00',即使这个日期本身被认为是无效的。 这意味着对于'0000-00-00'和'0000-01-01',TO_SECONDS()返回如下所示的值:
mysql> SELECT TO_SECONDS('0000-00-00');
+--------------------------+
| TO_SECONDS('0000-00-00') |
+--------------------------+
| NULL |
+--------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> SHOW WARNINGS;
+---------+------+----------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------+
| Warning | 1292 | Incorrect datetime value: '0000-00-00' |
+---------+------+----------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT TO_SECONDS('0000-01-01');
+--------------------------+
| TO_SECONDS('0000-01-01') |
+--------------------------+
| 86400 |
+--------------------------+
1 row in set (0.00 sec)
无论是否启用ALLOW_INVALID_DATES SQL服务器模式,情况都是如此。
UNIX_TIMESTAMP(), UNIX_TIMESTAMP(date)
如果不带参数调用,则返回一个Unix时间戳(从'1970-01-01 00:00:00'UTC开始的秒数)。 如果未给出参数或参数不包含小数秒部分,则返回值为整数;如果给定参数包含小数秒部分,则返回值为DECIMAL。
如果使用date参数调用UNIX_TIMESTAMP(),则它会返回参数的值,自UTC 1970年1月1日00:00:00起的秒。 date参数可以是DATE,DATETIME或TIMESTAMP字符串,也可以是YYMMDD,YYMMDDHHMMSS,YYYYMMDD或YYYYMMDDHHMMSS格式的数字。 如果参数包含时间部分,则可以选择包含小数部分。 服务器将日期解释为当前时区中的值,并将其转换为UTC中的内部值。 客户可以按照第5.1.10节“MySQL服务器时区支持”中所述设置其时区。
mysql> SELECT UNIX_TIMESTAMP();
-> 1447431666
mysql> SELECT UNIX_TIMESTAMP('2015-11-13 10:20:19');
-> 1447431619
mysql> SELECT UNIX_TIMESTAMP('2015-11-13 10:20:19.012');
-> 1447431619.012
当在TIMESTAMP列上使用UNIX_TIMESTAMP()时,该函数将直接返回内部时间戳记值,而不会有隐式的“字符串到Unix时间戳记”转换。 如果将超出范围的日期传递给UNIX_TIMESTAMP(),则返回0.有效值范围与TIMESTAMP数据类型 相同:'1970-01-01 00:00:01.000000'到2038 -01-19 03:14:07.999999'UTC。
注意:如果使用UNIX_TIMESTAMP()和FROM_UNIXTIME()在TIMESTAMP值和Unix时间戳值之间进行转换,则转换是有损的,因为映射在两个方向上都不是一一对应的。 例如,由于本地时区的变化,两个UNIX_TIMESTAMP()可能将两个TIMESTAMP值映射到相同的Unix时间戳值。 FROM_UNIXTIME()会将该值映射回原始TIMESTAMP值中的一个。 以下是一个示例,在CET时区中使用TIMESTAMP值:
mysql> SELECT UNIX_TIMESTAMP('2005-03-27 03:00:00');
+---------------------------------------+
| UNIX_TIMESTAMP('2005-03-27 03:00:00') |
+---------------------------------------+
| 1111885200 |
+---------------------------------------+
mysql> SELECT UNIX_TIMESTAMP('2005-03-27 02:00:00');
+---------------------------------------+
| UNIX_TIMESTAMP('2005-03-27 02:00:00') |
+---------------------------------------+
| 1111885200 |
+---------------------------------------+
mysql> SELECT FROM_UNIXTIME(1111885200);
+---------------------------+
| FROM_UNIXTIME(1111885200) |
+---------------------------+
| 2005-03-27 03:00:00 |
+---------------------------+
UTC_DATE, UTC_DATE()
根据函数是在字符串还是数字上下文中使用,以“YYYY-MM-DD”或YYYYMMDD格式的值返回当前UTC日期。
mysql> SELECT UTC_DATE(), UTC_DATE() + 0;
-> '2003-08-14', 20030814
UTC_TIME, UTC_TIME([fsp])
根据函数是在字符串还是数字上下文中使用,将当前UTC时间作为'HH:MM:SS'或HHMMSS格式的值返回。
如果给出的fsp参数指定从0到6的分数秒精度,则返回值包含该许多数字的小数部分。
mysql> SELECT UTC_TIME(), UTC_TIME() + 0;
-> '18:07:53', 180753.000000
UTC_TIMESTAMP, UTC_TIMESTAMP([fsp])
根据函数是在字符串还是数字上下文中使用,将当前UTC日期和时间作为'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式的值返回。
如果给出的fsp参数指定从0到6的分数秒精度,则返回值包含该数字的小数部分。
mysql> SELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0;
-> '2003-08-14 18:08:04', 20030814180804.000000
WEEK(date[,mode])
此函数返回日期的星期编号。 WEEK()的双参数形式使您能够指定星期是从星期天还是星期一开始,以及返回值是在0到53还是从1到53的范围内。如果省略mode参数,则值 使用了default_week_format系统变量。 请参见第5.1.5节“服务器系统变量”。
下表描述了mode 参数的工作原理。

对于“今年有4天或更长时间”含义的模式值,根据ISO 8601:1988对数周进行编号:
如果包含1月1日的一周在新的一年中有4天或更多天,那么这是第1周。
否则,这是上一年的最后一周,下一周是第1周。
mysql> SELECT WEEK('2008-02-20');
-> 7
mysql> SELECT WEEK('2008-02-20',0);
-> 7
mysql> SELECT WEEK('2008-02-20',1);
-> 8
mysql> SELECT WEEK('2008-12-31',1);
-> 53
请注意,如果某个日期落在上一年的最后一周,则如果不使用2,3,6或7作为可选模式参数,则MySQL返回0:
mysql> SELECT YEAR('2000-01-01'), WEEK('2000-01-01',0);
-> 2000, 0
有人可能会说WEEK()应该返回52,因为给定的日期实际上是在1999年的第52周发生的。WEEK()返回0,所以返回值是“给定年份中的周数”。这使得 WEEK()函数与其他从日期中提取日期部分的函数结合使用时可靠。
如果您更喜欢根据包含给定日期的每周第一天的年份评估的结果,请使用0,2,5或7作为可选模式参数。
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)
返回日期的日期索引(0 =星期一,1 =星期二,... 6 =星期日)。
mysql> SELECT WEEKDAY('2008-02-03 22:23:00');
-> 6
mysql> SELECT WEEKDAY('2007-11-06');
-> 1
WEEKOFYEAR(date)
将日期的日历周作为1到53范围内的数字返回。WEEKOFYEAR()是一个与WEEK(date,3)等效的兼容性函数。
mysql> SELECT WEEKOFYEAR('2008-02-20');
-> 8
YEAR(date)
返回日期的年份,范围为1000到9999,或者对于“零”日期返回0。
mysql> SELECT YEAR('1987-01-01');
-> 1987
YEARWEEK(date), YEARWEEK(date,mode)
返回一个日期的年份和星期。 结果中的年份可能在年度第一周和最后一周的日期参数中的不同。
mode参数的工作方式与WEEK()的mode参数完全相同。 对于单参数语法,使用模式值0。 与WEEK()不同,default_week_format的值不会影响YEARWEEK()。
mysql> SELECT YEARWEEK('1987-01-01');
-> 198652
请注意,周数与WEEK()函数返回(0)可选参数0或1的值不同,因为WEEK()会返回给定年份上下文中的星期。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69946831/viewspace-3154537/ ,如需转载,请注明出处,否则将追究法律责任。