文章目录
一、背景说明二、Hive日期类型解析三、获取当前日期的8种方式1. 基础方法(4种方式)2. 带时区操作3. Unix时间戳格式4. 格式化实时获取5. 动态分区专用
四、格式转换的9大高频场景1. 字符串转DATE类型2. 复杂格式解析3. 多格式兼容转换4. 日期转时间戳5. 日期格式的转换6. 时间戳转日期
五、生产级实战案例场景:多源日志日期统一处理
六、高频问题解决方案1. 时区不一致问题2. 闰年二月处理3. 性能优化建议
七、总结与最佳实践1. 格式选择优先级:2. 函数性能排行:3. 避坑指南:4. 扩展建议:
扩展文章(推荐)1. 参数配置:2. 核心内置函数和自定义UDF:3. Hive参数(groupby.skewindata遇到map.aggr的致命组合):
一、背景说明
在大数据ETL和统计分析中,时间日期处理是最高频的操作场景之一。Hive作为企业级数据仓库解决方案,提供了丰富的日期处理函数。但在实际使用中,开发人员常会遇到以下痛点:
源数据日期格式杂乱(如’2023/01/01’、'01-Jan-2023’等)需要动态获取当前日期进行增量数据处理时区转换和日期计算需求复杂 本文将深入解析Hive日期处理的15+种核心用法,并提供可直接复用的生产级案例代码。
二、Hive日期类型解析
Hive支持两种原生日期类型:
DATE:存储格式为YYYY-MM-DDTIMESTAMP:精确到纳秒级(格式YYYY-MM-DD HH:MM:SS.fffffffff) 注:实际生产中常用STRING类型存储日期,需注意格式转换
三、获取当前日期的8种方式
1. 基础方法(4种方式)
-- 1.获取当前日期(推荐)
SELECT current_date();
-- 结果:2023-08-20
-- 2.获取当前时间戳(推荐)
SELECT current_timestamp();
-- 结果:2023-08-20 14:30:45.389
-- 3.获取年月日
select from_unixtime(unix_timestamp(),"yyyy-MM-dd")
-- 结果:2020-04-21
--4.获取年月日时分秒
select from_unixtime(unix_timestamp(),"yyyy-MM-dd HH:mm:ss")
-- 结果:2020-04-21 11:02:55
2. 带时区操作
-- 指定时区获取(需要Hive 2.1+)
SELECT current_timestamp() AT TIME ZONE 'Asia/Shanghai';
3. Unix时间戳格式
SELECT unix_timestamp(); -- 1692520245(秒级时间戳)
4. 格式化实时获取
SELECT date_format(current_timestamp(), 'yyyy年MM月dd日'); -- 2023年08月20日
5. 动态分区专用
SET hive.exec.dynamic.partition=true;
INSERT OVERWRITE TABLE log_partition PARTITION(dt=date_format(current_date(),'yyyyMMdd'))
SELECT * FROM source_table;
四、格式转换的9大高频场景
1. 字符串转DATE类型
SELECT
to_date('2023-08-20'), -- 标准格式
to_date('20230820'), -- 连续数字
to_date('2023/08/20'); -- 斜杠分隔
-- 结果均为:2023-08-20
2. 复杂格式解析
SELECT
from_unixtime(
unix_timestamp('20-Aug-2023', 'dd-MMM-yyyy'),
'yyyy-MM-dd'
); -- 2023-08-20
3. 多格式兼容转换
CREATE TEMPORARY FUNCTION parse_date AS
'org.apache.hadoop.hive.ql.udf.generic.GenericUDFDateFormat';
SELECT
parse_date(date_str,
CASE
WHEN date_str LIKE '%/%' THEN 'yyyy/MM/dd'
WHEN date_str LIKE '%-%' THEN 'yyyy-MM-dd'
ELSE 'MMM dd, yyyy'
END
)
FROM dates_table;
4. 日期转时间戳
SELECT
unix_timestamp('2023-08-20 14:30:00'), -- 默认格式转换
cast(to_unix_timestamp('2023-08-20','yyyy-MM-dd') AS BIGINT);
5. 日期格式的转换
--20191019 转换为 2019-10-19
select from_unixtime(unix_timestamp('20191019','yyyymmdd'),'yyyy-mm-dd');
--结果:2019-10-19
--2019-10-19 转换为 20191019
select from_unixtime(unix_timestamp('2019-10-19','yyyy-mm-dd'),'yyyymmdd');
--结果:20191019
6. 时间戳转日期
SELECT
from_unixtime(1692520200), -- 默认格式
from_unixtime(1692520200, 'HH:mm:ss'); -- 指定格式
五、生产级实战案例
场景:多源日志日期统一处理
-- 创建原始日志表
CREATE TABLE raw_logs (
log_id STRING,
event_time STRING -- 混合格式:20230820 / 2023-08-20 / August 20, 2023
) STORED AS PARQUET;
-- 创建标准化日期表
CREATE TABLE std_logs (
log_id STRING,
event_date DATE,
event_hour INT
);
-- 执行转换
INSERT INTO std_logs
SELECT
log_id,
CASE
WHEN event_time REGEXP '^\\d{8}$' THEN to_date(event_time)
WHEN event_time LIKE '%-%' THEN to_date(event_time)
ELSE from_unixtime(
unix_timestamp(event_time, 'MMM dd, yyyy'),
'yyyy-MM-dd'
)
END AS event_date,
hour(from_unixtime(unix_timestamp())) AS event_hour
FROM raw_logs;
六、高频问题解决方案
1. 时区不一致问题
-- 设置会话时区
SET hive.timezone=Asia/Shanghai;
-- 显式转换时区
SELECT
from_utc_timestamp(current_timestamp(), 'GMT+08:00'),
to_utc_timestamp(current_timestamp(), 'Asia/Tokyo');
2. 闰年二月处理
-- 自动处理闰年
SELECT add_months('2020-02-28', 1); -- 2020-03-28
SELECT last_day('2020-02-15'); -- 2020-02-29
3. 性能优化建议
-- 避免在WHERE条件中使用函数
-- 反例(全表扫描):
SELECT * FROM logs WHERE date_format(event_time,'yyyyMMdd')='20230820';
-- 正例(分区剪裁):
SELECT * FROM logs WHERE event_date='2023-08-20';
七、总结与最佳实践
1. 格式选择优先级:
DATE类型 > 格式统一STRING > Unix时间戳
2. 函数性能排行:
to_date > unix_timestamp > from_unixtime > date_format
3. 避坑指南:
统一服务器时区配置日期字符串存入前做格式校验分区字段使用DATE类型
4. 扩展建议:
对于复杂时间序列处理,推荐使用Hive 3.0+的OVER窗口函数:
SELECT
event_time,
AVG(value) OVER(ORDER BY event_time RANGE BETWEEN INTERVAL '1' HOUR PRECEDING AND CURRENT ROW)
FROM sensor_data;
扩展文章(推荐)
1. 参数配置:
Hive配置参数终极指南:核心参数详解、调优实战与避坑手册
2. 核心内置函数和自定义UDF:
Hive函数大全:从核心内置函数到自定义UDF实战指南(附详细案例与总结)
3. Hive参数(groupby.skewindata遇到map.aggr的致命组合):
Hive学习(6)Hive性能优化避坑指南:当groupby.skewindata遇到map.aggr的致命组合
码字不易,喜欢请点赞,谢谢!!!😊