RDBMS 时间戳与 Hive 时间戳时区不匹配

RDBMS timestamp to Hive timestamp timezone mismatch

如果我查询 RDBMS 以获取我收到的时间戳:2015-03-30 00:00:00 在我将它作为 bigint 列导出到 Hive table 后,我得到 1427673600000 (cast(ts as timestamp) gives 2015-03-30 02:00:00) 。即当前本地时区(带夏令时)已应用于时间戳。

如果我想与数据库中的内容保持一致,如何将导出的时间戳存储在 Hive 中?我是否需要始终将时间戳存储为 Hive 中的 UTC 格式,所以在这种情况下,我需要从我得到的时间中减去 2 小时 然后我必须在查询期间应用当前时区(使用 from_utc_timestamp)?
我如何考虑夏令时(GMT+1 和 GMT+2)?

最佳做法是什么?

Hive 从 Unix 纪元开始以毫秒为单位存储时间戳。 Hive docs on timestamps 实际上是错误的 "timezoneless",因为根据 UTC 的定义 ,Unix 纪元是

您提供的时间戳 (1427673600000) 确实对应 2015-03-30 00:00:00 UTC。如果这是您打算存储的即时时间,那么您的操作是正确的。如果实际上你打算只存储一个日历日期(指的是 整个 日期,而不是那个日期的午夜 UTC),那么你可能应该使用 DATE 类型, 仅存储 2015-03-30.

你问为什么 cast(ts as timestamp) 给出 2015-03-30 02:00:00。这里可能发生的事情是,时间被 exported 使用原始时间戳,但是当您 receive 它时,它被加载到一个类型中向您显示等效的本地时间。

例如,java.util.Date 可能会发生这种情况。您应该能够使用 java.util.Calendar 或 Joda-Time,或新的 Java 8 java.time 类 来获取此值并进行不同的解释。如果您不使用 Java,那么类似的方法可能仍然适用。关键是,您可能正确使用了 Hive,但是在您查看结果时引入了本地时区。

Do I need to always store timestamps as UTC format in Hive ...

是的,这是最佳做法,而且您已经在这样做了。

... so in this case I need to subtract 2 hours from what I got ...

不,您永远不应该从时间戳中手动添加或减去时间。这样做会使您处于完全不同的时间点。

... and then I have to apply the current timezone during querying (using from_utc_timestamp) ?

我对 Hive 不是很熟悉。查看 the docs for from_utc_timestamp,这似乎期望输入已经在时间戳中,但他们显示了一个使用字符串的示例。也许它也需要一个整数,但是你只需将 UTC 作为时区传递,实际上在值转换中什么都不做。您可能仍然会遇到同样的问题,尤其是当问题出在接收端时。恕我直言,我认为您不必使用它。