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

时间:2015-10-19 15:01:51

标签: database date hadoop timezone hive

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

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

最佳做法是什么?

1 个答案:

答案 0 :(得分:1)

Hive存储自Unix纪元以来的时间戳(以毫秒为单位)。 Hive docs on timestamps实际上是错误的,因为它是“无时区的”,因为Unix Epoch在UTC中按照定义是

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

你问为什么cast(ts as timestamp)给出2015-03-30 02:00:00。这里可能发生的是,时间是导出和原始时间戳,但当你接收时,它会被加载到一个显示当地时间的类型中等效。

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

  

我是否需要始终在Hive中将时间戳存储为UTC格式...

是的,这是最好的做法,而这正是你所做的。

  

...所以在这种情况下,我需要从我得到的东西中减去2小时......

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

  

...然后我必须在查询期间应用当前时区(使用from_utc_timestamp)?

我对Hive并不完全熟悉。看看the docs for from_utc_timestamp,看起来这要求输入已经在时间戳中,但它们显示了一个使用字符串的示例。也许它也需要一个整数,但是你只需要传递UTC作为时区,在值转换中基本上什么都不做。您可能仍会遇到相同的问题,尤其是问题出在接收端时。恕我直言,我认为你不应该使用它。