【问题标题】:How to set timezone to UTC in Apache Spark?如何在 Apache Spark 中将时区设置为 UTC?
【发布时间】:2018-09-13 14:46:31
【问题描述】:

在 Spark 的 WebUI(端口 8080)和环境选项卡上,有以下设置:

user.timezone   Zulu

您知道如何/在哪里可以将其覆盖为 UTC 吗?

环境细节:

  • Spark 2.1.1
  • jre-1.8.0-openjdk.x86_64
  • 没有 jdk
  • EC2 亚马逊 Linux

编辑(有人回答以下然后删除): https://www.timeanddate.com/time/zones/z

【问题讨论】:

  • 因此,根据已删除答案中的链接,Zulu TZ 与 UTC 的偏移量为 0,这意味着对于大多数实际目的,您不需要更改。

标签: java apache-spark pyspark apache-spark-sql jvm


【解决方案1】:

现在你可以使用了:

spark.conf.set("spark.sql.session.timeZone", "UTC")

因为https://issues.apache.org/jira/browse/SPARK-18936 在 2.2.0

编辑:

另外,我将默认时区设置为 UTC 以避免隐式转换

TimeZone.setDefault(TimeZone.getTimeZone("UTC"))

否则,当您要转换的时间戳中不存在时区信息时,您将获得从默认时区到 UTC 的隐式转换

例子:

val rawJson = """ {"some_date_field": "2018-09-14 16:05:37"} """

val dsRaw = sparkJob.spark.createDataset(Seq(rawJson))

val output =
  dsRaw
    .select(
      from_json(
        col("value"),
        new StructType(
          Array(
            StructField("some_date_field", DataTypes.TimestampType)
          )
        )
      ).as("parsed")
    ).select("parsed.*")

如果我的默认时区是欧洲/都柏林,即 GMT+1,并且 Spark sql 会话时区设置为 UTC,Spark 将假定“2018-09-14 16:05:37”在欧洲/都柏林时区并执行一次转换(结果将是“2018-09-14 15:05:37”)

【讨论】:

    【解决方案2】:

    在某些情况下,您还需要设置 JVM 时区。例如,当将数据加载到 TimestampType 列时,它将解释本地 JVM 时区中的字符串。要设置 JVM 时区,您需要为驱动程序和执行程序添加额外的 JVM options

    spark = pyspark.sql.SparkSession \
        .Builder()\
        .appName('test') \
        .master('local') \
        .config('spark.driver.extraJavaOptions', '-Duser.timezone=GMT') \
        .config('spark.executor.extraJavaOptions', '-Duser.timezone=GMT') \
        .config('spark.sql.session.timeZone', 'UTC') \
        .getOrCreate()
    

    我们在本地单元测试环境中执行此操作,因为我们的本地时间不是 GMT。

    有用的参考: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

    【讨论】:

    • 喜欢这个答案有两个原因。 #1) 它在会话构建器而不是会话上设置配置。由于您执行的顺序,这对时区没有影响(所有 spark 代码在创建会话之后运行,通常在设置配置之前)。 #2)这是正确建议在 JVM 中设置用户时区的唯一答案以及这样做的原因!希望OP能接受这个答案:(
    【解决方案3】:

    如这些 SPARK 错误报告(linklink)中所述,最新的 SPARK 版本(撰写本文时为 3.0.0 和 2.4.6)不完全/正确支持为所有操作设置时区,尽管@Moemars 和@Daniel 给出了答案。

    我建议尽可能避免在 SPARK 中进行时间操作,要么在从 SPARK 中提取后自己执行它们,要么使用 this question 中使用的 UDF。

    【讨论】:

      【解决方案4】:

      您可以使用下面将时区设置为您想要的任何区域,并且您的笔记本或会话将为 current_time() 或 current_timestamp() 保留该值。

      %sql

      SET TIME ZONE 'America/Los_Angeles' -> 获取 PST

      SET TIME ZONE '美国/芝加哥'; -> 获取 CST

      最后一部分应该是一个城市,它不允许我尝试的所有城市。

      参考:https://spark.apache.org/docs/latest/sql-ref-syntax-aux-conf-mgmt-set-timezone.html

      【讨论】:

        【解决方案5】:

        更改您的系统时区并检查它,我希望它会工作

        【讨论】:

        • 这并不能真正解决问题。不能在所有使用的系统上更改 TZ。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-05-10
        • 1970-01-01
        • 2018-06-20
        • 1970-01-01
        • 2015-04-16
        • 1970-01-01
        • 2015-12-06
        相关资源
        最近更新 更多