如果我查询RDBMS以获取我收到的时间戳:2015-03-30 00:00:00
在我将其作为bigint列导出到Hive表后,我得到1427673600000
(cast(ts as timestamp) gives 2015-03-30 02:00:00
)。即当前的本地时区(夏令时)已应用于时间戳。
如果我希望与数据库中的内容保持一致,如何在Hive中存储导出的时间戳?我是否需要始终在Hive中将时间戳存储为UTC格式,因此在这种情况下我需要从我得到的内容中减去2小时
然后我必须在查询期间应用当前时区(使用from_utc_timestamp
)?
我如何考虑夏令时(GMT + 1和GMT + 2)?
最佳做法是什么?
答案 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
作为时区,在值转换中基本上什么都不做。您可能仍会遇到相同的问题,尤其是问题出在接收端时。恕我直言,我认为你不应该使用它。