我在spark中有一个架构
root
|-- atom: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- dailydata: array (nullable = true)
| | | |-- element: struct (containsNull = true)
| | | | |-- datatimezone: string (nullable = true)
| | | | |-- intervaltime: long (nullable = true)
| | | | |-- intervalvalue: long (nullable = true)
| | | | |-- utcacquisitiontime: string (nullable = true)
| | |-- usage: string (nullable = true)
| -- titlename: string (nullable = true)
我从上面的架构
中提取了utcacquisitiontime
和datatimezone
,如下所示
val result=q.selectExpr("explode(dailydata) as r").select("r.utcacquisitiontime","r.datatimezone")
+--------------------+------------+
| utcacquisitiontime|datatimezone|
+--------------------+------------+
|2017-03-27T22:00:00Z| +02:00|
|2017-03-27T22:15:00Z| +02:00|
|2017-03-27T22:30:00Z| +02:00|
|2017-03-27T22:45:00Z| +02:00|
|2017-03-27T23:00:00Z| +02:00|
|2017-03-27T23:15:00Z| +02:00|
|2017-03-27T23:30:00Z| +02:00|
|2017-03-27T23:45:00Z| +02:00|
|2017-03-28T00:00:00Z| +02:00|
|2017-03-28T00:15:00Z| +02:00|
|2017-03-28T00:30:00Z| +02:00|
|2017-03-28T00:45:00Z| +02:00|
|2017-03-28T01:00:00Z| +02:00|
|2017-03-28T01:15:00Z| +02:00|
|2017-03-28T01:30:00Z| +02:00|
|2017-03-28T01:45:00Z| +02:00|
|2017-03-28T02:00:00Z| +02:00|
|2017-03-28T02:15:00Z| +02:00|
|2017-03-28T02:30:00Z| +02:00|
|2017-03-28T02:45:00Z| +02:00|
+--------------------+------------+
我需要使用这两列计算localtime
,并在计算后将其替换为localtime
。我该如何计算localtime
并替换它?
答案 0 :(得分:2)
你可以依靠spark(用户自定义函数)中的udf函数。同样在org.apache.sql.functions._中有很多已经预定义的函数可以帮助你。但这是你如何做这项工作
+-------------------+------------+
| utcacquisitiontime|datatimezone|
+-------------------+------------+
|2017-03-27T22:00:00| +02:00|
+-------------------+------------+
请注意,我已从时间列中删除了不必要的“Z”。 使用JodaTime依赖项定义一个像这样的udf函数:
val toTimestamp = udf((time:String, zone:String) => {
val timezone = DateTimeZone.forID(zone)
val df = DateTimeFormat.forPattern("yyyy-mm-dd'T'HH:mm:ss")
new java.sql.Timestamp(df.withZone(timezone).parseDateTime(time).getMillis)
})
将其应用于withColumn
df.withColumn("timestamp", toTimestamp(col("utcacquisitiontime"), col("datatimezone"))
显示结果(请注意,在模式中,列时间戳的类型为Timestamp,因此您可以对其执行日期操作)
+-------------------+------------+--------------------+
| utcacquisitiontime|datatimezone| timestamp|
+-------------------+------------+--------------------+
|2017-03-27T22:00:00| +02:00|2017-01-27 22:00:...|
+-------------------+------------+--------------------+
root
|-- utcacquisitiontime: string (nullable = true)
|-- datatimezone: string (nullable = true)
|-- timestamp: timestamp (nullable = true)
答案 1 :(得分:0)
您可以使用Joda Time API将df列中的时间转换为本地时间,例如,
def convertToLocal(str:String):String = new DateTime(str).toLocalDateTime().toString
接下来你导入sql implicits,
import ss.implicits._
其中ss是SparkSession
的实例。要将utcacquisitiontime列的每个元素转换为localDateTime,请执行以下操作
val df=result map(r=>(convertToLocal(r.getString(0)),r.getString(1)))
df show
如果这有帮助,请告诉我。欢呼声。