【发布时间】:2019-11-29 12:05:57
【问题描述】:
我有一个名为 lastModified 的列,其字符串如下所示,表示 GMT 时间。 “2019-06-24T15:36:16.000Z”
我想使用 scala 在 spark 中将此字符串格式化为 yyyy-MM-dd HH:mm:ss 格式。为此,我创建了一个带有新列 "ConvertedTS" 的数据框。 这给出了错误的时间。
我运行它的机器位于美国/纽约时区。
df.withColumn("ConvertedTS", date_format(to_utc_timestamp(to_timestamp(col("lastModified"), "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"), "America/New_York"), "yyyy-MM-dd HH:MM:SS").cast(StringType))
我基本上是在 yyyy-MM-dd HH:mm:ss 中寻找格式化以下语句的结果
df.withColumn("LastModifiedTS", col("lastModified"))
目前对我有用的一种方法是 udf,但由于不推荐使用 udf,我一直在寻找更多可以使用的直接表达式。
val convertToTimestamp = (logTimestamp: String) => {
println("logTimeStamp: " + logTimestamp)
var newDate = ""
try {
val sourceFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
sourceFormat.setTimeZone(TimeZone.getTimeZone("GMT"))
val convertedDate = sourceFormat.parse(logTimestamp)
val destFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
destFormat.setTimeZone(TimeZone.getTimeZone("GMT"))
newDate = destFormat.format(convertedDate)
println("newDate: " + newDate)
} catch {
case e: Exception => e.printStackTrace()
}
newDate
}
//register for sql
EdlSparkObjects.sparkSession.sqlContext.udf.register("convertToTimestamp", convertToTimestamp)
// register for scala
def convertToTimestampUDF = udf(convertToTimestamp)
df.withColumn("LastModifiedTS", convertToTimestampUDF(col("lastModified")))
感谢您的帮助和指导。
【问题讨论】:
-
除了不推荐使用 UDF 之外,我建议您不要使用
SimpleDateFormat和TimeZone。这些类设计不良且过时,尤其是前者,尤其是出了名的麻烦。而是使用Instant、ZonedDateTime和DateTimeFormatter,均来自java.time, the modern Java date and time API。 -
谢谢奥莱。这里有什么使用指南吗?
-
我只能编写 Java 代码:
Instant.parse("2019-06-24T15:36:16.000Z").atZone(ZoneId.of("America/New_York")).format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss"))产生2019-06-24 11:36:16。 Tutorial here.
标签: scala apache-spark dataframe apache-spark-sql user-defined-functions