【问题标题】:RDBMS timestamp to Hive timestamp timezone mismatchRDBMS 时间戳与 Hive 时间戳时区不匹配
【发布时间】:2016-01-17 23:57:15
【问题描述】:

如果我查询 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)?

最佳做法是什么?

【问题讨论】:

  • 过去的时间戳应始终存储为 UTC。例外情况是,如果您还需要需要关联当地时间,则将当地时间存储在单独的字段中,或者在平台支持时使用datetimeoffset。 (未来是完全不同的事情。)这是最佳实践,链接为重复。
  • 感谢您的信息。您有任何与 Hive 相关的附加组件/最佳实践吗?
  • 重新打开以添加 Hive 的详细信息。 (最初标记为Daylight saving time and time zone best practices的dup)

标签: database date hadoop timezone hive


【解决方案1】:

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

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

你问为什么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 作为时区传递,在值转换中基本上什么都不做。很可能您仍然会遇到同样的问题,特别是如果问题出在接收端。恕我直言,我认为您不应该使用它。

【讨论】:

  • 如果您能提供有关如何接收导出值的更多详细信息,我或许可以提供更多信息。
猜你喜欢
  • 2016-02-06
  • 1970-01-01
  • 1970-01-01
  • 2021-02-26
  • 2015-04-02
  • 2015-01-28
  • 2013-11-27
  • 1970-01-01
相关资源
最近更新 更多