【问题标题】:Spark SQL is not converting timezone correctly [duplicate]Spark SQL 未正确转换时区 [重复]
【发布时间】:2019-01-14 01:07:48
【问题描述】:

使用 Scala 2.10.4 和 spark 1.5.1 和 spark 1.6

sqlContext.sql(
  """
    |select id,
    |to_date(from_utc_timestamp(from_unixtime(at), 'US/Pacific')),
    |from_utc_timestamp(from_unixtime(at), 'US/Pacific'),
    |from_unixtime(at),
    |to_date(from_unixtime(at)),
    | at
    |from events
    | limit 100
  """.stripMargin).collect().foreach(println)

Spark-提交选项: --driver-java-options '-Duser.timezone=US/Pacific'

结果:

[56d2a9573bc4b5c38453eae7,2016-02-28,2016-02-27 16:01:27.0,2016-02-28 08:01:27,2016-02-28,1456646487]
[56d2aa1bfd2460183a571762,2016-02-28,2016-02-27 16:04:43.0,2016-02-28 08:04:43,2016-02-28,1456646683]
[56d2aaa9eb63bbb63456d5b5,2016-02-28,2016-02-27 16:07:05.0,2016-02-28 08:07:05,2016-02-28,1456646825]
[56d2aab15a21fa5f4c4f42a7,2016-02-28,2016-02-27 16:07:13.0,2016-02-28 08:07:13,2016-02-28,1456646833]
[56d2aac8aeeee48b74531af0,2016-02-28,2016-02-27 16:07:36.0,2016-02-28 08:07:36,2016-02-28,1456646856]
[56d2ab1d87fd3f4f72567788,2016-02-28,2016-02-27 16:09:01.0,2016-02-28 08:09:01,2016-02-28,1456646941]

美国/太平洋的时间应该是2016-02-28 00:01:27 等,但它如何减去两次“8”小时

【问题讨论】:

    标签: scala apache-spark hive timezone


    【解决方案1】:

    阅读一段时间后得出以下结论:

    • Spark-Sql 不支持日期时间,也不支持时区
    • 使用时间戳是唯一的解决方案
    • from_unixtime(at) 正确解析纪元时间,只是将其打印为字符串会因时区而改变它。可以安全地假设 from_unixtime 将正确转换它(尽管打印它可能会显示不同的结果)
    • from_utc_timestamp 会将时间戳转换(不仅仅是转换)到该时区,在这种情况下,它将从 (-08:00) 开始的时间减去 8 小时
    • 打印 sql 结果会弄乱时区参数的时间

    【讨论】:

    • from_unixtime(at) 和 from_utc_timestamp 一样,它将解析一个 Unix 时间戳整数(自 1970-01-01 午夜以来的秒数),并将从 UTC 解析的时间转换为系统的默认时区。
    • 这似乎已在Spark 2.3.2 中解决,请阅读this
    【解决方案2】:

    为了记录,这里我们使用 UDF 转换 Long 值。

    出于我们的目的,我们只对时间戳的日期字符串表示感兴趣(以 UTC 纪元以来的毫秒数为单位)

    val udfToDateUTC = udf((epochMilliUTC: Long) => {
      val dateFormatter = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(java.time.ZoneId.of("UTC"))
      dateFormatter.format(java.time.Instant.ofEpochMilli(epochMilliUTC))
    })
    

    这样,我们可以控制日期的解析和呈现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-20
      • 2012-10-31
      • 1970-01-01
      • 2019-08-19
      • 2017-10-01
      • 2017-02-27
      • 2017-06-20
      相关资源
      最近更新 更多