Pyspark to_timestamp с часовым поясом

#python-3.x #pyspark #apache-spark-sql

#python-3.x #pyspark #apache-spark-sql

Вопрос:

Я пытаюсь преобразовать строки даты и времени с часовым поясом в метку времени, используя to_timestamp.

Пример фрейма данных:

 df = spark.createDataFrame([("a", '2020-09-08 14:00:00.917 02:00'), 
                            ("b", '2020-09-08 14:00:00.900 01:00')], 
                           ["Col1", "date_time"])
  

Моя попытка (со спецификатором часового пояса Z):

 df = df.withColumn("timestamp",f.to_timestamp(df.date_time, "yyyy-MM-dd HH:mm:ss.SSSZ"))
df.select('timestamp').show()
  

Фактический результат:

      --------- 
    |timestamp|
     --------- 
    |     null|
    |     null|
     --------- 
  

Требуемый результат (где временная метка имеет тип timestamp):

  ------------------------- 
|                timestamp|
 ------------------------- 
|2020-09-08 14:00:00 02:00|
|2020-09-08 14:00:00 01:00|
 ------------------------- 
  

Я также перепробовал много других версий format, но, похоже, не могу найти подходящую.

Ответ №1:

Насколько я знаю, невозможно проанализировать временную метку с помощью часового пояса и сохранить ее первоначальную форму напрямую.

Проблема в том, что to_timestamp() amp; date_format() функции автоматически преобразуют их в часовой пояс локального компьютера.

Я могу предложить вам проанализировать временные метки и преобразовать их в UTC следующим образом,

 df.withColumn('local_ts', date_format(df.date_time, "yyyy-MM-dd HH:mm:ss.SSSX")) 
  .withColumn("timestamp_utc",to_utc_timestamp(to_timestamp(df.date_time, "yyyy-MM-dd HH:mm:ss.SSSX"), 'America/New_York')) 
  .show(10, False) 

# America/New_York is machine's timezone

 ---- ----------------------------- -------------------------- ----------------------- 
|Col1|date_time                    |local_ts                  |timestamp_utc          |
 ---- ----------------------------- -------------------------- ----------------------- 
|a   |2020-09-08 14:00:00.917 02:00|2020-09-08 08:00:00.917-04|2020-09-08 12:00:00.917|
|b   |2020-09-08 14:00:00.900 01:00|2020-09-08 09:00:00.900-04|2020-09-08 13:00:00.9  |
 ---- ----------------------------- -------------------------- ----------------------- 
  

Если вы все еще предпочитаете сохранять в исходном виде, то, я думаю, вы предполагаете написать пользовательский udf для этого.