Spark 在 RDD 中使用时间戳

Spark using timestamp inside a RDD

我正在尝试比较地图中的时间戳,但 Spark 似乎使用了不同的时区或其他非常奇怪的时区。 我读取了如下所示的虚拟 csv 文件来构建输入数据框:

"ts"
"1970-01-01 00:00:00"
"1970-01-01 00:00:00"
df.show(2)
+-------------------+
|        ts         |
+-------------------+
|1970-01-01 00:00:00|
|1970-01-01 00:00:00|
+-------------------+

目前,没有什么可报告的,但是:

df.rdd.map { row =>
  val timestamp = row.getTimestamp(0)
  val timestampMilli = timestamp.toInstant.toEpochMilli
  val epoch = Timestamp.from(Instant.EPOCH)
  val epochMilli = epoch.toInstant.toEpochMilli
  (timestamp, timestampMilli, epoch, epochMilli)
}.foreach(println)
(1970-01-01 00:00:00.0,-3600000,1970-01-01 01:00:00.0,0)
(1970-01-01 00:00:00.0,-3600000,1970-01-01 01:00:00.0,0)

我不明白为什么两个时间戳都不是 1970-01-01 00:00:00.0, 0。有人知道我错过了什么吗?

注意:我已经 ,使用了以下属性。

spark.sql.session.timeZone=UTC
user.timezone=UTC

java.sql.Timestamp class 继承自 java.util.Date。它们都具有存储 UTC-based 数字时间戳,但显示 本地时区时间的行为。您会在 Java 中使用 .toString() 看到它,这与您在给定代码中使用 println 看到的相同。

我相信您的 OS(或环境)设置类似于 Europe/London。请记住,在 Unix 时代 (1970-01-01T00:00:00Z),London was on BST (UTC+1).

您的 timestampMilli 变量显示 -3600000 因为它将您在本地时间的输入解释为 1970-01-01T00:00:00+01:00,这等同于 1969-12-31T23:00:00Z.

您的 epoch 变量显示 1970-01-01 01:00:00.0 因为 0 等同于 1970-01-01T00:00:00Z,后者等同于 1970-01-01T01:00:00+01:00.

另请参阅:

  • Is java.sql.Timestamp timezone specific?

我确实看到您注意到您将会话时区设置为 UTC,这在理论上应该有效。但很明显,结果表明它没有使用它。抱歉,我对 Spark 的了解还不够多,无法告诉您原因。但我会专注于问题的那一部分。