获取带有时区偏移的日期

Posted

技术标签:

【中文标题】获取带有时区偏移的日期【英文标题】:Getting date with timezone offset 【发布时间】:2014-05-24 16:28:19 【问题描述】:

我正在尝试从 postgres 中的查询中提取日期。时间戳存储为 UTC,所以如果我有 2014 年 1 月 1 日 02:00:00,我希望太平洋时间的日期是 2013 年 12 月 31 日,而不是 2014 年 1 月 1 日。我真的很接近,但查询 2 和 3 仍然返回 1/1/2014。

SELECT '1-1-2014 02:00:00'::timestamp at time zone 'America/Los_Angeles';

返回

2014-01-01 02:00:00-08

-

SELECT CAST('1-1-2014 02:00:00'::timestamp at time zone 'America/Los_Angeles' AS Date);

返回

2014-01-01

但我希望它返回2013-12-31

SELECT CAST('1-1-2014 00:02:00'::timestamp at time zone 'America/Los_Angeles' AS Date) at time zone 'America/Los_Angeles';

返回

2014-01-01 00:00:00

但我希望它返回2013-12-31 00:00:00

我基本上想返回它所在时区的日期,在这种情况下是太平洋时区。

【问题讨论】:

【参考方案1】:

我想通了,使用间隔,我可以减去偏移量,然后得到日期。

SELECT '1-1-2014 02:00:00'::timestamp + INTERVAL '1 hour' * extract(timezone_hour FROM '1-1-2014 00:02:00'::timestamp at time zone 'America/Los_Angeles');

在这里添加答案,因为我确信这个问题可能是其他人想知道的。

【讨论】:

【参考方案2】:

如果是没有时区的时间戳,你需要先告诉它使用UTC时区,然后转换为另一个时区:

SELECT '1-1-2014 02:00:00'::timestamp at time zone 'UTC' at time zone 'America/Los_Angeles';
      timezone       
---------------------
 2013-12-31 18:00:00

【讨论】:

我会给你正确的答案。这比我的解决方案更简洁明了。谢谢!【参考方案3】:

如果'America/Los_Angeles' 是您当前的时区(timezone 当前会话的设置),那么只需告诉 Postgres timestamp 的时区。

SELECT ('2014-01-01 02:00:00'::timestamp AT TIME ZONE 'UTC')::date;

转换为date 是基于当前时区并根据需要自动工作。

如果当前时区可以是其他时区,则需要明确like @Clodoaldo demonstrates。

正确的解决方案是先存储一个timestamp with time zone (timestamptz),然后你可以直接转换为date

SELECT '2014-01-01 02:00:00+0'::timestamptz::date;

关于 Postgres 中的时间戳:

Ignoring time zones altogether in Rails and PostgreSQL

最近有更多细节的相关答案(也处理索引):

Optimize/Index Timezone Query

【讨论】:

以上是关于获取带有时区偏移的日期的主要内容,如果未能解决你的问题,请参考以下文章

使用 Joda-Time 获取给定日期和时区的 UTC 偏移量

.NET 通过时区名称获取时区偏移量

带有 pytz 时区的日期时间。不同的偏移量取决于 tzinfo 的设置方式[重复]

如何在 JavaScript 中使用 ISO 8601 格式化带有时区偏移的日期?

Javascript 日期对象未正确调整时区偏移

CookComputing XmlRpc客户端-如何获取带有时区的日期时间[重复]