hive日期转换
两种日期的转换:
dt = '20190408'
partition_date = '2019-04-08'
从partition_date到dt
date2datekey('partition_date')
反过来用
datekey2datek('dt')
将指定格式的字符串转换为时间戳
select unix_timestamp("2022-10-09T14:35:55.337", "yyyy-MM-dd'T'HH:mm:ss.SSS");
select unix_timestamp("2022-10-09T06:36:24.930Z", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
将时间戳转换为timestamp
select from_unixtime(unix_timestamp("2022-10-09T06:36:24.930Z", "yyyy-MM-dd'T'HH:mm:ss.SSS"));
select from_unixtime(unix_timestamp("2022-10-09T06:36:24.930Z", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
将任意字符串转换为timestamp
select timestamp("2022-10-18T20:42:59.717");
但是不支持T, Z这些特殊字符,可以先用正则处理,再使用timestamp
select timestamp(regexp_replace("2019-05-17T17:03:09.775Z", '^(.+?)T(.+?)Z1 $2'));
时区问题
Hive中的timestamp与时区无关,存储为UNIX纪元的偏移量。Hive提供了用于timestamp和时区相互转换的便利UDF:to_utc_timestamp和 from_utc_timestamp
将utc时间转换为北京时间
from_utc_timestamp(utc_timestamp,'PRC')
JAVA时间API
时区
全球有25个时区,其中Z时区也称为UTC时区为初始时区,所谓的时区偏移量是相对于UTC时区的偏移量,比如偏移1h 30min
虽然有时间偏差,但时间在这个25个时区是一一对应的,可以互相转换
localDateTime不携带时区的概念
字符串转localDateTime:
不带有时区的字符串转为localDateTime,默认该字符串的隐藏时区为机器所在的地理位置,比如中国;
所以localDateTime转换为Instant时,由于Instant表示的是UTC时区,localDateTime实际存放的时间是中国东8时区,转换为Instant需要手动指定中国时区相对于UTC时区的偏移,即+8
带有时区的字符串不能直接转换为localDateTime,而是需要先单独转换字符串对应的时区,再转换localDateTime
日期格式大全
https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
如何将带有时区的字符串转换为localDateTime
1)先将字符串转换为Instant,即字符串转utc时间
DateTimeFormatter dtf = DateTimeFormatter.ofPattern
("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
instant = Instant.from(dtf.parse("2021-12-23T23:42:50.000-0700"))
2)再将Instant转换为LocalDateTime,设置想要数据显示时机器所在的时区
localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
关于X,x,XXX,Z,ZZZ 等字母的区别
SimpleDateFormat
将时间转换为指定时区
通过指定时区id进行转换
DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss");
formatter.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); //here set timezone
System.out.println(formatter.format(new Date()));
手动指定时间字符串所隐含的时区offset,将带有时区的该时间,转换为对应的utc时间
val localDateTime = LocalDateTime.parse(EndDateTime, "yyyy-MM-dd HH:mm:ss")
localDateTime.toInstant(ZoneOffset.of("+8")).toString
将字符串日期转换为时间毫秒数
LocalDateTime localDateTime = LocalDateTime.parse(dateStr, dtf);
long ts = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli()
比较两个时间相差的月份
public static Integer between(LocalDate one,LocalDate two) {
return Period.between(one,two).getMonths();
}