在pyspark中将Unix(纪元)时间更改为本地时间

new*_*eaf 3 timezone epoch apache-spark apache-spark-sql pyspark

我在 Spark 中有一个数据帧,其中包含 Unix(Epoch) 时间和时区名称。我希望根据不同的tz名称将epochtime转换为当地时间。我的数据如下所示:

data = [
    (1420088400, 'America/New_York'),
    (1420088400, 'America/Los_Angeles'),
    (1510401180, 'America/New_York'),
    (1510401180, 'America/Los_Angeles')]

df = spark.createDataFrame(data, ["epoch_time", "tz_name"])

df.createOrReplaceTempView("df")
df1 = spark.sql("""select *, from_unixtime(epoch_time) as gmt_time,"
               from_utc_timestamp(from_unixtime(epoch_time), tz_name) as local_time"
               from df""")
df1.show(truncate= False)
Run Code Online (Sandbox Code Playgroud)

结果如下:

+----------+-------------------+-------------------+---------------------+
|epoch_time|tz_name            |gmt_time           |local_time           |
+----------+-------------------+-------------------+---------------------+
|1420088400|America/New_York   |2015-01-01 05:00:00|2015-01-01 00:00:00.0|
|1420088400|America/Los_Angeles|2015-01-01 05:00:00|2014-12-31 21:00:00.0|
|1510401180|America/New_York   |2017-11-11 11:53:00|2017-11-11 06:53:00.0|
|1510401180|America/Los_Angeles|2017-11-11 11:53:00|2017-11-11 03:53:00.0|
+----------+-------------------+-------------------+---------------------+
Run Code Online (Sandbox Code Playgroud)
  1. 我不太确定这种转移是否正确,但夏令时似乎已经得到考虑。
  2. 我是否应该首先使用 from_unixtime 将 epochtime 更改为时间字符串,然后使用 to_utc_timestamp 将其更改为 utc 时间戳,最后使用 tz_name 将此 UTC 时间戳更改为本地时间?尝试了这个但出现错误

    df2 = spark.sql("""select *, from_unixtime(epoch_time) as gmt_time,
                       from_utc_timestamp(from_unixtime(epoch_time), tz_name) as local_time,
                       from_utc_timestamp(to_utc_timestamp(from_unixtime(epoch_time),from_unixtime(unix_timestamp(), 'z')), tz_name) as newtime from df""")
    
    Run Code Online (Sandbox Code Playgroud)
  3. 如何检查我的 EMR 服务器时区?

  4. 尝试使用,这是服务器时区吗?

    spark.sql("select from_unixtime(unix_timestamp(), 'z')").show()
    
    Run Code Online (Sandbox Code Playgroud)

    这给了我:

    +--------------------------------------------------------------------------+
    |from_unixtime(unix_timestamp(current_timestamp(), yyyy-MM-dd HH:mm:ss), z)|
     +--------------------------------------------------------------------------+
    |                                                                       UTC|
    +--------------------------------------------------------------------------+
    
    Run Code Online (Sandbox Code Playgroud)

感谢您的澄清。

Sil*_*vio 5

当您调用时,from_unixtime它将根据 Java 运行时的时区格式化日期,因为它只是使用SimpleDateFormat here的默认时区。在你的情况下,它是 UTC。因此,当您将值转换为本地时间时,您只需要调用from_utc_timestamp传入tz_name的值。但是,如果您要更改系统时区,则需要to_utc_timestamp先调用。

Spark 2.2 引入了时区设置,因此您可以像这样设置 SparkSession 的时区

spark.conf.set("spark.sql.session.timeZone", "GMT")
Run Code Online (Sandbox Code Playgroud)

在这种情况下,时间函数将使用GMT您的系统时区,请参阅此处的源代码