[英]Spark date format issue
我在火花日期格式中觀察到了奇怪的行為。 實際上我需要將日期yy
轉換為yyyy
。 日期轉換后,日期應該是 20yy
我嘗試過如下,它在 2040 年后失敗了。
import org.apache.spark.sql.functions._
val df= Seq(("06/03/35"),("07/24/40"), ("11/15/43"), ("12/15/12"), ("11/15/20"), ("12/12/22")).toDF("Date")
df.withColumn("newdate", from_unixtime(unix_timestamp($"Date", "mm/dd/yy"), "mm/dd/yyyy")).show
+--------+----------+
| Date| newdate|
+--------+----------+
| 06/3/35|06/03/2035|
|07/24/40|07/24/2040|
|11/15/43|11/15/1943| // Here year appended with 19
|12/15/12|12/15/2012|
|11/15/20|11/15/2020|
|12/12/22|12/12/2022|
+--------+----------+
為什么這種行為,是否有任何日期實用程序可以直接使用而無需將 20 附加到字符串日期
解析 2 位年份字符串需要遵循SimpleDateFormat
文檔中記錄的一些相關解釋:
為了使用縮寫年份模式(“y”或“yy”)進行解析,SimpleDateFormat 必須解釋相對於某個世紀的縮寫年份。 它通過將日期調整為在創建 SimpleDateFormat 實例之前 80 年和之后 20 年內實現這一點。 例如,使用模式“MM/dd/yy”和創建於 1997 年 1 月 1 日的 SimpleDateFormat 實例,字符串“01/11/12”將被解釋為 2012 年 1 月 11 日,而字符串“05/04/ 64" 將被解釋為 1964 年 5 月 4 日。
因此,距2043
還有 20 多年,解析器使用記錄的 1943 年。
這是一種使用 UDF 的方法,該方法在解析日期之前顯式調用SimpleDateFormat
對象上的set2DigitYearStart
(我選擇 1980 年為例):
def parseDate(date: String, pattern: String): Date = {
val format = new SimpleDateFormat(pattern);
val cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 1980)
val beginning = cal.getTime();
format.set2DigitYearStart(beginning)
return new Date(format.parse(date).getTime);
}
進而:
val custom_to_date = udf(parseDate _);
df.withColumn("newdate", custom_to_date($"Date", lit("mm/dd/yy"))).show(false)
+--------+----------+
|Date |newdate |
+--------+----------+
|06/03/35|2035-01-03|
|07/24/40|2040-01-24|
|11/15/43|2043-01-15|
|12/15/12|2012-01-15|
|11/15/20|2020-01-15|
|12/12/22|2022-01-12|
+--------+----------+
了解您的數據后,您就會知道為set2DigitYearStart()
的參數選擇哪個值
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.