问题描述
我在spark数据框中有一个列
时间跨度
值在iso 8601持续时间内
例如:P0Y0M0DT0H5M35S
。我想将这些值转换为秒。 spark或Scala中是否有功能可以帮助我做到这一点?我正在寻找一种方法,但未成功
我尝试了持续时间
import java.time.Duration
java.time.Duration.parse("P0Y0M0DT0H5M35S")
这给我带来了错误:
java.time.format.DateTimeParseException: Text cannot be parsed to a Duration
在将值传递给函数时,我做错了什么吗?我找到了这份文件 https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html
如果我以这种方式成功完成操作,则必须在整个dataframe列上应用其他逻辑
解决方法
希望以下方法对您有所帮助。
import org.apache.spark.sql.types._
import org.apache.spark.sql.functions._
val isoToSecondsUDF = udf( (value: String) => (java.time.Duration.parse("PT".concat(value.split("T")(1))).get(java.time.temporal.ChronoUnit.SECONDS)))
val df=Seq(("P0Y0M0DT0H5M35S")).toDF("value")
df.withColumn("seconds",isoToSecondsUDF($"value")).show()
/*
+---------------+-------+
| value|seconds|
+---------------+-------+
|P0Y0M0DT0H5M35S| 335|
+---------------+-------+
*/
,
更新了解决方案以涵盖存在月份和日期的情况 例如:P0Y0M2DT23H59M56S。和P0Y1M2DT23H59M56S
我们将需要使用time4j lib:https://github.com/MenoData/Time4J
这是代码:
import org.apache.spark.sql.types._
import org.apache.spark.sql.functions._
import net.time4j.Duration
def getSeconds(value: String) : String={
var b = Duration.parsePeriod(value).toTemporalAmount().get(java.time.temporal.ChronoUnit.MONTHS)
var c = Duration.parsePeriod(value).toTemporalAmount().get(java.time.temporal.ChronoUnit.DAYS)
var days =((b*30)+c).toString()
var seconds = (java.time.Duration.parse("P".concat(days).concat("DT").concat(if(value.contains("T")) value.split("T")(1) else value.split("D")(1))).get(java.time.temporal.ChronoUnit.SECONDS)).toString()
return seconds
}
val isoToSecondsUDF = udf( (value: String) => getSeconds(value))
spark.udf.register("isoToSecondsUDF",isoToSecondsUDF)
val df=Seq(("P0Y0M2DT23H59M56S")).toDF("value")
df.withColumn("seconds",isoToSecondsUDF($"value")).show()
首先获取月份数,然后转换为天数并将其添加到现有的天数中,然后将其传递给解析方法。 @sathya
输出:
+-----------------+-------+
| value|seconds|
+-----------------+-------+
|P0Y0M2DT23H59M56S| 259196|
+-----------------+-------+
+-----------------+-------+
| value|seconds|
+-----------------+-------+
|P0Y1M2DT23H59M56S|2851196|
+-----------------+-------+