日期和時間戳

重要的

這個文檔已經退休了,可能不會被更新。產品、服務或技術中提到的這些內容不再支持。看到Datetime模式

日期時間戳7.0數據類型在磚運行時的顯著改變。本文描述了:

  • 日期類型和相關的日曆。

  • 時間戳類型,以及它如何與時區。這也解釋了時區偏移決議的細節和微妙的行為變化的新的時間API在Java 8中,由磚7.0運行時使用。

  • api來構建日期和時間戳值。

  • 常見的陷阱和最佳實踐收集日期和時間戳上的對象Apache火花司機。

日期和日曆

一個日期結合了年、月、日,像(年= 2012,月= 12天= 31)。然而,的值年、月和日領域約束以確保日期值在現實世界中是一個有效的日期。例如,的值必須從1到12個月,一天的價值,必須從1到28日,29日,30日,或31(取決於年和月),等等。的日期不考慮時區類型。

日曆

限製日期字段定義的許多可能的日曆。有些人,像陰曆使用僅在特定區域。有些人,像公曆曆史上,隻使用。是事實上的國際標準公曆這是世界上幾乎所有用於民事用途。這是在1582年推出,並擴展到支持日期在1582年之前。這個擴展的日曆被稱為預期的公曆

磚7.0運行時使用預期的公曆,已經被用於其他數據係統的像熊貓,R, Apache箭頭。磚運行時的6。x和下麵結合朱利安和公曆的日期在1582年之前,使用公曆,1582年後使用公曆日期。這是繼承了遺產java.sql.DateAPI,它在Java 8所取代java.time.LocalDate,它使用預期的公曆。

時間戳和時區

時間戳類型擴展了日期與新字段類型:小時,分鍾,秒(小數部分),加上全球時區(會話作用域)。它定義了一個具體的時間。例如,(年= 2012,月= 12日天= 31小時= 23分鍾= 59歲,第二個= 59.123456)與會話時區UTC + 01:00。當編寫時間戳值非文本數據來源如拚花,隻是瞬間的值(比如在UTC時間戳)沒有時區信息。如果你寫和閱讀時間戳值有不同的會話時區,您可能會看到不同的值的小時,分鍾,和第二個字段,但是他們是相同的具體時間。

小時、分鍾和第二領域標準範圍:0-23小時0-59分鍾和秒。火花支持毫秒微秒級精度。分數的有效範圍從0到999999微秒。

在任何具體的時刻,根據時區,你可以觀察到許多不同的掛鍾值:

牆上的時鍾

相反,一個掛鍾值可以表示許多不同的時間瞬間。

時區偏移量允許您明確地將本地時間戳綁定到一個瞬間的時間。通常被定義為時區偏移補償在數小時內從格林威治標準時間(GMT)UTC + 0(協調世界時)。這個時區信息消除了歧義的代表,但它是不方便的。大多數人喜歡指出的位置等美國/ Los_AngelesorgydF4y2Ba歐洲/巴黎。這些額外的抽象級別從區補償使生活更輕鬆,但帶來的並發症。例如,您現在必須維持一個特殊時區數據庫時區名稱映射到補償。由於火花在JVM上運行,它代表映射到Java標準庫,它裝載的數據互聯網地址分配機構的數據庫時區(IANA TZDB)。此外,Java的標準庫中的映射機製有一些細微的差別,影響引發的行為。

自Java 8, JDK暴露不同的API操縱日期-時間和時區偏移分辨率和磚7.0運行時使用這個API。雖然補償時區名稱的映射具有相同的來源,IANA TZDB,實現不同的Java 8比Java 7以上。

例如,看一個時間戳在1883年之前美國/ Los_Angeles時區:1883-11-10就是。今年從別人的與眾不同之處在於11月18日,1883年,所有北美鐵路轉向了一種新標準時間係統。使用Java 7次API,您可以獲得一個時區偏移在本地時間戳喂飼:

java時間ZoneIdsystemDefault
res0:java時間ZoneId=美國/Los_Angeles
javasql時間戳返回對象的值(“1883-11-10”就是)。getTimezoneOffset/60.0
res1:=8.0

相當於Java 8 API返回不同的結果:

java時間ZoneId(“美國/ Los_Angeles”)。getRulesgetOffset(java時間LocalDateTime解析(“1883 - 11 - 10 - t00:00:00”))
:java時間ZoneOffset=- - - - - -07年:52:58

1883年11月18日之前,在北美時間是當地的物質,和大多數城市和城鎮使用某種形式的地方太陽時,由著名的鍾(例如在一座教堂的尖塔,或在一個珠寶商的窗口)。這就是為什麼你看到這樣一個奇怪的時區偏移量。

的例子演示了Java 8函數更精確,從IANA TZDB考慮曆史數據。切換到Java 8次API之後,磚自動運行時7.0受益於改進,變得更加精確的在如何解決時區偏移量。

磚運行時的7.0還轉向的預期的公曆時間戳類型。的ISO SQL: 2016標準聲明時間戳的有效範圍0001-01-01就是9999-12-3123:59:59.999999。磚7.0運行時完全符合標準和支持所有的時間戳在這個範圍。磚相比,運行時6。x和下麵,注意下麵的子區間:

  • 0001-01-01就是1582-10-03 . .23:59:59.999999。磚運行時的6。x和下麵使用公曆和不符合標準。磚7.0運行時的修複問題並應用等內部操作時間戳的預期的公曆一年,月,日,等。由於不同的日曆,在磚運行時存在的一些日期6。x和下麵不存在於磚7.0運行時。例如,1000不是一個有效的日期,因為1000-02-29不是一個公曆閏年。同時,磚運行時的6。x和下麵解決時區名稱為這個時間戳區補償錯誤範圍。

  • 1582-10-04就是1582-10-14 . .23:59:59.999999。這是一個有效的本地時間戳數據磚7.0運行時,與磚運行時的6。x和低於不存在這樣的時間戳。

  • 1582-10-15就是1899-12-31 . .23:59:59.999999。磚7.0運行時解決時區偏移量從IANA TZDB正確使用曆史數據。磚7.0運行時相比,磚運行時的6。x和下麵可能解決區域補償時區名稱錯誤在某些情況下,如前麵的示例所示。

  • 1900-01-01就是2036-12-31 . .23:59:59.999999。磚7.0運行時和磚運行時的6。x和下麵符合ANSI SQL標準和使用公曆日期-時間操作,如月的日子。

  • 2037-01-01就是9999-12-31 . .23:59:59.999999。磚運行時的6。x和下麵能解決時區偏移和夏令時抵消錯誤。磚運行時7.0不。

時區名稱映射到補償的一個方麵是重疊的本地時間戳,可以發生由於日光節約時間(DST)或切換到另一個標準時區偏移量。02:00:00例如,11月3日2019年,在美國大多數州將時鍾向後01:00:00 1小時。本地時間戳2019-11-0301:30:00美國/ Los_Angeles可以映射要麼2019-11-0301:30:00UTC-08:00orgydF4y2Ba2019-11-0301:30:00UTC-07:00。如果你不指定偏移量和設置時區名稱(例如,2019-11-0301:30:00美國/ Los_Angeles),磚7.0運行時將抵消早些時候,通常對應於“夏天”。從磚運行時行為發散6。x和下麵的“冬季”抵消。在缺口的情況下,時鍾向前跳,沒有有效的抵消。對於一個典型的小時的日光節約時間的變化,引發這樣的時間戳到下一個有效時間戳相應轉移到“夏季”的時間。

從前麵的例子可以看出,時區名稱映射到補償是模棱兩可的,並不是一個對一個。在當它是可能的,當構建時間戳我們建議指定確切的時區偏移量,例如2019-11-0301:30:00UTC-07:00

ANSI SQL和SQL時間戳火花

時間戳的ANSI SQL標準定義了兩種類型:

  • 時間戳沒有時間orgydF4y2Ba時間戳:當地時間戳(一年,,一天,小時,一分鍾,第二個)。這些時間戳不綁定到任何時區,掛鍾時間戳。

  • 時間戳時間:劃定的時間戳(一年,,一天,小時,一分鍾,第二個,TIMEZONE_HOUR,TIMEZONE_MINUTE)。這些時間戳代表即時在UTC時間區+時區偏移(小時和分鍾數)的價值。

的時區偏移時間戳時間不影響時間戳代表的物理時間點,因為這是完全由的UTC時間即時其他時間戳組件。相反,時區偏移隻影響一個時間戳值顯示的默認行為,提取日期/時間組件(例如,提取),需要知道時區的其他操作,如添加幾個月時間戳。

火花SQL類型定義了時間戳時間戳會話時間的,這是一個組合字段(一年,,一天,小時,一分鍾,第二個,會話TZ)一年通過第二個字段確定一個時間即時在UTC時間區,並在會話TZ來自SQL配置spark.sql.session.timeZone。會話時區可以設置為:

  • 區抵消(+ | -)HH: mm。這種形式允許您明確定義一個物理的時間點。

  • 時區名稱的形式區域ID區域/城市,如美國/ Los_Angeles。這種形式的時區信息遭受前麵描述的一些問題像重疊的本地時間戳。然而,明確每個UTC時間即時與一個時區抵消任何區域ID,因此,每個時間戳可以明確地區基於ID的時區轉換為時間戳與區域偏移量。默認情況下,會話時區設置為默認時區的Java虛擬機。

火花時間戳會話時間是不同的:

  • 時間戳沒有時間,因為這種類型的值可以映射到多個物理時間的瞬間,但是任何的價值時間戳會話時間即時是一個具體的物理時間。SQL類型可以通過使用一個模擬固定在所有會話時區偏移,例如UTC + 0。在這種情況下,你可以考慮在UTC時間戳作為本地時間戳。

  • 時間戳時間,因為根據SQL標準列值的類型可以有不同的時區偏移量。,不支持SQL。

你應該注意時間戳與全球相關(會話作用域)時區不是新發明的火花SQL。rdbms如Oracle提供類似時間戳:時間戳當地的時間

建造日期和時間戳

火花SQL提供了一些方法來創建日期和時間戳值:

  • 默認構造函數沒有參數:CURRENT_TIMESTAMP ()當前日期()

  • 從其他原始火花SQL類型等INT,,字符串

  • 從外部類型像Python datetime或Java類java.time.LocalDate/即時

  • 反序列化數據來源如CSV, JSON, Avro,拚花,獸人等等。

這個函數MAKE_DATE介紹了磚需要三個參數- 7.0運行時一年,,一天——構造一個日期價值。所有輸入參數是隱式轉換成INT盡可能的類型。功能檢查結果預期的公曆日期是有效日期,否則它的回報。例如:

火花createDataFrame(((2020年,6,26),(1000年,2,29日),(- - - - - -44,1,1)]、[“Y”,“米”,' D '])createTempView(“YMD”)df=sql(“選擇make_date (Y, M, D)從YMD日期”)dfprintSchema()
|——日期:日期(可以為空=真正的)

打印DataFrame內容,調用顯示()行動,將日期轉換為字符串的執行者和轉移司機的字符串輸出到控製台:

df顯示()
+ - - - - - - - - - - - - +|日期|+ - - - - - - - - - - - - +|2020年- - - - - -06- - - - - -26|||| - - - - - -0044年- - - - - -01- - - - - -01|+ - - - - - - - - - - - - +

類似地,您可以構建使用時間戳值MAKE_TIMESTAMP功能。就像MAKE_DATE日期字段,它執行相同的驗證,另外接受時間字段(0-23)小時,分鍾(0-59)和第二(0-60)。第二個十進製類型(精密= 8,規模= 6)因為秒可以通過微秒級精度的小數部分。例如:

df=火花createDataFrame(((2020年,6,28,10,31日,30.123456),\(1582年,10,10,0,1,2.0001),(2019年,2,29日,9,29日,1.0)]、[“年”,“月”,“天”,“小時”,“一分鍾”,“第二”])df顯示()
+ - - - + - - - + - - - + - - - + - - - - - - - - - - - - - - - - - - + +|一年||一天|小時|一分鍾|第二個|+ - - - + - - - + - - - + - - - + - - - - - - - - - - - - - - - - - - + +|2020年|6|28|10|31日|30.123456||1582年|10|10|0|1|2.0001||2019年|2|29日|9|29日|1.0|+ - - - + - - - + - - - + - - - + - - - - - - - - - - - - - - - - - - + +
dfselectExpr(“make_timestamp(年,月,日,小時,分鍾,秒)make_timestamp”)tsprintSchema()
|——MAKE_TIMESTAMP:時間戳(可以為空=真正的)

至於日期,打印的內容ts DataFrame使用show()操作。以類似的方式,顯示()時間戳轉換為字符串但現在考慮會話時區配置定義的SQLspark.sql.session.timeZone

ts顯示(截斷=)
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - +|MAKE_TIMESTAMP|+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - +|2020年- - - - - -06- - - - - -2810:31日:30.123456||1582年- - - - - -10- - - - - -1000:01:02.0001|||+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - +

火花不能創建最後一個時間戳,因為這不是有效日期:2019年不是閏年。

您可能注意到,沒有時區信息在前麵的例子。在這種情況下,火花時區從SQL配置spark.sql.session.timeZone它適用於函數調用。你也可以選擇一個不同的時區通過它的最後一個參數MAKE_TIMESTAMP。這是一個例子:

df=火花createDataFrame(((2020年,6,28,10,31日,30.,UTC的),(1582年,10,10,0,1,2,“美國/ Los_Angeles”),\(2019年,2,28,9,29日,1,“歐洲/莫斯科”)),(“年”,“月”,“天”,“小時”,“一分鍾”,“第二”,' TZ '])df=dfselectExpr(“make_timestamp(年、月、日、小時、分鍾,第二,TZ) make_timestamp”)df=dfselectExpr(“date_format (MAKE_TIMESTAMP yyyy-MM-dd HH: mm: ss VV) TIMESTAMP_STRING”)df顯示(截斷=)
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +|TIMESTAMP_STRING|+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +|2020年- - - - - -06- - - - - -2813:31日:00歐洲/莫斯科||1582年- - - - - -10- - - - - -1010:24:00歐洲/莫斯科||2019年- - - - - -02- - - - - -2809年:29日:00歐洲/莫斯科|+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +

為例說明,火花考慮指定時區但調整所有本地時間戳會話時區。原來的時區傳遞到MAKE_TIMESTAMP丟失,因為函數時間戳會話時間假設所有值類型屬於一個時區,它甚至不存儲一個時區每值。根據的定義時間戳會話時間,引發當地商店在UTC時間戳時區,並使用會話時區而提取日期-時間字段或將時間戳轉換為字符串。

同時,時間戳可以由長類型使用。如果一個長列包含時代以來的秒數1970-01-01 00:00:00Z,可以把它轉換為火花SQL時間戳:

選擇(- - - - - -123456789作為時間戳);1966年- - - - - -02- - - - - -0205年:26:51

不幸的是,這種方法不允許您指定秒的小數部分。

另一種方法是構建日期和時間戳的值字符串類型。你可以讓文字使用特殊的關鍵詞:

選擇時間戳“2020-06-28 22:17:33.123456歐洲/阿姆斯特丹的,日期“2020-07-01”;2020年- - - - - -06- - - - - -2823:17:33123456年2020年- - - - - -07年- - - - - -01

或者,您可以使用鑄造,你可以申請一個列中所有的值:

選擇(“2020-06-28 22:17:33.123456歐洲/阿姆斯特丹的作為時間戳),(“2020-07-01”作為日期);2020年- - - - - -06- - - - - -2823:17:33123456年2020年- - - - - -07年- - - - - -01

輸入時間戳字符串解釋為本地時間戳在指定的時區或會話時區如果省略時區在輸入字符串。與不尋常的模式可以被轉換成字符串使用的時間戳to_timestamp ()函數。描述的支持模式Datetime模式格式化和解析:

選擇to_timestamp(“28/6/2020 22.17.33”,“dd / M / yyyy HH.mm.ss”);2020年- - - - - -06- - - - - -2822:17:33

如果你不指定一個模式,行為類似的函數

可用性,火花SQL識別特殊字符串值的所有方法接受一個字符串並返回一個時間戳或日期:

  • 時代是一個別名日期嗎1970-01-01或時間戳1970-01-0100:00:00Z

  • 現在是當前時間戳或會話時區的日期。在一個查詢中它總是產生同樣的結果。

  • 今天是當前日期的開始的嗎時間戳類型或隻是當前日期日期類型。

  • 明天是第二天的開始時間戳或隻是第二天嗎日期類型。

  • 昨天前一天是目前的一個或的開始時間戳類型。

例如:

選擇時間戳“昨天”,時間戳“今天”,時間戳“現在”,時間戳“明天”;2020年- - - - - -06- - - - - -2700:00:002020年- - - - - -06- - - - - -2800:00:002020年- - - - - -06- - - - - -2823:07年:07年182020年- - - - - -06- - - - - -29日00:00:00選擇日期“昨天”,日期“今天”,日期“現在”,日期“明天”;2020年- - - - - -06- - - - - -272020年- - - - - -06- - - - - -282020年- - - - - -06- - - - - -282020年- - - - - -06- - - - - -29日

引發允許您創建數據集從現有的外部對象的集合在司機身邊,創建相應的列類型。火花將外部類型的實例轉換為語義等價的內部表示。例如,要創建一個數據集日期時間戳列從Python集合,您可以使用:

進口datetimedf=火花createDataFrame(((datetimedatetime(2020年,7,1,0,0,0),datetime日期(2020年,7,1))),(“時間戳”,“日期”])df顯示()
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +|時間戳|日期|+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +|2020年- - - - - -07年- - - - - -0100:00:00|2020年- - - - - -07年- - - - - -01|+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +

PySpark Python的日期時間對象轉換為內部火花在驅動端使用SQL表示係統時區,可以引發不同的會話時區設置spark.sql.session.timeZone。內部價值不包含原始的時區信息。未來在並行操作日期和時間戳值隻考慮火花SQL會話時區顯示時間戳會話時間類型定義。

同樣,火花承認以下類型為外部日期時間類型在Java和Scala api:

  • java.sql.Datejava.time.LocalDate的外部類型日期類型

  • java.sql.Timestampjava.time.Instant時間戳類型。

是有區別的java.sql。*java.time。*類型。java.time.LocalDatejava.time.Instant添加Java 8中,類型是基於預期的相同格裏高裏曆日曆,磚使用運行時7.0及以上。java.sql.Datejava.sql.Timestamp有另一個日曆下麵混合日曆(Julian +公曆1582-10-15)以來,這是一樣的磚運行時使用的傳統日曆6。下麵的x和。由於不同的日曆係統,火花在轉換執行額外的操作內部引發SQL表示,從一個日曆和變基輸入日期/時間戳到另一個地方。現代時間戳的變基操作有一個小的開銷在1900年之後,它可以更重要的時間戳。

下麵的例子展示了如何利用Scala集合時間戳。第一個示例構造java.sql.Timestamp從一個字符串對象。的返回對象的值方法解釋輸入字符串作為本地時間戳在JVM默認時區,可以引發不同的會話時區。如果您需要構建的實例java.sql.TimestamporgydF4y2Bajava.sql.Date在特定的時區,看一看java.text.SimpleDateFormat(和它的方法setTimeZone)或java.util.Calendar

Seq(javasql時間戳返回對象的值(“2020-06-29 22:41:30”),javasql時間戳(0))。toDF(“t”)。顯示()
+ - - - - - - - - - - - - - - - - - - - +|ts|+ - - - - - - - - - - - - - - - - - - - +|2020年- - - - - -06- - - - - -29日22:41:30.||1970年- - - - - -01- - - - - -0103:00:00|+ - - - - - - - - - - - - - - - - - - - +
Seq(java時間即時ofEpochSecond(- - - - - -12219261484 l),java時間即時時代)。toDF(“t”)。顯示
+ - - - - - - - - - - - - - - - - - - - +|ts|+ - - - - - - - - - - - - - - - - - - - +|1582年- - - - - -10- - - - - -1511:12:13||1970年- - - - - -01- - - - - -0103:00:00|+ - - - - - - - - - - - - - - - - - - - +

同樣,你可以日期列的集合java.sql.DateorgydF4y2Bajava.sql.LocalDate。並行化的java.sql.LocalDate實例是完全獨立的火花的會話或JVM默認時區,但並行的是不一樣的java.sql.Date實例。有細微差別:

  1. java.sql.DateJVM實例代表當地日期默認時區的司機。

  2. 對於正確轉換引發SQL價值觀,JVM默認時區的司機和執行人必須相同。

Seq(java時間LocalDate(2020年,2,29日),java時間LocalDate現在)。toDF(“日期”)。顯示
+ - - - - - - - - - - - +|日期|+ - - - - - - - - - - - +|2020年- - - - - -02- - - - - -29日||2020年- - - - - -06- - - - - -29日|+ - - - - - - - - - - - +

為了避免任何日曆和時區相關問題,我們建議Java 8類型java.sql.LocalDate/即時並行化外部類型的Java / Scala集合的時間戳或日期。

收集日期和時間戳

反向操作的並行采集日期和時間戳從執行人回到司機並返回外部類型的集合。對於上麵的例子,可以把DataFrame回到司機使用收集()行動:

df收集()
((時間戳=datetimedatetime(2020年,7,1,0,0),日期=datetime日期(2020年,7,1)))

火花轉移內部的日期和時間戳列值隨著時間的瞬間在UTC時間區從執行者到司機,並執行轉換到Python datetime對象係統時區的司機,不使用SQL會話時區火花。收集()不同於顯示()行動前一節中描述。顯示()使用會話時區而將時間戳轉換為字符串,並收集了字符串的司機。

在Java和Scala api,火花執行以下默認轉換:

  • 火花SQL日期值轉換為實例java.sql.Date

  • 火花SQL時間戳值轉換為實例java.sql.Timestamp

這兩個轉換都表現在JVM默認時區的司機。通過這種方式,相同的日期-時間字段,你可以使用Date.getDay (),getHour ()等等,和使用火花SQL函數一天,小時JVM,默認時區的司機和會話時區執行者應該是相同的。

同樣的日期/時間戳java.sql.Date/時間戳,磚7.0運行時的執行重新從預期的公曆混合日曆(Julian +格雷戈裏)。這個操作是幾乎免費的現代日期(1582年之後)和時間戳(1900年之後),但它可能帶來一些開銷古老的日期和時間戳。

你可以避免這種calendar-related問題,問引發返回java.time類型,添加自Java 8。如果你設置SQL配置spark.sql.datetime.java8API.enabled真實的,Dataset.collect ()行動回報:

  • java.time.LocalDate對於火花SQL日期類型

  • java.time.Instant對於火花SQL時間戳類型

現在轉換不遭受calendar-related問題,因為Java 8類型和磚運行時的7.0及以上都是基於預期的公曆。的收集()行動並不取決於JVM默認時區。時間戳轉換不依賴於時區。日期轉換使用SQL的會話時區配置spark.sql.session.timeZone。例如,考慮一個數據集日期時間戳列,JVM使用默認時區設置歐洲/俄羅斯和會話時區設置美國/ Los_Angeles

java跑龍套時區getDefault
res1:java跑龍套時區=太陽跑龍套日曆ZoneInfo(id=“歐洲/莫斯科”,]
火花相依得到(“spark.sql.session.timeZone”)
:字符串=美國/Los_Angeles
df顯示
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +|時間戳|日期|+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +|2020年- - - - - -07年- - - - - -0100:00:00|2020年- - - - - -07年- - - - - -01|+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +

顯示()行動打印在會話時的時間戳美國/ Los_Angeles,但如果你收集數據集,它被轉換為java.sql.TimestamptoString方法打印歐洲/俄羅斯:

df收集()
res16:數組(orgapache火花sql]=數組([2020年- - - - - -07年- - - - - -0110:00:00.0,2020年- - - - - -07年- - - - - -01])
df收集()(0)。木屐(javasql時間戳)(0)。toString
res18:javasql時間戳=2020年- - - - - -07年- - - - - -0110:00:00.0

實際上,本地時間戳2020-07-01就是2020 - 07 - 01 t07:00:00z UTC。你可以觀察到,如果啟用了Java 8 API和收集數據集:

df收集()
res27:數組(orgapache火花sql]=數組([2020年- - - - - -07年- - - - - -01T07:00:00Z,2020年- - - - - -07年- - - - - -01])

你能將一個java.time.Instant反對任何本地時間戳獨立從全球JVM時區。這是一個的優點java.time.Instantjava.sql.Timestamp。前者需要改變全球JVM設置,影響其他時間戳在同一JVM。因此,如果您的應用程序進程日期或時間戳在不同的時區,和應用程序不應該互相衝突而收集數據驅動程序使用Java或ScalaDataset.collect ()API,我們建議切換到Java 8 API使用SQL配置spark.sql.datetime.java8API.enabled