这篇博客回顾总结了sql中所有的日期时间类函数用法 。
首先来回顾一下日期时间的数据类型,这对理解函数很有帮助,因为时间处理函数的参数就是这些数据类型。
日期时间的数据类型
类型 | 大小 | 范围 | 格式 | 适用 |
---|---|---|---|---|
DATE | 3 byte | 1000-01-01/9999-12-31 | YYYY-MM-DD | 日期值 |
TIME | 3 bytes | ‘-838:59:59’/‘838:59:59’ | HH:MM:SS | 时间值或持续时间 |
YEAR | 1 bytes | 1901/2155 | YYYY | 年份值 |
DATETIME | 8 bytes | 1000-01-01 00:00:00/9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 |
TIMESTAMP | 4 bytes | 1970-01-01 00:00:00/2038 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 |
datetime 与timestamp数据比较:
二者格式相同,都包括日期和时间两部分。
区别: 除了上表中的大小,范围不一样 。约束也不同,timestramp的字段默认不为空(not null),默认值为当前时间(current_timestamp)。储存方式也不同 ,对于timestamp,它把客户端插入的时间从当前时区转化为UTC(世界标准时间)进行存储。查询时,将其又转化为客户端当前时区进行返回。而对于datetime,不做任何改变,基本上是原样输入和输出。
在总结处理时间的函数之前, 我想按照函数功能的类型将函数分成三类(函数较多,分类使得结构更清晰)。 在实际操作的过程中,我们可能对日期时间做哪些操作呢? 我认为可以分为时间的 1获取,2提取输出,3计算。
一 日期时间的获取
函数 | 功能 | 举例 |
---|---|---|
current_date(), curdate() | 当前语句执行时的日期 | ↪ \hookrightarrow ↪ |
sysdate() | 该函数执行时的日期 | ↪ \hookrightarrow ↪ |
current_time(), curtime() | 当前时间 | ↪ \hookrightarrow ↪ |
now() | 当前日期和时间 | ↪ \hookrightarrow ↪ |
current_timestamp() | 当前时间戳 ,和now()相同 | ↪ \hookrightarrow ↪ |
localtime(), localtimestamp() | 当前日期和时间 ,和now()相同 | ↪ \hookrightarrow ↪ |
utc_date() | 时间标准时间当前日期 | ↪ \hookrightarrow ↪ |
utc_time() | 时间标准时间当前使时间 | ↪ \hookrightarrow ↪ |
utc_timestamp() | 时间标准时间当前时间戳 | ↪ \hookrightarrow ↪ |
unix_timetramp() | 返回Unix时间戳, (Unix timestamp是一种时间表示方式,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。广泛被使用在Unix系统、类Unix系统中). | ↪ \hookrightarrow ↪ |
str_to_date() | 将含有日期的字符串格式化输出为datetime格式 | ↪ \hookrightarrow ↪ |
二 日期时间的提取输出
函数 | 功能 | 举例 |
---|---|---|
date() | 提取日期 | ↪ \hookrightarrow ↪ |
year() | 提取年份 | ↪ \hookrightarrow ↪ |
yearweek() | 提取年份和第几周 | ↪ \hookrightarrow ↪ |
quarter() | 提取季节 | ↪ \hookrightarrow ↪ |
month() | 提取月份 | ↪ \hookrightarrow ↪ |
monthname() | 提取月名称 | ↪ \hookrightarrow ↪ |
day() | 提取天数 | ↪ \hookrightarrow ↪ |
time() | 提取时间 HH:MM:SS | ↪ \hookrightarrow ↪ |
hour() | 提取小时 | ↪ \hookrightarrow ↪ |
minute() | 提取分钟 | ↪ \hookrightarrow ↪ |
second() | 提取秒 | ↪ \hookrightarrow ↪ |
microsecond() | 提取微秒 | ↪ \hookrightarrow ↪ |
date_format() | 格式化输出 (格式符说明 ↪ \hookrightarrow ↪) | ↪ \hookrightarrow ↪ |
time_format() | 仅格式化输出时间 ,用法与date_formate()相同 | ↪ \hookrightarrow ↪ |
get_format() | 得到特定的格式,比如get_format(date, “usa”)返回美式日期表示法 “%m.%d.%Y” , 常配合date_format, time_format使用 | ↪ \hookrightarrow ↪ |
sec_to_time() | 将秒转化为 HH:MM:SS 小时分钟秒的格式 | ↪ \hookrightarrow ↪ |
time_to_sec() | 将小时分钟秒转为秒的格式 | ↪ \hookrightarrow ↪ |
mekedate(year,N) | 输入两个参数分别年份和整数N,返回该年的第N天的date类型日期 | ↪ \hookrightarrow ↪ |
meketime(H,M,S) | 输入三个分别为小时分钟秒,返回该time类型的时间 | ↪ \hookrightarrow ↪ |
三 日期时间的计算
函数 | 功能 | 举例 |
---|---|---|
dayofyear() | 日期中该天是该年的第几天 | ↪ \hookrightarrow ↪ |
day(), dayofmonth() | 日期中该天是该月的第几天 | ↪ \hookrightarrow ↪ |
last_day() | 该月最后一天是几号(28,29,30,31其中一个) | ↪ \hookrightarrow ↪ |
dayofweek(), dayname() | 该日期是星期几? | ↪ \hookrightarrow ↪ |
weekofyear() | 该日期是该年份的第几周? | ↪ \hookrightarrow ↪ |
to_days() , from_days | 日期和天数相互转化 | ↪ \hookrightarrow ↪ |
adddate(expr,interval expr unit),date_add(expr,interval expr unit) | 日期加上一段时间是什么日期(比如今天加100天后是什么日期?) | ↪ \hookrightarrow ↪ |
subdate(), date_sub() | 减一段时间 | ↪ \hookrightarrow ↪ |
addtime(), subtime() | 两段时间相加或相减 | ↪ \hookrightarrow ↪ |
datediff(), timediff() | 两个日期或时间点的时间差, datediff()忽略day以下的单位,只计算差多少天。 timediff()计算到秒 | ↪ \hookrightarrow ↪ |
timestampdiff(unit, t1,t2) | unit = year/ month/…/second .指定最小单位等于unit时,两个时间点的差 | ↪ \hookrightarrow ↪ |
period_add(date, N) | 加N个月 | ↪ \hookrightarrow ↪ |
period_diff(date1, date2) | 计算差几个月 | ↪ \hookrightarrow ↪ |
convert_tz() | 日期时间的时区转化 | ↪ \hookrightarrow ↪ |
返回当前日期
mysql> select current_date(), curdate();
+----------------+------------+
| current_date() | curdate() |
+----------------+------------+
| 2020-09-22 | 2020-09-22 |
+----------------+------------+
返回该函数执行的日期时间
mysql> select sysdate();
+---------------------+
| sysdate() |
+---------------------+
| 2020-09-22 16:32:11 |
+---------------------+
返回当前时间
mysql> select current_time(), curtime();
+----------------+-----------+
| current_time() | curtime() |
+----------------+-----------+
| 16:33:24 | 16:33:24 |
+----------------+-----------+
返回当前日期和时间
mysql> select now(), current_timestamp(), localtime(), localtimestamp();
+---------------------+---------------------+---------------------+---------------------+
| now() | current_timestamp() | localtime() | localtimestamp() |
+---------------------+---------------------+---------------------+---------------------+
| 2020-09-22 15:34:48 | 2020-09-22 15:34:48 | 2020-09-22 15:34:48 | 2020-09-22 15:34:48 |
+---------------------+---------------------+---------------------+---------------------+
世界标准时间
mysql> select utc_date(), utc_time(), utc_timestamp(), now();--utc与北京时间差了8个小时
+------------+------------+---------------------+---------------------+
| utc_date() | utc_time() | utc_timestamp() | now() |
+------------+------------+---------------------+---------------------+
| 2020-09-22 | 13:09:53 | 2020-09-22 13:09:53 | 2020-09-22 21:09:53 |
+------------+------------+---------------------+---------------------+
1970年01月01日00时00分00秒起至现在的总秒数
mysql> select unix_timestamp(now());
+-----------------------+
| unix_timestamp(now()) |
+-----------------------+
| 1600840479 |
+-----------------------+
字符串转化为datetime格式日期
mysql> select str_to_date("时间是2020年09月01号","时间是%Y年%m月%d号") as datetime;
+------------+
| datetime |
+------------+
| 2020-09-01 |
+------------+
提取时间数据中有的部分信息
mysql> select now(), date(now()), year(now()), yearweek(now()), quarter(now()),month(now()), monthname(now());
+---------------------+-------------+-------------+-----------------+----------------+--------------+------------------+
| now() | date(now()) | year(now()) | yearweek(now()) | quarter(now()) | month(now()) | monthname(now()) |
+---------------------+-------------+-------------+-----------------+----------------+--------------+------------------+
| 2020-09-23 13:45:35 | 2020-09-23 | 2020 | 202038 | 3 | 9 | September |
+---------------------+-------------+-------------+-----------------+----------------+--------------+------------------+
提取时间数据中有的部分信息
mysql> select now(), day(now()), time(now()), hour(now()), minute(now()), second(now());
+---------------------+------------+-------------+-------------+---------------+---------------+
| now() | day(now()) | time(now()) | hour(now()) | minute(now()) | second(now()) |
+---------------------+------------+-------------+-------------+---------------+---------------+
| 2020-09-23 13:46:08 | 23 | 13:46:08 | 13 | 46 | 8 |
+---------------------+------------+-------------+-------------+---------------+---------------+
date_format格式化示例
mysql> select date_format(now(),"%Y年%m%月%d是今年的第%j天");
+------------------------------------------------+
| date_format(now(),"%Y年%m%月%d是今年的第%j天") |
+------------------------------------------------+
| 2020年09月22是今年的第266天 |
+------------------------------------------------+
time_format格式化输出时间示例
mysql> select time_format(now(), "现在时间是%h点%i分%s秒");
+----------------------------------------------+
| time_format(now(), "现在时间是%h点%i分%s秒") |
+----------------------------------------------+
| 现在时间是08点22分54秒 |
+----------------------------------------------+
get_format输出特定格式,配合date_format案例
mysql> select date_format(now(), get_format(date,"usa")) as "美式日期";
+------------+
| 美式日期 |
+------------+
| 09.22.2020 |
+------------+
秒转时间和时间转秒
mysql> select sec_to_time(3661), time_to_sec("01:01:01");
+-------------------+-------------------------+
| sec_to_time(3661) | time_to_sec("01:01:01") |
+-------------------+-------------------------+
| 01:01:01 | 3661 |
+-------------------+-------------------------+
生成日期与生成时间
mysql> select makedate(2020,266), maketime(1,2,3);
+--------------------+-----------------+
| makedate(2020,266) | maketime(1,2,3) |
+--------------------+-----------------+
| 2020-09-22 | 01:02:03 |
+--------------------+-----------------+
第几天?
mysql> select dayofyear(now()), day(now()), dayofmonth(now());
+------------------+------------+-------------------+
| dayofyear(now()) | day(now()) | dayofmonth(now()) |
+------------------+------------+-------------------+
| 266 | 22 | 22 |
+------------------+------------+-------------------+
最后一天是几号?
mysql> select last_day("2020-02-01");
+------------------------+
| last_day("2020-02-01") |
+------------------------+
| 2020-02-29 |
+------------------------+
星期几?
mysql> select dayofweek(now()), dayname(now());
+------------------+----------------+
| dayofweek(now()) | dayname(now()) |
+------------------+----------------+
| 3 | Tuesday |
+------------------+----------------+
第几周?
mysql> select weekofyear(now());
+-------------------+
| weekofyear(now()) |
+-------------------+
| 39 |
+-------------------+
日期转化为数字与其逆运算
mysql> select to_days("2020-01-01"), from_days(737790);
+-----------------------+-------------------+
| to_days("2020-01-01") | from_days(737790) |
+-----------------------+-------------------+
| 737790 | 2020-01-01 |
+-----------------------+-------------------+
adddate()第二个参数为interval expr unit时, 与date_add()完全一样 。adddate()第二参数为整数时N,默认为加N天 .
mysql> select adddate("2020-09-23", interval 10 hour), date_add("2020-09-23", interval 10 hour);
+-----------------------------------------+------------------------------------------+
| adddate("2020-09-23", interval 10 hour) | date_add("2020-09-23", interval 10 hour) |
+-----------------------------------------+------------------------------------------+
| 2020-09-23 10:00:00 | 2020-09-23 10:00:00 |
+-----------------------------------------+------------------------------------------+
mysql> select adddate("2020-09-23",100), date_add("2020-09-23", interval 100 day);
+---------------------------+------------------------------------------+
| adddate("2020-09-23",100) | date_add("2020-09-23", interval 100 day) |
+---------------------------+------------------------------------------+
| 2021-01-01 | 2021-01-01 |
+---------------------------+------------------------------------------+
subdate()与date_sub()用来减去一段时间,用法与adddate(),dateadd()完全一样
mysql> select subdate(" 2020-09-23",100), date_sub(" 2020-09-23", interval 100 day);
+----------------------------+-------------------------------------------+
| subdate(" 2020-09-23",100) | date_sub(" 2020-09-23", interval 100 day) |
+----------------------------+-------------------------------------------+
| 2020-06-15 | 2020-06-15 |
+----------------------------+-------------------------------------------+
addtime() 与subtime() 计算两段时间的和、差
mysql> select addtime("00:01:01", "00:01:01"),subtime("00:01:01", "00:01:01");
+---------------------------------+---------------------------------+
| addtime("00:01:01", "00:01:01") | subtime("00:01:01", "00:01:01") |
+---------------------------------+---------------------------------+
| 00:02:02 | 00:00:00 |
+---------------------------------+---------------------------------+
datediff()与timediff()区别在于datediff()只计算差多少天。
mysql> select datediff("2020-05-14 01:01:02","2020-05-14 01:01:01"), timediff("2020-05-14 01:01:02","2020-05-14 01:01:01");
+-------------------------------------------------------+-------------------------------------------------------+
| datediff("2020-05-14 01:01:02","2020-05-14 01:01:01") | timediff("2020-05-14 01:01:02","2020-05-14 01:01:01") |
+-------------------------------------------------------+-------------------------------------------------------+
| 0 | 00:00:01 |
+-------------------------------------------------------+-------------------------------------------------------+
timestampdiff(unit,t1,t2)可以指定最小时间单位计算t2-t1。 若unit=day,等价于-datediff(); 若unit=second,等价于-timediff().注意这里datediff() 与timediff()都是 t1-t2 。
mysql> select timestampdiff(month,"2020-06-14 01:01:02","2020-05-14 01:01:01");
+------------------------------------------------------------------+
| timestampdiff(month,"2020-06-14 01:01:02","2020-05-14 01:01:01") |
+------------------------------------------------------------------+
| -1 |
+------------------------------------------------------------------+
mysql> select timestampdiff(day,"2020-06-14 01:01:02","2020-05-14 01:01:01");
+----------------------------------------------------------------+
| timestampdiff(day,"2020-06-14 01:01:02","2020-05-14 01:01:01") |
+----------------------------------------------------------------+
| -31 |
+----------------------------------------------------------------+
mysql> select timestampdiff(second,"2020-06-14 01:01:02","2020-05-14 01:01:01");
+-------------------------------------------------------------------+
| timestampdiff(second,"2020-06-14 01:01:02","2020-05-14 01:01:01") |
+-------------------------------------------------------------------+
| -2678401 |
+-------------------------------------------------------------------+
period_add() , 周期就是月份
mysql> select period_add("202001",2);
+------------------------+
| period_add("202001",2) |
+------------------------+
| 202003 |
+------------------------+
period_diff() , 两个日期差了几个月, 只能用YYYYMM或者YYMM格式
mysql> select period_diff("202003","202001");
+--------------------------------+
| period_diff("202003","202001") |
+--------------------------------+
| 2 |
+--------------------------------+
convert_tz() 时间的时区转换
mysql> select convert_tz('2004-01-01 12:00:00','GMT','MET');
+---------------------------------------------------------+
| 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');
+---------------------------------------------------------+
| CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00') |
+---------------------------------------------------------+
| 2004-01-01 22:00:00 |
+---------------------------------------------------------+
时间格式化符号说明
格式符 | 说明 |
---|---|
%a | 简短星期名 |
%b | 简短月份名 |
%c | 月份数字表示 |
%D | 带英文后缀的日期 (0th, 1st, 2nd, 3rd, …) |
%d | 该月份的日期(两位数01,02,…,31) |
%e | 该月份的日期(1,2,…,31) |
%f | 微秒 |
%H | 小时(二十四制00,01,…, 23) |
%h | 小时(十二小时制00,01,…, 12) |
%I | 小时(十二小时制00,01,…, 12) |
%i | 分钟 |
%j | 该年的第几天,三位数(001,002,…,366) |
%M | 完整月份名 (January…December) |
%m | 月份(01,…,12) |
%p | AM or PM |
%r | 12小时制带有AM/PM的时间 |
%S,/s | 秒 (00…59) |
%T | 24小时制时间 |
%u | 第几周(00,…,53) |
%W | 完整星期名(Sunday…Saturday) |
%w | 该周的第几天 (0=Sunday…6=Saturday) |
%Y | 年份(四位数字) |
%y | 年份(两位数字) |
思维导图
本文包含了我查到的所有的时间类函数,如有遗漏或者错误,请留言告诉我,谢谢。
参考文献: sql官方文档: https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_convert-tz