2016-03-03 52 views
4

使用階2.10.4和火花1.5.1和火花1.6火花SQL不轉換時區正確

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) 

火花提交選項: --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」小時

回答

4

讀了一段時間後,以下是結論:

  • 星火-SQL不支持日期,時間,和時區也
  • 使用時間戳唯一的解決辦法
  • from_unixtime(at)正確地分析了劃時代的時間,只是將它打印爲字符串會因時區而改變它。假設from_unixtime可以正確轉換它(儘管打印它可能會顯示不同的結果)是安全的
  • from_utc_timestamp將會將時間戳移位(不僅僅是轉換)到該時區,在這種情況下,它會將時間減去8小時(-08:00)
  • 打印SQL結果爲:時代弄亂到時區PARAM
+1

from_unixtime(at)做什麼from_utc_timestamp也會做,它會解析一個Unix時間戳整數(自1970-01-01午夜以來的秒數),並將從UTC解析的時間轉換爲系統的默認時區。 – user180940

1

爲了記錄在案,這裏我們把這樣的使用UDF長值。

爲了我們的目的,我們(因爲在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)) 
}) 

這種方式感興趣的只是時間戳的日期字符串表示,我們控制瞭解析,以及日期的渲染。