在 Scala 中将字符串纪元转换为字符串时间戳

Convert string epoch to string timestamp in Scala

我有一列 ORDER_DATE,字符串中包含纪元时间戳。如何将此列与 str = "1536309236032" 之类的字符串(纪元中的时间)转换为具有以下格式的字符串:Scala 中的 2018-09-07T14:03:56.032Z

目前我正在使用:

from_unixtime(input.col(ORDER_DATE), "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")

但这会错误地转换为 50668-08-21 01:10:00.000。在这里,它增加了年份并增加了 000 毫秒。

我不想除以 1000,因为我们希望得到以毫秒为单位的结果。

在文档中,from_unixtime的定义如下:

Converts the number of seconds from unix epoch (1970-01-01 00:00:00 UTC) to a string representing the timestamp of that moment in the current system time zone in the given format.

它使用秒,因此与毫秒不兼容,这就是结果错误的原因。要转换纪元时间戳并保留毫秒信息,您可以使用 concat:

val spark = SparkSession.builder.getOrCreate()
import spark.implicits._

df.withColumn("time", concat(
    from_unixtime($"ORDER_DATE"/1000, "yyyy-MM-dd'T'HH:mm:ss."), 
    $"ORDER_DATE".substr(length($"ORDER_DATE")-2, length($"ORDER_DATE")), 
    lit("Z")))

这将起作用,因为纪元时间戳中的最后 3 位数字与想要的结果中的数字相同。

我从@Shaido 那里得到了这个想法,我也做了类似的事情。最后,这为我解决了问题:

input.withColumn("time",
concat(from_unixtime(input.col("ORDER_DATE")/1000, "yyyy-MM-dd'T'HH:mm:ss"), 
typedLit("."), substring(input.col("ORDER_DATE"), 11, 3), typedLit("Z")))