scala 如何在Spark Dataset中存储日期而不会误解

inkz8wg9  于 5个月前  发布在  Scala
关注(0)|答案(1)|浏览(61)

Java 8 java.time.LocalDate允许你用YearMonthDayOfMonth来定义Dates,而不需要时区。它没有底层的Long表示,而是用YearMonthDayOfMonth。这在逻辑上是有意义的,因为当存储Date时,您不希望查看器根据时区将其解释为不同的日期。
然而,java.sql.DateLong表示的“瘦 Package 器”,这是spark中唯一支持的Date类型
因此,我的问题是,如何确保当您将Date存储在Spark Dataset中并将其序列化到磁盘(即)parquet文件时,它会被读取并解释为正确的日期,而不会传递时区信息?
范例:
我可以在英格兰(GMT+0)解析一个字符串"2016-01-01 02:00"。我实际上想存储的只是一个日/月/year.但由于它是java.sql.Date,它存储的是基础unixtime at 2AM.然后我将其序列化,美国东海岸的某个人拿起它并繁荣.它现在是"2016-12-31 21:00".然而,如果我知道时区,我会知道它实际上是"2016-01-01 02:00"如果java.sql.Date是无时区的,只使用UTC,我可以理解,但它使用LocalTimeZone来解释。
因此,如何存储一个不会被错误解释的DateTime,因为java.sql.Date存储了unix,然后使用LocalTimeZone来解释Date

ws51t4hk

ws51t4hk1#

java.sql.Date不携带时区信息,这可以从documentation中的主构造函数签名中看到。
当时间戳存储在没有时区信息的地方时,您需要以某种方式将此信息传递到带外。最安全的选择是将其存储为UTC时间,因为Unix epoch是一个长期存在的约定,可以很容易地与许多系统兼容。
由于Spark已经公开了处理java.sql.Date s和java.sql.Timestamp s的工具,我建议你坚持使用这些工具(也可以利用org.spark.sql.functions中预定义的函数)。
不幸的是,没有办法防止错误的客户端使用错误的解释来验证值。您可以将时区信息作为第二列的一部分传递,但没有什么可以阻止用户仅使用存储在第一列中的值并假设它是本地日期(无论“本地”在运行时上下文中的含义是什么)。

相关问题