• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

[1144]Hive常用日期格式转换

武飞扬头像
周小董
帮助1

获取当前时间

  • 获取当前时间戳
-- Hive中获取当前时间戳,默认使用unix_timestamp()函数,精确到秒
select unix_timestamp(); -- 1677062942
  • Hive中获取毫秒级别的时间戳
select current_timestamp() as current_time, cast(current_timestamp() as double) * 1000 as timestamp;

2019-06-02 15:44:23.324	1559461463324
  • 把时间戳转为正常的日期
select from_unixtime(unix_timestamp(),'yyyy-MM-dd HH:mm:ss')
select from_unixtime(unix_timestamp(),'yyyy-MM-dd')
 
SELECT from_unixtime(1571709884123/1000,'yyyy-MM-dd HH:dd:ss.sss');
2019-10-22 10:22:44.044
  • 业务中有时存放的是包含毫秒的整数,需要先转换为秒
select from_unixtime(cast(create_time/1000 as bigint),'yyyyMMdd') as dt
  • 返回当天日期或时间
SELECT CURRENT_DATE;   --2017-06-15
select current_date();   -- 2021-10-22

-- Hive中使用current_timestamp()函数获取当前时间,精确到毫秒
select current_timestamp;  --2018-06-18 10:37:53.278
select current_timestamp();  --2023-02-22 18:46:18.406
select from_unixtime(unix_timestamp());  --2017-06-15 19:55:04
select from_unixtime(unix_timestamp(),'yyyy-MM-dd HH:mm:ss.SSS') as etl_time;  --2023-02-22 18:46:18.406

select from_unixtime(unix_timestamp(),'yyyy-MM-dd HH:mm:ss') as etl_time;  --2023-02-22 18:46:18
select date_format(current_timestamp(), 'yyyy-MM-dd HH:mm:ss') as etl_time;  --2023-02-22 18:46:18

Hive中处理毫秒级别的时间戳

desc function extended to_utc_timestamp;

to_utc_timestamp(timestamp, string timezone) - Assumes given timestamp is in given timezone and converts to UTC (as of Hive 0.8.0)


select to_utc_timestamp(1559461463324, 'GMT');
 -------------------------- -- 
|           _c0            |
 -------------------------- -- 
| 2019-06-02 15:44:23.324  |
 -------------------------- -- 
1 row selected (2.745 seconds)
  • 将毫秒级别的时间戳转换为指定格式的毫秒时间,SSS代表毫秒
select date_format(to_utc_timestamp(1559461463324, 'GMT'), 'yyyyMMddHHmmssSSS');
 -------------------- -- 
|        _c0         |
 -------------------- -- 
| 20190602154423324  |
 -------------------- -- 
1 row selected (0.323 seconds)


select date_format(to_utc_timestamp(1559461463324, 'GMT'), 'yyyy/MM/dd HH:mm:ss.SSS');
 -------------------------- -- 
|           _c0            |
 -------------------------- -- 
| 2019/06/02 15:44:23.324  |
 -------------------------- -- 
1 row selected (0.183 seconds)
学新通
  • 将毫秒级时间转化为毫秒级时间戳
select cast(from_utc_timestamp('2023-01-30 12:00:00.123', 'yyyy-MM-dd HH:mm:ss.SSS') as double) * 1000 as timestamp1;--1675051200123

日期格式转换

  • 日期格式转换 yyyyMMdd—>yyyy-MM-dd
select from_unixtime(unix_timestamp('20211022','yyyyMMdd'),"yyyy-MM-dd");
2021-10-22
  • 固定日期转换成时间戳
select unix_timestamp('2016-08-16','yyyy-MM-dd') --1471276800
select unix_timestamp('20160816','yyyyMMdd') --1471276800
select unix_timestamp('2016-08-16T10:02:41Z', "yyyy-MM-dd'T'HH:mm:ss'Z'") --1471312961
16/Mar/2017:12:25:01  0800 转成正常格式(yyyy-MM-dd hh:mm:ss)
select from_unixtime(to_unix_timestamp('16/Mar/2017:12:25:01  0800', 'dd/MMM/yyy:HH:mm:ss Z'))
  • 时间戳转换程固定日期
select from_unixtime(1471276800,'yyyy-MM-dd') --2016-08-16
select from_unixtime(1471276800,'yyyyMMdd') --20160816
select from_unixtime(1471312961) --    2016-08-16 10:02:41
select from_unixtime( unix_timestamp('20160816','yyyyMMdd'),'yyyy-MM-dd')  --2016-08-16
select date_format('2016-08-16','yyyyMMdd') --20160816
  • 字符串强制转换,获取日期
select to_date('2016-08-16 10:03:01') --2016-08-16
类似sql中的date
  • 截取日期部分
select substr('2021-10-22 17:34:56',1,10)
2021-10-22

select date_format('2021-10-22 17:34:56','yyyy-MM-dd')
2021-10-22

返回日期中的年,月,日,时,分,秒,当前的周数

  • 返回日期中的年
select year('2016-08-16 10:03:01') --2016
  • 返回日期中的月
select month('2016-08-16 10:03:01') --8
  • 返回日期中的日
select day('2016-08-16 10:03:01') --16
  • 返回日期中的时
select hour('2016-08-16 10:03:01') --10
  • 返回日期中的分
select minute('2016-08-16 10:03:01') --3
  • 返回日期中的秒
select second('2016-08-16 10:03:01') --1
  • 返回日期在当前的周数
select weekofyear('2016-08-16 10:03:01') --33

返回当月或当年的第一天

  • 返回当月的第一天
select trunc('2016-08-16','MM') --2016-08-01

select date_format(to_date(trunc(current_date(),'MM')),"yyyy-MM-dd");
2021-10-01
  • 返回当年的第一天
select trunc('2016-08-16','YEAR') --2016-01-01

计算日期差值

返回结束日期减去开始日期的天数

语法:datediff(string enddate,string startdate)
返回值: int
说明: 返回结束日期减去开始日期的天数。

select datediff('2016-08-16','2016-08-11') ;
5

需要注意的是datediff两个日期必须是’yyyy-MM-dd’的格式,否则执行结果会是NULL
例如:

select datediff('20221220','20221231');

执行结果:NULL

而在mysql中,

select datediff('20221220','20221231');

这种写法是支持的,执行结果 -11。

返回开始日期startdate增加days天后的日期

语法:date_add(string startdate, intdays)
返回值: string
说明: 返回开始日期startdate增加days天后的日期。

select date_add('2016-08-16',10)

需要注意的是intdays 可以是正数、也可以是负数,正数代表加,负数代表减。

返回开始日期startdate减少days天后的日期

语法:date_sub (string startdate,int days)
返回值: string
说明: 返回开始日期startdate减少days天后的日期。

select date_sub('2016-08-16',10)

前一日/昨日
select date_sub(current_date(),1);
2021-10-21

最近一个月/30天
select date_sub(current_date(),30);
2021-09-22

hive日期比较函数,虽然只是一个很小的知识点,但它在实际应用有很大的作用,掌握了往往有事半功倍的效果。

比如获取某张表昨日的分区 可以使用

regexp_replace(date_sub(from_unixtime(unix_timestamp(),'yyyy-MM-dd'),1) ,'-','')

或者

date_format(date_sub(from_unixtime(unix_timestamp(),'yyyy-MM-dd'),1),'yyyyMMdd')

前一日12点/昨日12点

select concat(date_format(date_sub(current_date(),1),'yyyy-MM-dd'),' ','12');
2021-10-21 12

计算时间相差的秒数,unix_timestamp精确到秒

select nvl(unix_timestamp(substr('2023-02-13 23:59:59.199',1,19)) - unix_timestamp(substr('2023-02-13 23:59:58.800',1,19)),0) as seconds;

select nvl(unix_timestamp('2023-02-13 23:59:59.199') - unix_timestamp('2023-02-13 23:59:58.800'),0) as seconds;

select nvl(unix_timestamp('2023-02-13 23:59:59.199','yyyy-MM-dd HH:mm:ss.SSS') - unix_timestamp('2023-02-13 23:59:58.800','yyyy-MM-dd HH:mm:ss.SSS'),0) as seconds;

特殊函数

weekofyear(date1)**:返回日期date1位于该年第几周。
如weekofyear('2019-03-06')=10

datediff(date1,date2)**:返回日期date1与date2相差的天数
如datediff('2019-03-06','2019-03-05')=1

date_add(date1,int1)**:返回日期date1加上int1的日期
如date_add('2019-03-06',1)='2019-03-07'

date_sub(date1,int1)**:返回日期date1减去int1的日期
如date_sub('2019-03-06',1)='2019-03-05'

months_between(date1,date2)**:返回date1与date2相差月份
如months_between('2019-03-06','2019-01-01')=2

add_months(date1,int1)**:返回date1加上int1个月的日期,int1可为负数
如add_months('2019-02-11',-1)='2019-01-11'

last_day(date1)**:返回date1所在月份最后一天
如last_day('2019-02-01')='2019-02-28'

next_day(date1,day1)**:返回日期date1的下个星期day1的日期。day1为星期X的英文前两字母
如next_day('2019-03-06','MO') 返回'2019-03-11'

trunc(date1,string1):**返回日期最开始年份或月份。string1可为年(YYYY/YY/YEAR)或月(MONTH/MON/MM)。
如trunc('2019-03-06','MM')='2019-03-01',trunc('2019-03-06','YYYY')='2019-01-01'

select split('12','\\.')[1]
select concat(1,'.',3)
select if(split('1.2','\\.')[1] is NULL,0,split('1.2','\\.')[1])
学新通

总结

Hive中获取时间戳的方式为unix_timestamp()函数,该函数只能够精确到秒级别的时间,对于时间精确到要求高的应用则该函数并不适合。

Hive获取当前时间毫秒级别的时间戳时需要使用cast函数将current_timestamp()转为double类型并乘以1000,则得到毫秒级别的时间戳。

对于Hive库中存储的毫秒精度的时间戳,为了确保时间精度不损失则需要使用to_utc_timestamp()函数,该函数支持毫秒级别的时间错,但需要指定当前时区。

参考:https://blog.csdn.net/wufagang/article/details/124025258
https://www.jianshu.com/p/55f9683c63f1
https://blog.csdn.net/m0_46689661/article/details/117734151
Hive中TimeStamp精度问题分析:https://blog.csdn.net/lz6363/article/details/90740061
https://blog.csdn.net/X8i0Bev/article/details/128391689

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhiafjci
系列文章
更多 icon
同类精品
更多 icon
继续加载