Hive时间戳TIMESTAMP使用的限制

本文介绍在Hive中使用TIMESTAMP类型字段时遇到的问题及原因分析。当通过LOAD命令加载数据时,仅符合特定格式(yyyy-MM-dd HH:MM:SS)的时间数据才能被正确解析,否则会被识别为NULL。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Hive中提供了字段类型TIMESTAMP,但其对应的时间格式为yyyy-MM-dd HH:MM:SS,即通过LOAD命令将文本加载到已创建的表中时,只有满足上述格式的内容才可以被正确解析,否则只能识别为NULL。


1.        创建表。

create table airline
 (
 Yyear double,
 Tt double,
 W double,
 R double,
 L double,
 K double,
 T timestamp

 )
 PARTITIONED BY(dt string) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

1.        将文本上传到HDFS。

hadoop fs -put /root/airline.csv /opt/hadoop/zet_data/airline.csv
其中文本内容如下所示:
1948.000008,1.213999987,0.243000001,0.145400003,1.414999962,0.611999989,2017-11-13 12:00:00
1949.000008,1.353999972,0.25999999,0.218099996,1.383999944,0.559000015,2017-11-14 12:01:00
1950,1.569000006,0.277999997,0.315699995,1.388000011,0.573000014,2017-11-15 12:02:00
1951,1.947999954,0.296999991,0.393999994,1.549999952,0.56400001,2017-11-16 12:03:00
1952,2.265000105,0.310000002,0.35589999,1.802000046,0.574000001,2017-11-17 12:04:00
1953,2.730999947,0.321999997,0.359299988,1.925999999,0.711000025,2017-11-18 12:05:00
1954,3.025000095,0.335000008,0.402500004,1.963999987,0.776000023,1528169207
1955,3.562000036,0.349999994,0.396100014,2.115999937,0.827000022,20171120 12:07:00
1956,3.979000092,0.361000001,0.382200003,2.434999943,0.800000012,2017/11/21 12:08:00
上述内容中,每行的最后一个字段为时间,前六条记录的该字段满足yyyy-MM-ddHH:MM:SS格式,后三条的为其它格式。

3.        加载文本。

LOAD DATA INPATH '/opt/hadoop/zet_data/airline.csv' INTO TABLE ariline PARTITION (dt='201312');
4.       在HUE中查看表中的内容。

可以看出,最后三列无法识别,显示为NULL。


<think>我们有一个任务:将Hive中的时间戳转换为日期格式。时间戳通常指的是从1970年1月1日00:00:00 UTC开始计算的秒数(或毫秒数)。在Hive中,我们通常使用内置函数进行转换。根据引用,我们可以使用`from_unixtime`函数将时间戳(秒数)转换为字符串格式的日期。该函数的第一个参数是时间戳(整数),第二个参数是目标日期格式(可选,默认为'yyyy-MM-dd HH:mm:ss')。例如,将时间戳(秒)转换为'yyyy-MM-dd'格式的日期: ```sqlselect from_unixtime(1609459200, 'yyyy-MM-dd');``` 这将返回:'2021-01-01'注意:如果时间戳是以毫秒为单位的,我们需要先将其转换为秒(除以1000),因为`from_unixtime`函数默认处理的是秒级时间戳。例如,对于毫秒级时间戳1609459200000,我们可以这样转换: ```sqlselect from_unixtime(cast(1609459200000as bigint)/1000, 'yyyy-MM-dd');``` 或者更简洁地:```sqlselectfrom_unixtime(1609459200000 div1000,'yyyy-MM-dd'); ```另外,如果我们的时间戳是字符串格式的,我们需要先将其转换为整数类型(比如bigint)再进行计算。例如: ```sqlselect from_unixtime(cast('1609459200'as bigint),'yyyy-MM-dd'); ```如果我们的时间戳列是浮点数,也可以直接使用,因为函数会将其转换为整数(截断小数部分)。另外,引用[1]中提到了将字符串日期格式从'yyyyMMdd'转换为'yyyy-MM-dd'的方法,这使用了`unix_timestamp`和`from_unixtime`的组合:```sqlselectfrom_unixtime(unix_timestamp('20211022','yyyyMMdd'),"yyyy-MM-dd"); ```这里,`unix_timestamp`函数将字符串日期(格式为'yyyyMMdd')转换为时间戳(秒),然后`from_unixtime`函数将时间戳转换为目标格式的字符串。但是,如果我们的需求是直接将时间戳(数值类型)转换为日期格式,那么直接使用`from_unixtime`即可。 总结步骤:1.确认时间戳的单位(秒还是毫秒)。如果是毫秒,需要先除以1000转换为秒。2.使用`from_unixtime`函数,指定目标日期格式。示例: -秒级时间戳转日期(格式为'yyyy-MM-dd HH:mm:ss'):```sqlselect from_unixtime(1614556800);```结果:'2021-02-2800:00:00' -毫秒级时间戳转日期(格式为'yyyy-MM-dd'):```sqlselectfrom_unixtime(1614556800000/1000, 'yyyy-MM-dd');```或```sqlselectfrom_unixtime(cast(1614556800000 asdouble)/1000, 'yyyy-MM-dd');```注意:Hive中整数除法会得到整数,所以如果毫秒时间戳是bigint类型,除以1000可能会被截断(整数除法)。为了避免这个问题,可以先将毫秒时间戳转换为double类型再除以1000,或者使用`div`运算符(整数除法)并确保没有小数部分。另外,如果目标格式是其他形式,比如'yyyy/MM/dd',只需修改第二个参数即可。例如:```sqlselectfrom_unixtime(1614556800, 'yyyy/MM/dd HH:mm:ss'); ```结果:'2021/02/2800:00:00'如果时间戳列是表中的一个字段,假设字段名为`timestamp_col`,则转换的SQL语句为:```sqlselectfrom_unixtime(timestamp_col, 'yyyy-MM-dd')as date_colfrom table_name;``` (如果是毫秒,则使用`timestamp_col/1000`)另外,Hive3.0及以上版本支持新的日期函数,比如`to_date`,但`to_date`只能返回日期部分(格式固定为'yyyy-MM-dd'),且输入必须是日期字符串或时间戳类型(timestamp)。如果我们的时间戳是整数类型,还是使用`from_unixtime`更直接。 如果我们需要转换为Hive中的Date类型(而不是字符串),可以使用`to_date(from_unixtime(timestamp_col))`,这样会得到'yyyy-MM-dd'格式的Date类型。例如:```sqlselectto_date(from_unixtime(1614556800)) asmy_date;```但是,如果只需要字符串形式的日期,直接使用`from_unixtime`并指定格式即可。 因此,根据需求,我们选择合适的方法。</think>### Hive 时间戳转日期格式方法 在 Hive 中,时间戳(Unix 时间戳)到日期格式的转换主要通过 `from_unixtime()` 函数实现。以下是详细步骤和示例: #### 1. **基本转换方法** - **语法**:`from_unixtime(unix_timestamp, format)` - **功能**: - `unix_timestamp`:整数类型的时间戳(秒级) - `format`:目标日期格式(可选,默认为 `yyyy-MM-dd HH:mm:ss`) - **示例**: ```sql -- 将时间戳 1661990400 转为默认格式 SELECT from_unixtime(1661990400); -- 输出:2022-08-31 00:00:00 -- 指定目标格式为 yyyy-MM-dd SELECT from_unixtime(1661990400, 'yyyy-MM-dd'); -- 输出:2022-08-31 ``` #### 2. **处理毫秒级时间戳** 若时间戳为毫秒级(13位),需先转换为秒级: ```sql -- 毫秒级时间戳转日期 SELECT from_unixtime(CAST(1661990400000 AS BIGINT) / 1000, 'yyyy-MM-dd'); -- 输出:2022-08-31 ``` #### 3. **字符串时间戳转换** 若时间戳以字符串形式存储,需先转为数值类型: ```sql -- 字符串时间戳转日期 SELECT from_unixtime(CAST('1661990400' AS BIGINT), 'yyyy-MM-dd'); -- 输出:2022-08-31 ``` #### 4. **常用日期格式示例** | 目标格式 | Hive 语句示例 | 输出结果 | |----------------|----------------------------------------|------------------| | `yyyy-MM-dd` | `from_unixtime(1661990400, 'yyyy-MM-dd')` | 2022-08-31 | | `yyyy/MM/dd` | `from_unixtime(1661990400, 'yyyy/MM/dd')` | 2022/08/31 | | `yyyy年MM月dd日` | `from_unixtime(1661990400, 'yyyy年MM月dd日')` | 2022年08月31日 | | `HH:mm:ss` | `from_unixtime(1661990400, 'HH:mm:ss')` | 00:00:00 | #### 5. **复杂场景:日期格式互转** 若需将其他格式的日期字符串(如 `yyyyMMdd`)转为标准日期格式,可结合 `unix_timestamp()`: ```sql -- 将 '20220831' (yyyyMMdd) 转为 'yyyy-MM-dd' SELECT from_unixtime( unix_timestamp('20220831', 'yyyyMMdd'), -- 先转时间戳 'yyyy-MM-dd' -- 再转目标格式 ); -- 输出:2022-08-31 [^1] ``` #### 注意事项 - **时区问题**:Hive 默认使用 UTC 时区,如需本地时区需配置 `hive.session.timezone`。 - **空值处理**:非法时间戳或格式错误会返回 `NULL`。 - **性能优化**:对大规模数据避免逐行转换,优先用数值计算。 > 引用说明: > [^1]: 日期格式转换示例参考 Hive 标准方法。 > [^2]: 时间戳处理需注意输入格式匹配性。 > [^3]: 复杂日期转换需分步处理。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汀桦坞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值