一、获取月份第一天/最后一天
--需求一:获取月份第一天/最后一天
--方式一:last_day
--获取当月第一天
select date_add(last_day(add_months('2020-06-14',-1)),1);
--获取当月最后一天
select last_day('2020-06-14');
--方式二:floor_month(注:必须转换成时间戳处理!)
--获取当月第一天
select to_date(floor_month(cast('2020-06-14' as timestamp)));
select to_date(floor_month(from_utc_timestamp(unix_timestamp('2020-06-14','yyyy-MM-dd')*1000,'GMT+8')));
--获取当月最后一天
select date_sub(add_months(floor_month(cast('2020-06-14' as timestamp)),1),1);
--方式三:trunc
desc function extended trunc;
--获得当月的第一天
select trunc('2020-06-14','MM');
--获得当月的最后一天
select date_sub(trunc(add_months('2020-06-14',1),'MM'),1);
二、获得年份的第一天/最后一天
--方式一:floor_year获取当年的第一天
--from_unixtime返回'string'型
select to_date(floor_year(cast(from_unixtime(unix_timestamp()) as timestamp)));
--floor_year获取当年的最后一天
select to_date(date_sub(add_months(floor_year(cast(from_unixtime(unix_timestamp()) as timestamp)),12),1));
--方式二:trunc获取当年的第一天/最后一天
--trunc获取当年的第一天
select trunc(from_unixtime(unix_timestamp()),'YYYY');
--trunc获取当年的最后一天
select date_sub(add_months(trunc(from_unixtime(unix_timestamp()),'YYYY'),12),1);
三、获取时间区间中的连续区间日期
--获得时间区间的方法一:
--利用函数关系做变换,逻辑强
select if(year(start_time_t)=year(add_months(start_time_t,12*p)),start_time_t,trunc(add_months(start_time_t,12*p),'YYYY')) start_time_t_sec,
if(year(stop_time_t)=year(add_months(start_time_t,12*p)),stop_time_t,add_months(date_sub(trunc(add_months(start_time_t,12*p),'YYYY'),1),12)) stop_time_t_sec
from (
select from_unixtime(unix_timestamp(start_time, 'yyyyMdd'), 'yyyy-MM-dd') start_time_t,
from_unixtime(unix_timestamp(stop_time, 'yyyyMdd'), 'yyyy-MM-dd') stop_time_t
from (
select '2015506' start_time,
'2022712' stop_time
) t1
)t2
lateral view posexplode(split(space(year(stop_time_t)-year(start_time_t)),' ')) tmp as p,v;
--获得时间区间的方法二:
--拼接写法似乎也差不多代码量,但是逻辑简单
select if(year(start_time_t)=year(add_months(start_time_t,12*p)),start_time_t,concat(year(add_months(start_time_t,12*p)),'-','01-01')) start_time_t_sec,
if(year(stop_time_t)=year(add_months(start_time_t,12*p)),stop_time_t,concat(year(add_months(start_time_t,12*p)),'-','12-31')) stop_time_t_sec
from (
select from_unixtime(unix_timestamp(start_time, 'yyyyMMdd'), 'yyyy-MM-dd') start_time_t,
from_unixtime(unix_timestamp(stop_time, 'yyyyMMdd'), 'yyyy-MM-dd') stop_time_t
from (
select '20150506' start_time,
'20220712' stop_time
) t1
)t2
lateral view posexplode(split(space(year(stop_time_t)-year(start_time_t)),' ')) tmp as p,v;
该需求的结果显示:
![](https://i-blog.csdnimg.cn/blog_migrate/34d339e79219a92debc7b3f288207e31.png)
总结:
1、月份处理函数:last_day、floor_month、trunc;
2、年份处理函数:floor_year、trunc;
3、时间区间处理函数选择:posexplode、split、space。