Hive 常用的日期及时间函数,以及常用的场景介绍。

声明:

  • 函数的参数中,中括号[]表示参数可选,即可不传入可传入;
  • 时间是包括日期的,hive中的日期时间函数的对象可以是时间类型,也可以是字符串类型(STRING);
  • hive的日期函数,对时间(yyyy-MM-dd HH:mm:ss)格式的字符串几乎都是通用的。

/导图

一、常用日期时间

1.1 返回时间的函数

返回当前时间

current_date() :

  • 返回当前日期,“yyyy-MM-dd” 格式

current_timestamp() :

  • 返回当前系统时间,“yyyy-MM-dd HH:mm:ss” 格式,精确到毫秒

unix 时间戳相关

unix_timestamp([STRING timestamp [, STRING pattern]]) :

  • 返回时间对应的 unix 时间戳(即返回距离"1970-01-01 00:00:00" 的秒数(之前的时间unix时间戳是负值),如果是中国时区,则以该天 8点为参照),是 int 型;
  • 第一个参数是字符串类型的时间,第二个 pattern 用于匹配第一个参数时间字符串的格式,用于识别时间;
  • 不传入参数则返回当前时间的 unix 时间戳,相当于 unix_timestamp(current_timestamp());
  • 只传入第 1 个参数的话,格式必须是 “yyyy-mm-dd HH:mm:ss” ,否则返回 NULL ,因为第二个参数 pattern 默认是这个格式。

from_timestamp(BIGINT unixtime [, STRING format]) :

  • 将 unix 时间戳转换为指定格式的时间,可理解为 unix_timestamp 的逆过程;
  • 第一个参数 unixtime 是 unix 时间戳,默认第二个参数 format 是 ‘yyyy-MM-dd HH:mm:ss’ 格式(即输出时间的格式)

1.2 时间格式化函数

转为日期形式

to_date(STRING timestamp) : 字符串转日期

  • 从时间格式的字符串中获取日期部分,“yyyy-MM-dd” 格式;
  • 只要字符串前面是 “yyyy-MM-dd”,后面不是紧跟数字即可

转为自定义形式

date_format(DATE|TIMESTAMP|STRING ts, STRING fmt)

  • 将字符串或时间转为指定格式的时间
  • 第一个参数是必须是标准时间格式(即yyyy-MM-dd HH:mm:ss,可以是日期),第二个参数 fmt (format) 是想要输出的格式类型。

抽取时间中的部分内容

以下都必须传入标准时间格式,返回的是 int 型:

year(STRING date): 返回年;

month: 返回月;

day: 返回天;

hour: 返回时;

minute: 返回分;

second: 返回秒。

1.3 时间计算函数

时间的加减

date_add(DATE startdate, INT days) :

  • 对时间按天做加减,返回的是日期;
  • 第二个参数是 int型的,若为正则往后推,为负往前推。

add_months(DATE|STRING|TIMESTAMP start_date, INT num_months) :

  • 对时间按月做加减,返回的是日期;
  • 第二个参数是 int 型的,若为正则往后推,为负往前推。

返回差值

datediff(STRING enddate, STRING startdate) :

  • 计算两个时间相差的天数,返回的是 int型;
  • 注意是前减后,即第一个参数 - 第二个参数;

months_between(DATE|TIMESTAMP|STRING enddate, DATE|TIMESTAMP|STRING startdate):

  • 计算两个时间相差的月数,返回的是 浮点型
  • 注意是前减后。

1.4 时间转换函数

月初、月末、年初

trunc(STRING date, STRING format) format: MONTH/MON/MM, YEAR/YYYY/YY

  • 返回月初或年初的日期,格式是"yyyy-MM-dd"。

last_day(STRING date) :

  • 返回月末日期,返回的是 "yyyy-MM-dd"格式的日期。

当前日期的下一个 周几的日期

next_day(STRING start_date, STRING day_of_week)

  • 返回 当前日期下个 周几的 日期;如果当前日期是周一,day_of_week 参数输入的是‘MO’,则返回的是下周周一的日期;
  • 第二个参数给周几的缩写(可以小写)或全称:下个周一(‘MO’)、下个周二(‘TU’)、下个周三(‘WE’)、下个周四(‘TH’)、下个周五(‘FR’)、下个周六(‘SA’)、下个周日(‘SU’);
  • 比如 next_day(‘2020-03-27’, ‘MO’) 返回’2020-03-27’(27号是周六)下个周一的日期,即’2020-03-30’。

更高维日期中的第几次

weekofyear(STRING date) :

  • 返回时间在这一年中是第几周

dayofmonth(STRING date)

  • 返回时间在这一月中是第几天

参考:https://ask.hellobi.com/blog/musper/16794

二、常用场景

2.1 判断某日期是周几

pmod(datediff(<需要判断的日期或时间>, '1970-01-04'), 7)
-- 返回值:int 类型;
-- 返回值范围:0~6
-- 如果是0,表示该日期是周日,若是1,则表示该日期为周一,其他以此类推

思路:以一个历史上是周日的时间为参照(这里是’1970-01-04’,是周日),然后用 datediff 函数实现需要判断的日期减去参照日期,最后用 pmod 函数取余数,该差值除以 7 余 多少,如果余0,表示需要判断的日期是周日,余1,表示是周一,其他以此类推。

2.2 给指定时间增加或减少一段时间

-- 返回指定时间8小时后的时间
cast(from_unixtime(unix_timestamp(<需要更改的时间>)+28800, 'yyyy-MM-dd HH:mm:ss') as string)

思路:从时间戳角度切入,通过 unix_timestamp 函数将时间转为时间戳,然后加上需要修改的时间,再用 from_unixtime 函数将时间戳转为想要的时间格式(yyyy-MM-dd HH:mm:ss),最后转为 string 格式。
因为时间戳的单位是秒,所以要增加8小时,就需要在原时间戳上边加上 28800秒(8 * 60 * 60 )。

2.3 计算两个时间段相差时长

(unix_timestamp(<time1>) - unix_timestamp(<time2>) ) / 3600

思路:转为时间戳处理,除以3600(60 * 60)。

2.4 时间格式转换

-- 输出标准日期格式(注:<需要转化的日期或时间>本身需要是yyyy-MM-dd HH:mm:ss样式的)
to_date(<需要转化的日期或时间>)
date_format(<需要转化的日期或时间>, 'yyyy-MM-dd')
-- 2020-01-01 转为 20200101 样式
date_format(<需要转化的日期>, 'yyyyMMdd')

2.5 next_day 的具体应用(如本周一的日期,上周一的日期等)

-- 除了周一,其他不适用,需要更新
-- 本周一
date_add(next_day(current_date(), 'MO'), -7)
-- 上周一
date_add(next_day(current_date(), 'MO'), -14)
-- 下周一
next_day(current_date(), 'MO')
-- 下下周一
date_add(next_day(current_date(), 'MO'), 7)

2.6 trunc 的具体应用()

trunc(add_months(current_timestamp(), -1), 'MM')  -- 上月1号