提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、时间戳函数
1、unix_timestamp()
- unix_timestamp() 无参数调用,获取当前系统时间戳为10位的bigint类型数值,该数值只精确到秒。
select unix_timestamp();
> 1680227307
- unix_timestamp(string timestamp) 输入格式默认为“yyyy-MM-dd HH:mm:ss”,如不符合则返回null。
select unix_timestamp('2023-03-31 01:48:27') ;
> 1680227307
select unix_timestamp('2023-03-31');
> NULL
- unix_timestamp(string date,string pattern) 将指定时间格式的字符串转化成时间戳,如不符合则返回null。
--固定日期转换成时间戳
select unix_timestamp('2023-03-31','yyyy-MM-dd');
> 1680220800
select unix_timestamp('2023-03-31 01:48:27','yyyy-MM-dd HH:mm:ss');
> 1680227307
select unix_timestamp('2023-03-31T10:02:41Z', "yyyy-MM-dd'T'HH:mm:ss'Z'");
> 1680256961
select unix_timestamp('2023-03-31','yyyy-MM-dd HH:mm:ss')
> NULL
- unix_timestamp() - unix_timestamp()是两个时间转换为timestamp之后相减,timestamp单位是秒,相减之后是两个时间之间相差的秒数。
cast((unix_timestamp() - unix_timestamp()) % 60 as int) --是相差的秒数。
cast((unix_timestamp() - unix_timestamp()) / 60 as int) % 60 --是相差的分钟数。
cast((unix_timestamp() - unix_timestamp()) / (60 * 60) as int) % 24 --是相差的小时数。
concat(cast((unix_timestamp() - unix_timestamp()) / (60 * 60 * 24) as int) --是相差的天数。
--是相差的秒数
select unix_timestamp('20230329185800','yyyyMMddHHmmss')- unix_timestamp('20230329185604','yyyyMMddHHmmss');
> 56
select cast((unix_timestamp('20230329185800','yyyyMMddHHmmss')- unix_timestamp('20230329185604','yyyyMMddHHmmss'))%60 AS int);
> 56
--是相差的分钟数
select cast((unix_timestamp('20230329185800','yyyyMMddHHmmss')- unix_timestamp('20230329185604','yyyyMMddHHmmss'))/60 AS int);
> 1
--是相差的小时数
select cast((unix_timestamp('20230329215800','yyyyMMddHHmmss')- unix_timestamp('20230329185604','yyyyMMddHHmmss'))/(60 * 60) AS int) % 24;
> 3
--是相差的天数
select cast((unix_timestamp('20230331185800','yyyyMMddHHmmss')- unix_timestamp('20230329185604','yyyyMMddHHmmss'))/(60 * 60 * 24) AS int) ;
> 2
注意:unix_timestamp 类第一个参数只接受 string 类型
2、from_unixtime()
- from_unixtime(bigint unixtime,string format) 将时间戳秒数转化成UTC时间,并用字符串表示,可通过format规定时间格式,指定输出的时间格式。其中unixtime是10位的时间戳值,而13位的所谓毫秒是不可以的。
-- 时间戳转换成固定日期
select from_unixtime(1680257881,'yyyy-MM-dd HH:mm:ss');
> 2023-03-31 10:18:01
select from_unixtime(1680257881,'yyyy-MM-dd');
> 2023-03-31
select from_unixtime(unix_timestamp('31/Mar/2023:10:18:01 +0800', 'dd/MMM/yyy:HH:mm:ss Z'))
> 2023-03-31 02:18:01
select from_unixtime(1680257881);
> 2023-03-31 10:18:01
-- 取当前系统时间
select from_unixtime(unix_timestamp(),'yyyy-MM-dd HH:mm:ss');
> 2023-03-31 02:37:17
注意:from_unixtime 类 第一个参数只接受 bigint 类型。
3、unix_timestamp()与from_unixtime()结合使用
举例:已知通话开始时间为 “20230329185604”,通话时长为56秒,计算通话结束的时刻。
select from_unixtime((unix_timestamp(concat(substr('20230329185604',0,4),'-',substr('20230329185604',5,2),'-',substr('20230329185604',7,2),' ',substr('20230329185604',9,2),':',substr('20230329185604',11,2),':',substr('20230329185604',13,2)))+56),'yyyy-MM-dd HH:mm:ss');
> 2023-03-29 18:57:00
select from_unixtime((unix_timestamp('20230329185604','yyyyMMddHHmmss')+56),'yyyy-MM-dd HH:mm:ss');
> 2023-03-29 18:57:00
总结
1.Hive中获取时间戳的方式为unix_timestamp()函数,该函数只能够精确到秒级别的时间,对于时间精确到要求高的应用则该函数并不适合。
2.Hive获取当前时间毫秒级别的时间戳时需要使用cast函数将current_timestamp()转为double类型并乘以1000,则得到毫秒级别的时间戳。
3.对于Hive库中存储的毫秒精度的时间戳,为了确保时间精度不损失则需要使用to_utc_timestamp()函数,该函数支持毫秒级别的时间错,但需要指定当前时区。
-- 1.Hive中使用current_timestamp()函数获取当前时间,精确到毫秒。
select current_timestamp();
> 2023-03-31 11:18:48.184
--2.Hive中获取当前时间戳为10位的bigint类型数值,该数值只精确到秒级别。
select unix_timestamp(current_timestamp());
> 1680261703
--3.Hive中将时间戳转换为日期类型,结果可以看到时间的毫秒是无法正常获取到,因为时间戳只是精确到秒级别的,from_unixtime()函数也只支持秒级别的时间戳转换。
select from_unixtime(1680261703,'yyyy-MM-dd HH:mm:ss:SSS');
> 2023-03-31 11:21:43:000
-4.Hive中获取毫秒级别的时间戳,获取到了一个13位的数值,该数值精确到毫秒即为当前的时间的时间戳。
select current_timestamp(), cast(current_timestamp() as double) ;
+--------------------------+-------------------+
| _c0 | _c1 |
+--------------------------+-------------------+
| 2023-03-31 11:25:26.802 | 1.680261926802E9 |
+--------------------------+-------------------+
--5.Hive中处理毫秒级别的时间戳,使用Hive提供的to_utc_timestamp()函数将毫秒级别的时间戳转换为相应的时间并且精确到了毫秒,与上一步获取时间戳的时间一致。
select to_utc_timestamp(1.680261926802E9, 'GMT');
> 2023-03-31 11:25:26.802
4.Hive中将十三位时间戳转换成日期,需要将“十三位时间戳” 除以1000并转为bigint类型,使用from_unixtime()转成想要的日期格式。
--十三位时间戳转换成日期,将十位时间戳/1000,转为bigint类型
select from_unixtime(cast(1679206709158/1000 as bigint),'yyyy-MM-dd HH:mm:ss');
> 2023-03-19 06:18:29
二、日期处理函数
1、date_format()
- date_format(expr, fmt) 将时间戳转换为 fmt 格式的字符串。
expr:DATE、TIMESTAMP(“YYYY-MM-DD:HH-MM-SS”) 或有效日期/时间格式的 STRING。
fmt:描述所需格式的 STRING 表达式。
select date_format('2023-03-31','yyyy-MM');
> 2023-03
select date_format('2023-03-31','yyyyMMdd');
> 20230331
select date_format('2023/03/31', 'y'); --识别不了/ 这种分隔符
> NULL
2、date_sub()
- date_sub(startDate,numDays) 对当前日期减少天数,返回日期。
startDate:日期表达式。
numDays:一个整数表达式。
date_sub(‘yyyy-MM-dd’,n/-m) ,返回初始日期 n 天前,m 天后的日期。
select date_sub('2023-03-31',5); --2023-03-31 5天前
> 2023-03-26
select date_sub('2023-03-31',-2); --2023-03-31 2天后
> 2023-04-02
3、date_add()
- date_add(startDate,numDays) 对当前日期增加的天数,返回日期。
startDate:日期表达式。
numDays:一个整数表达式。
date_sub(‘yyyy-MM-dd’,n/-m) ,返回初始日期 n 天后,m 天前的日期。
select date_add('2023-03-31',5); --2023-03-31 5天后
> 2023-04-05
select date_add('2023-03-31',-2); --2023-03-31 2天前
> 2023-03-29
4、datediff()
- datediff(‘endDate’,‘startDate’) 返回前后日期之间的天数差,int类型。
endDate:日期表达式。
startDate:日期表达式。
select datediff('2023-03-31','2023-03-21');
> 10
select datediff('2023-03-31','2023-04-05');
> -5
--"yyyy/MM/dd"转换成"yyyy-MM-dd"
select datediff(regexp_replace('2023/03/31', "/", "-"), regexp_replace('2023/03/12', "/", "-"));
> 19
-- 求时间差
select datediff(from_unixtime(unix_timestamp('20221001','yyyyMMdd'),'yyyy-MM-dd'),from_unixtime(unix_timestamp(substr('2022-09-09',1,10),'yyyy-MM-dd'),'yyyy-MM-dd'));
> 22
5、last_day()
- last_day(expr) 求当月最后一天
expr:一个 DATE 表达式。
select last_day('2023-03-21');
> 2023-03-31
select last_day('2023-03-21 10:18:01');
> 2023-03-31
6、next_day()
- next_day(expr, dayOfWeek),返回一个DATE。
expr:一个 DATE 表达式。
dayOfWeek:标识一周中某一天的 STRING 表达式。
dayOfWeek 必须是以下之一(不区分大小写):
‘SU’, ‘SUN’, ‘SUNDAY’
‘MO’, ‘MON’, ‘MONDAY’
‘TU’, ‘TUE’, ‘TUESDAY’
‘WE’, ‘WED’, ‘WEDNESDAY’
‘TH’, ‘THU’, ‘THURSDAY’
‘FR’, ‘FRI’, ‘FRIDAY’
‘SA’, ‘SAT’, ‘SATURDAY’
--取当前天的下一个周一
select next_day('2023-03-31','MO');
> 2023-04-03
--取当前周的周一
select date_sub(next_day('2023-03-31','MO'),7);
> 2023-03-27
7、add_months()
- add_months(startDate, numMonths)
startDate:一个 DATE 表达式。
numMonths:整数。
add_months(‘yyyy-MM-dd’,n/-m) ,返回初始日期 n 月后,m 月前的日期。文章来源:https://www.toymoban.com/news/detail-716858.html
select add_months('2023-03-01',1); --1个月后
> 2023-04-01
select add_months('2023-03-01',-6); --6个月前
> 2022-09-01
8、其他相关函数
#1、返回当天的三种方式
select current_date;
> 2023-03-31
select current_timestamp;
> 2023-03-31 15:20:11.566
select from_unixtime(unix_timestamp());
> 2023-03-31 07:20:30
#2、返回日期中的年
select year('2023-03-31 01:48:27');
> 2023
#3、返回日期中的月份
select month('2023-03-31 01:48:27');
> 3
#4、返回日期中的日
select day('2023-03-31 01:48:27');
> 31
#5、返回日期中的时
select hour('2023-03-31 01:48:27');
> 1
#6、返回日期中的分
select minute('2023-03-31 01:48:27');
> 48
#7、返回日期中的秒
select second('2023-03-31 01:48:27');
> 27
#8、返回日期中的当前月份的第几天
select dayofmonth('2023-03-31 01:48:27');
> 31
#9、返回日期中的当前的周数(今年第几周)
select weekofyear('2023-03-31 01:48:27');
> 13
#10、返回当月第一天
select date_sub(current_date,dayofmonth(current_date)-1);
> 2023-03-01
select trunc('2023-03-31','MM');
> 2023-03-01
select from_unixtime(unix_timestamp(date_format(from_unixtime(unix_timestamp('20230331','yyyymmdd'),'yyyy-mm-dd'),'yyyy-MM-01'),'yyyy-MM-dd'),'yyyyMMdd')
> 20230301
#11、返回当年的第一天
select trunc('2023-03-31','YEAR');
> 2023-01-01
总结
1.date_format()/date_sub()/date_add()/datediff()/last_day()/next_day()/add_months 函数日期只能为’yyyy-MM-dd’格式 & 'yyyy-MM-dd HH:mm:ss’格式文章来源地址https://www.toymoban.com/news/detail-716858.html
到了这里,关于【hive】时间相关函数的使用(时间戳函数unix_timestamp()/from_unixtime()、日期处理函数datediff()/date_sub()/date_add()等)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!