Pyspark中的TimeStampType与datetime tzaware对象

时间:2018-02-12 12:20:18

标签: python datetime pyspark

我在Pyspark中有以下问题我无法完全理解。我有以下日期时间对象

utc_now = datetime.now().replace(tzinfo=tz.tzutc())
utc_now # datetime.datetime(2018, 2, 12, 13, 9, 52, 785007, tzinfo=tzutc())

我创建了一个Spark DataFrame

data_df = spark.createDataFrame([Row(date=utc_now)])

当我尝试显示数据框

data_df.show(10, False)

包含数据的列在当地时间2小时前

>>> data_df.show(10, False)
+--------------------------+
|date                      |
+--------------------------+
|2018-02-12 15:09:52.785007|
+--------------------------+

并且收集数据已经在datetime对象中移动了两个小时前的时间

>>> data_df.collect()
[Row(date=datetime.datetime(2018, 2, 12, 15, 9, 52, 785007))]

区域信息也会被删除。在转换为TimestampType时,是否可以更改此行为?

1 个答案:

答案 0 :(得分:1)

pyspark中的

TimestampType与Pandas不同,而是通过long int并根据您机器的本地时区显示它们(默认情况下)。

话虽如此,您可以使用'spark.sql.session.timeZone'

更改您的火花会话时区
from datetime import datetime
from dateutil import tz
from pyspark.sql import Row

utc_now = datetime.now().replace(tzinfo=tz.tzutc())
print(utc_now)

spark.conf.set('spark.sql.session.timeZone', 'Europe/Paris')
data_df = spark.createDataFrame([Row(date=utc_now)])
data_df.show(10, False)
print(data_df.collect())

    2018-02-12 20:41:16.270386+00:00
    +--------------------------+
    |date                      |
    +--------------------------+
    |2018-02-12 21:41:16.270386|
    +--------------------------+

    [Row(date=datetime.datetime(2018, 2, 12, 21, 41, 16, 270386))]


spark.conf.set('spark.sql.session.timeZone', 'UTC')
data_df2 = spark.createDataFrame([Row(date=utc_now)])
data_df2.show(10, False)
print(data_df2.collect())

    +--------------------------+
    |date                      |
    +--------------------------+
    |2018-02-12 20:41:16.270386|
    +--------------------------+

    [Row(date=datetime.datetime(2018, 2, 12, 21, 41, 16, 270386))]

正如您所看到的,Spark认为它是UTC,但在本地时区服务,因为Python仍有时区' Europe / Paris'

import os, time
os.environ['TZ'] = 'UTC'
time.tzset()
utc_now = datetime.now()
spark.conf.set('spark.sql.session.timeZone', 'UTC')
data_df2 = spark.createDataFrame([Row(date=utc_now)])
data_df2.show(10, False)
print(data_df2.collect())

    +--------------------------+
    |date                      |
    +--------------------------+
    |2018-02-12 20:41:16.807757|
    +--------------------------+

    [Row(date=datetime.datetime(2018, 2, 12, 20, 41, 16, 807757))]

此外,pyspark.sql.module为您提供了两个函数,用于将时间戳对象转换为对应于同一时刻(from_utc_timesampto_utc_timestamp)的另一个时间戳对象。虽然我不认为你想改变你的约会时间。