Datetime 在spark中将纳秒级字符串转换为时间戳

Datetime 在spark中将纳秒级字符串转换为时间戳,datetime,apache-spark,apache-spark-sql,Datetime,Apache Spark,Apache Spark Sql,是否有一种方法可以将带有纳秒的时间戳值转换为spark中的时间戳。我从csv文件获取输入,timstamp值为格式 12-12-2015 14:09:36.992415+01:00。这是我试过的代码 val date_raw_data = List((1, "12-12-2015 14:09:36.992415+01:00")) val dateraw_df = sc.parallelize(date_raw_data).toDF("ID", "TIMESTAMP_VALUE") val t

是否有一种方法可以将带有纳秒的时间戳值转换为spark中的时间戳。我从csv文件获取输入,timstamp值为格式
12-12-2015 14:09:36.992415+01:00
。这是我试过的代码

val date_raw_data = List((1, "12-12-2015 14:09:36.992415+01:00"))

val dateraw_df = sc.parallelize(date_raw_data).toDF("ID", "TIMESTAMP_VALUE")

val ts = unix_timestamp($"TIMESTAMP_VALUE", "MM-dd-yyyy HH:mm:ss.ffffffz").cast("double").cast("timestamp")

val date_df = dateraw_df.withColumn("TIMESTAMP_CONV", ts).show(false)
输出是

+---+-----------------------+---------------------+
|ID |TIMESTAMP_VALUE        |TIMESTAMP_CONV       |
+---+-----------------------+---------------------+
|1  |12-12-2015 14:09:36.992|null                 |
+---+-----------------------+---------------------+

我能够使用格式
MM-dd-yyy-HH:MM:ss.SSS
将时间戳转换为毫秒。问题在于纳秒和时区格式。

unix\u时间戳在这里不起作用。即使您可以解析字符串(AFAIK不提供所需的格式),
unix\u timestamp
(emphasis mine):

def unix\u时间戳(s:Column,p:String):Column

将具有给定模式的时间字符串(请参见[])转换为Unix时间戳(,以秒为单位),如果失败,则返回null

您必须创建自己的函数来解析此数据。一个粗略的想法:

import org.apache.spark.sql.functions_
导入org.apache.spark.sql.Column
def至_nano(c:柱)={
val r=“([0-9]{2}-[0-9]{2}-[0-9]{4}[0-9]{2}:[0-9]{2}:[0-9]{2})(\\\.[0-9]*)(.*)$”
//第二部分
(unix_)时间戳(
海螺(
regexp_extract($“时间戳_值”,r,1),
regexp_提取($“时间戳_值”,r,3)
),“年月日HH:MM:ssXXX”
).cast(“十进制(38,9)”)+
//亚秒部分
regexp_extract($“TIMESTAMP_VALUE”,r,2).cast(“十进制(38,9)”).alias(“VALUE”)
}
Seq(“12-12-2015 14:09:36.992415+01:00”).toDF(“时间戳_值”)
.select(to_nano($“TIMESTAMP_COLUMN”).cast(“TIMESTAMP”))
.show(假)
// +--------------------------+
//|价值|
// +--------------------------+
// |2014-12-28 14:09:36.992415|
// +--------------------------+

如果你不在乎纳秒,那么在没有UDF的情况下,这里有一个肮脏的小把戏可以让这一切顺利进行。(我不能在需要时使用自定义项,也不能修改源)

例如

我基本上是将字符串从纳秒部分剥离出来,然后用spark SimpleDateFormat兼容解析器解析其余部分


请未来的雇主,不要用这个回答来判断我。

一个更正时间戳上的out put CONV列为null,这意味着转换失败。您可以尝试向CSV提供自定义模式,列值为TIMESTAMP。我尝试使用自定义模式“import org.apache.spark.sql.types.”;val customSchema=StructType(Seq(StructField(“ID”,DataTypes.IntegerType,true),StructField(“TIMESTAMP_VALUE”,DataTypes.TimestampType,true));`但是现在我得到了错误java.lang.ClassCastException:scala.Tuple2不能转换为java.lang.IntegerMay我应该提到我使用的是spark 1.6为什么不使用TimeUnit.NANOSECONDS.convert(时间,TimeUnit.毫秒)????
select CAST(UNIX_TIMESTAMP(substr(date,0,length(date)-4), "yyyy-MM-dd'T'HH:mm:ss.SSS") AS TIMESTAMP);
select CAST(UNIX_TIMESTAMP(substr("2020-09-14T01:14:15.596444Z",0,length("2020-09-14T01:14:15.596444Z")-4), "yyyy-MM-dd'T'HH:mm:ss.SSS") AS TIMESTAMP);