将火花数据帧中的日期时间时间戳转换为 epocTimestamp
Posted
技术标签:
【中文标题】将火花数据帧中的日期时间时间戳转换为 epocTimestamp【英文标题】:Convert date time timestamp in spark dataframe to epocTimestamp 【发布时间】:2020-12-04 15:16:39 【问题描述】:我有一个带有时间戳列的镶木地板文件,格式为2020-07-07 18:30:14.500000+00:00
,由 pandas 编写。当我在 spark 中读取同一个 parquet 文件时,它被读取为2020-07-08 00:00:14.5
。
我想将其转换为以毫秒为单位的纪元时间戳,即 1594146614500
我尝试过使用 java 日期时间格式
val dtformat = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
dtformat.parse(r2.getAs[Long]("date_time").toString).getTime
它正在转换但错误的值 (1594146614005) 而不是 1594146614500。
为了使它正确,我必须添加 dtformat.parse(r2.getAs[Long]("date_time").toString+"00").getTime
。
还有比这更干净的方法吗?
spark 中的任何可用函数以毫秒为单位读取它?
更新 1:
使用以下答案后:
df.withColumn("timestamp", to_timestamp($"date_time", "yyyy-MM-dd HH:mm:ss.SSSSSSXXX")).withColumn("epoch", ($"timestamp".cast("十进制(20, 10)") * 1000).cast("bigint")).show()
+-------------+--------------------+-------------------+-------------+
|expected_time| original_time| timestamp| epoch|
+-------------+--------------------+-------------------+-------------+
|1597763904500|2020-08-18 20:48:...|2020-08-18 20:48:24|1597763904000|
|1597763905000| 2020-08-18 20:48:25|2020-08-18 20:48:25|1597763905000|
|1597763905500|2020-08-18 20:48:...|2020-08-18 20:48:25|1597763905000|
缺点是假设如果数据的粒度为 500ms,那么每个时间戳都有两个相同的 epoc 时间戳,这是不期望的。
【问题讨论】:
我建议你不要使用SimpleDateFormat
。这个类是出了名的麻烦和过时。而是使用来自java.time, the modern Java date and time API 的LocalDateTime
和DateTimeFormatter
。 SimpleDateFormat
也无法解析 2020-07-08 00:00:14.5
。它只支持毫秒,精确到秒的三位小数。
【参考方案1】:
我建议您从 java.util
和相应的格式化 API (java.text.SimpleDateFormat
) 切换到过时的容易出错的日期/时间 API 到 java.time
的 modern date/time API 和相应的格式化 API (java.time.format
)。从 Trail: Date Time
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
public class Main
public static void main(String[] args)
OffsetDateTime odt = OffsetDateTime.parse("2020-07-07 18:30:14.500000+00:00",
DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSSSSZZZZZ"));
System.out.println(odt.toInstant().toEpochMilli());
输出:
1594146614500
【讨论】:
【参考方案2】:使用 spark 数据框功能,
df.withColumn("timestamp", to_timestamp($"time", "yyyy-MM-dd HH:mm:ss.SSSSSSXXX"))
.withColumn("epoch", ($"timestamp".cast("decimal(20, 10)") * 1000).cast("bigint"))
.show(false)
+--------------------------------+---------------------+-------------+
|time |timestamp |epoch |
+--------------------------------+---------------------+-------------+
|2020-07-07 18:30:14.500000+00:00|2020-07-07 18:30:14.5|1594146614500|
+--------------------------------+---------------------+-------------+
这也是一种可行的方法。
【讨论】:
感谢@Lamanus,使用它有一个缺点,如果数据的粒度为 500 毫秒,那么每个时间戳都有两个与我在问题中更新的值相同的值。 我不明白。您的原始时间没有正确显示,甚至格式看起来也不同。以上是关于将火花数据帧中的日期时间时间戳转换为 epocTimestamp的主要内容,如果未能解决你的问题,请参考以下文章
遍历 Float 时间戳的 Pandas DataFrame 并转换为日期时间