日期 - 草稿

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(.+?)Z','1 $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


image.png

将时间转换为指定时区

通过指定时区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();
}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容