Spark 2.1 Scala环境下将时间戳转换为UTC的实现方法
解决Spark 2.1 + Scala下带时区的时间转UTC问题
嘿,我之前在Spark 2.1里处理过几乎一模一样的时区转换需求,刚开始也绕了点弯路,其实两种方案都能搞定,看你更倾向于内置函数还是自定义UDF:
方案一:自定义UDF(推荐,处理夏令时更可靠)
Spark 2.1的内置时间函数在处理带时区的字符串解析时有点局限,所以用Java 8的时间API写个UDF是最稳妥的,它能自动处理夏令时这类时区规则变化:
import org.apache.spark.sql.functions.udf import java.time.{ZonedDateTime, ZoneId} import java.time.format.DateTimeFormatter // 定义UDF:接收原始时间字符串和时区,返回UTC格式的时间字符串 val convertToUtcUdf = udf((timestampStr: String, timezone: String) => { // 匹配你的时间格式,这里用ISO_LOCAL_DATE_TIME对应"yyyy-MM-dd'T'HH:mm:ss..."格式 val formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME // 解析原始时间为对应时区的ZonedDateTime val zonedDateTime = ZonedDateTime.parse(timestampStr, formatter.withZone(ZoneId.of(timezone))) // 转换为UTC时区并格式化输出 zonedDateTime.withZoneSameInstant(ZoneId.of("UTC")).format(formatter) }) // 应用UDF到你的DataFrame,生成新的utc_timestamp列 val utcDF = myDF.withColumn("utc_timestamp", convertToUtcUdf(col("orign_timestamp"), col("origin_timezone")))
方案二:用Spark内置函数组合(适合简单场景)
如果你的数据不会涉及夏令时变化,或者时区偏移固定,也可以用内置函数拼接实现,不过要注意时间格式要和你的orign_timestamp完全匹配:
import org.apache.spark.sql.functions._ // 步骤:1. 将原始时间转成对应时区的时间戳;2. 转成UTC时间字符串 val utcDF = myDF.withColumn("utc_timestamp", from_utc_timestamp( to_timestamp(col("orign_timestamp"), "yyyy-MM-dd'T'HH:mm:ss"), col("origin_timezone") ) )
注意:这个方案里
to_timestamp会先用Spark会话的默认时区解析字符串,然后再转成指定时区的时间,最后转成UTC。如果你的原始时间字符串本身不带时区信息,且默认时区和原始时区不一致,结果会出错,所以更推荐方案一。
验证结果
你可以用show()查看转换后的结果:
utcDF.select("orign_timestamp", "origin_timezone", "utc_timestamp").show(false)
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

