如何在Spark中将Unix时间戳转换为日期

44

我有一个数据框,其中包含一个Unix时间戳列(例如1435655706000),我希望将其转换为格式为“yyyy-MM-DD”的日期。我尝试了nscala-time,但它不起作用。

val time_col = sqlc.sql("select ts from mr").map(_(0).toString.toDateTime)
time_col.collect().foreach(println)

我遇到了错误:

java.lang.IllegalArgumentException: 无效格式:"1435655706000" 在 "6000" 处格式不正确


https://dev59.com/rGMl5IYBdhLWcg3wHTyg - Nikita
已解决,导入org.joda.time._,sqlc.sql("select ts from mr").map(line => new DateTime(line(0)).toString("yyyy-MM-dd"))。 - youngchampion
7个回答

37

以下是使用Scala DataFrame函数: from_unixtimeto_date

// NOTE: divide by 1000 required if milliseconds
// e.g. 1446846655609 -> 2015-11-06 21:50:55 -> 2015-11-06 
mr.select(to_date(from_unixtime($"ts" / 1000))) 

由于我想要将其转换为UTC时间,所以我进行了以下操作:to_utc_timestamp(from_unixtime($"buyOrdrEntryTime"/1000,"yyyy-MM-dd hh:mm:ss"),"Europe/Berlin").as("buyOrdrEntryTime")。 - Playing With BI

29

自Spark 1.5版本以来,有一个内置的UDF可以执行此操作。

val df = sqlContext.sql("select from_unixtime(ts,'YYYY-MM-dd') as `ts` from mr")

请查看Spark 1.5.2 API文档以获取更多信息。


3
您还可以导入org.apache.spark.sql.functions._来在函数调用中使用这些函数。例如:df.select(from_unixtime($"ts_col"/1000,"yyyy-MM-dd")).toDF("event_date").groupBy("event_date").count - panther
10
问题是当前时区将被用于转换,而不是UTC。 - Oleg
3
嗨@Oleg,我是这样解决UTC问题的:to_utc_timestamp(from_unixtime($"buyOrdrEntryTime"/1000,"yyyy-MM-dd hh:mm:ss"),"Europe/Berlin").as("buyOrdrEntryTime")。以这种方式指定时区非常重要,以避免夏令时问题。希望这有所帮助。 - Playing With BI
如果时间戳不是在柏林时区生成的话,@Playing With BI就不是UTC。 如果您的数据是UTC并且想确保它被视为UTC,则可以指定Europe/London。 - ZettaP

18
import org.joda.time.{DateTime, DateTimeZone}
import org.joda.time.format.DateTimeFormat

您需要导入以下库。

val stri = new DateTime(timeInMillisec).toString("yyyy/MM/dd")

或者根据您的情况进行调整:

 val time_col = sqlContext.sql("select ts from mr")
                     .map(line => new DateTime(line(0).toInt).toString("yyyy/MM/dd"))

还有另一种方式:

  import com.github.nscala_time.time.Imports._
  
  val date = (new DateTime() + ((threshold.toDouble)/1000).toInt.seconds )
             .toString("yyyy/MM/dd")

希望这能帮到你 :)

7

使用nscala_time库的toDataTime方法时不需要将其转换为字符串

import com.github.nscala_time.time.Imports._

scala> 1435655706000L.toDateTime
res4: org.joda.time.DateTime = 2015-06-30T09:15:06.000Z

`


如果您不喜欢隐藏的隐式参数,只需导入com.github.nscala_time.time.Imports.richLong即可。 - sauerburger

5

我使用 joda-time 库解决了这个问题,通过映射到 DataFrame 并将 DateTime 转换为字符串 :

import org.joda.time._
val time_col = sqlContext.sql("select ts from mr")
                         .map(line => new DateTime(line(0)).toString("yyyy-MM-dd"))

5
您可以在Java中使用以下语法。
input.select("timestamp)
            .withColumn("date", date_format(col("timestamp").$div(1000).cast(DataTypes.TimestampType), "yyyyMMdd").cast(DataTypes.IntegerType))

3
你可以做的事情有:

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

在这里,time是一个新的列名称,COL_WITH_UNIX_TIME是你想要转换的列的名称。这将使你的数据更加准确,以毫秒为单位给出数据,例如: "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接