Hive 中,可以用String、Date和Timestamp表示日期時間,String 用 yyyy-MM-dd 的形式表示,Date 用 yyyy-MM-dd 的形式表示,Timestamp 用 yyyy-MM-dd hh:mm:ss 的形式表示。這三種數據類型在使用細節上,有一些需要注意的點:
Join比較
在兩表Join時,會涉及到字段的比較,此時應注意:
如第一張圖所示,如果時間信息中不包含時分秒,String 與 Date、Timestamp 表達的時間相同時是可以直接比較的,但是Date和Timestamp之間卻不能直接比較的。
如果想比較這兩種時間類型,需要用cast函數做轉換,如:a_table join b_table on (a_table.timestamp_column = cast(b_table.date_column as timestamp));
如第二張圖所示,如果時間信息中包含時分秒,此時String 與 Timestamp 表達的時間相同時是可以直接比較的,Date 不能表示帶時分秒的信息。
Insert value
在insert value時,使用者一般用字符串的形式向Hive表中插入value,但是字符串的插入的結果與字段類型相關。如上圖所示,圖中綠線表示插入成功,紅線表示插入失敗得到了不想要的結果。
一、相互轉化
格式化 date_format
select date_format('2019-04-08', 'yyyy') --得到:2019 select date_format('2019-04-08', 'yyyy-MM') --得到:2019-04 select date_format('2019-04-08', 'yy-MM') --得到:19-04
注意:也可以用substr 方式截取年月或者substr+concat結合
字符串轉時間 to_date
語法: to_date(string timestamp)
返回值: string
說明: 返回日期時間字段中的日期部分。
舉例:
hive> select to_date('2019-02-16 14:02:03') from dual; OK 2019-02-16
日期轉年函數: year
語法: year(string date)
返回值: int
說明: 返回日期中的年。
舉例:
hive> select year(’2019-12-08 10:03:01′) ; 2011 hive> select year(’2019-12-08′) ; 2012
日期轉月函數: month
語法: month (string date)
返回值: int
說明: 返回日期中的月份。
舉例:
hive> select month(’2019-12-08 10:03:01′); 12 hive> select month(’2019-08-08′); 8
【注意】這里的轉成月份是0-12的數字顯示不出年份,要輸出‘2019-12’這種格式,需要用到時間戳函數
select from_unixtime( unix_timestamp(字段名), 'yyyy-MM' ) from 表名
例如
-- 獲取當前時間戳(1565858389) select unix_timestamp() --獲取當前日期和時間(2019-11-13 17:18:55) select from_unixtime(unix_timestamp()) --獲取當前日期和時間,精確到毫秒(2019-11-13 17:18:55.720) select current_timestamp() -- 獲取當前日期(2019-11-13) select from_unixtime(unix_timestamp(),'yyyy-MM-dd') -- 獲取當前年份(2019) select from_unixtime(unix_timestamp(),'yyyy') -- 獲取當前月份(0-12的數字) select from_unixtime(unix_timestamp(),'MM')
日期轉周函數: weekofyear
語法: weekofyear (string date)
返回值: int
說明: 返回日期在當前的周數。
舉例:
hive> select weekofyear(’2019-12-08 10:03:01′); 49
日期轉天函數: day
語法: day (string date)
返回值: int
說明: 返回日期中的天。
舉例:
hive> select day(’2019-12-08 10:03:01′) ; 8 hive> select day(’2019-12-24′); 24
日期轉小時函數: hour
語法: hour (string date)
返回值: int
說明: 返回日期中的小時。
舉例:
hive> select hour(’2019-12-08 10:03:01′) ; 10
日期轉分鍾函數: minute
語法: minute (string date)
返回值: int
說明: 返回日期中的分鍾。
舉例:
hive> select minute(’2019-12-08 10:03:01′) ; 3
日期轉秒函數: second
語法: second (string date)
返回值: int
說明: 返回日期中的秒。
舉例:
hive> select second(’2019-12-08 10:03:01′); 1
二、時間戳和日期格式互轉
1. 日期>>>>時間戳
(1)unix_timestamp() 獲取當前時間戳
例如:select unix_timestamp() --1565858389
注意事項:
(a) unix_timestamp(string timestamp) 輸入的時間戳格式必須為’yyyy-MM-dd HH:mm:ss’,如不符合則返回null
例如:
select unix_timestamp('2019-08-15 16:40:00') --1565858400 select unix_timestamp('2019-08-15') --null
(b)unix_timestamp(string date,string pattern) 將指定時間字符串格式字符串轉化成unix時間戳,如不符合則返回null
例如:
select unix_timestamp('2019-08-15','yyyy-MM-dd') --1565798400 select unix_timestamp('2019-08-15 16:40:00','yyyy-MM-dd HH:mm:ss') --1565858400 select unix_timestamp('2019-08-15','yyyy-MM-dd HH:mm:ss') --null
2.時間戳>>>>日期
(1)普通格式
from_unixtime(bigint unixtime,string format) 將時間戳秒數轉化為UTC時間,並用字符串表示,指定輸出的時間格式,其中unixtime 是10位的時間戳值,而13位的所謂毫秒的是不可以的。
例如:
--2019-08-15 16:39:49 select from_unixtime(1565858389,'yyyy-MM-dd HH:mm:ss') --2019-08-15 select from_unixtime(1565858389,'yyyy-MM-dd')
(2)特殊格式:先轉10位
如果unixtime為13位的,需要先轉成10位
--2019-03-22 00:00:00 select from_unixtime(cast(1553184000488/1000 as int),'yyyy-MM-dd HH:mm:ss') --2019-03-22 00:00:00 select from_unixtime(cast(substr(1553184000488,1,10) as int),'yyyy-MM-dd HH:mm:ss')
三、獲取當前日期和時間
語法: from_unixtime( unixtime,“string format”)
后面的年月日格式可以根據需要自己設置
或者用current_timestamp()
和 current_date()
舉例:
--1. 獲取當前日期和時間(年月日時分秒) --寫法一: select from_unixtime(unix_timestamp(),"yyyy-MM-dd HH:mm:ss") 2020-04-21 11:02:55 --寫法二: select substr(current_timestamp(),1,19) 2020-04-21 11:02:55 -- 2.獲取當前日期 --寫法一: select from_unixtime(unix_timestamp(),"yyyy-MM-dd") 2020-04-21 --寫法二:(推薦) select current_date()或者select current_date 2020-04-21 -- 寫法三: select substr(current_timestamp(),1,10) 2020-04-21 --3. 獲取當前年份(2020) select from_unixtime(unix_timestamp(),'yyyy') 2020 -- 獲取當前月份(0-12的數字) select from_unixtime(unix_timestamp(),'MM')
四、時間拼接和更改格式
方法1: from_unixtime+ unix_timestamp --20171205轉成2017-12-05 select from_unixtime(unix_timestamp('20171205','yyyymmdd'),'yyyy-mm-dd') from dual; --2017-12-05轉成20171205 select from_unixtime(unix_timestamp('2017-12-05','yyyy-mm-dd'),'yyyymmdd') from dual; 方法2: substr + concat --20171205轉成2017-12-05 select concat(substr('20171205',1,4),'-',substr('20171205',5,2),'-', substr('20171205',7,2)) from dual; --2017-12-05轉成20171205 select concat(substr('2017-12-05',1,4),substr('2017-12-05',6,2), substr('2017-12-05',9,2)) from dual;
已知日期 |
要求日期 |
語句 |
結果 |
本周任意一天 |
本周一 |
select date_sub(next_day('2016-11-29','MO'),7) ; |
2016-11-28 |
本周任意一天 |
上周一 |
select date_sub(next_day('2016-11-29','MO'),14) ; |
2016-11-21 |
本周任意一天 |
本周二 |
select date_sub(next_day('2016-11-29','MO'),6) |
2016-11-29 |
本周任意一天 |
上周二 |
select date_sub(next_day('2016-11-29','MO'),13) ; |
2016-11-22 |
本周任意一天 |
上周末 |
select date_sub(next_day('2016-11-29','MO'),8) ; |
2016-11-27 |
本月任意一天 |
上月末 |
select date_sub(trunc('2016-11-02','MM'),1); |
2016-10-31 |
本月任意一天 |
上月初 |
select trunc(add_months('2016-11-02',-1),'MM') |
2016-10-01 |
本月任意一天 |
本月初 |
select trunc('2016-11-02','MM') |
2016-11-01 |
本月任意一天 |
上上月26 |
select date_add(add_months(trunc('2016-11-02','MM'),-2),25) ; |
2016-09-26 |
本月任意一天 |
上月26 |
select date_add(add_months(trunc('2016-11-02','MM'),-1),25) ; |
2016-10-26 |
|
當前時間戳 |
select current_timestamp() ; |
2016-11-30 15:18:06.276 |
|
當前時間 |
select current_date() ; |
2016-11-30 |
本季度任意一天 |
上季度初 |
case quarter('2016-05-23') when 1 then concat(year('2016-05-23')-1,'-10-01') when 2 then concat(year('2016-05-23'),'-01-01') when 3 then concat(year('2016-05-23'),'-04-01') when 4 then concat(year('2016-05-23'),'-07-01') end 或 add_months(concat(year('2017-02-23'),'-',substr(concat('0',quarter('2017-02-23')*3+1),-2),'-01'),-6) |
|
本季度任意一天 |
本季度初 |
case quarter('2016-05-23') when 1 then concat(year('2016-05-23'),'-01-01') when 2 then concat(year('2016-05-23'),'-04-01') when 3 then concat(year('2016-05-23'),'-07-01') when 4 then concat(year('2016-05-23'),'-10-01') end 或 add_months(concat(year('2017-02-23'),'-',substr(concat('0',quarter('2017-02-23')*3+1),-2),'-01'),-3) |
|
|
|
|
|