PostgreSQL 中的时间戳操作 - 小时/时区问题
我需要对数据库执行一些日期时间操作,这要求所有创建的时间戳具有相同的年份。我尝试使用此查询:
select created,cast (created -
to_timestamp(''||date_part('year', created), 'YYYY') +
timestamp '2010-01-01' as timestamp without time zone)
from table where created is not null limit 10;
...但结果仅部分令人满意:
created | timestamp
---------------------+---------------------
2010-08-29 12:44:05 | 2010-08-29 11:44:05
2007-06-21 13:49:22 | 2010-06-21 12:49:22
2007-06-21 15:02:33 | 2010-06-21 14:02:33
2007-06-21 15:05:26 | 2010-06-21 14:05:26
1999-09-30 13:00:00 | 2010-09-30 12:00:00
1997-06-07 13:00:00 | 2010-06-07 12:00:00
2010-06-15 20:51:01 | 2010-06-15 19:51:01
2006-08-26 15:33:02 | 2010-08-26 14:33:02
2009-12-15 11:07:06 | 2010-12-15 11:07:06
1997-06-28 13:00:00 | 2010-06-28 12:00:00
(10 rows)
如您所见,与原始创建
值相比,所有时间戳均为-1小时。更奇怪的是,上一篇(2010-12-15 11:07:06
)之前的一篇却不是。
created
列是timestamp without time zone
类型。
知道我做错了什么吗?
I need to do some date-time operations on my database which require all created
timestamps to have the same year. I tried with this query:
select created,cast (created -
to_timestamp(''||date_part('year', created), 'YYYY') +
timestamp '2010-01-01' as timestamp without time zone)
from table where created is not null limit 10;
... but the result is only partially satisfying:
created | timestamp
---------------------+---------------------
2010-08-29 12:44:05 | 2010-08-29 11:44:05
2007-06-21 13:49:22 | 2010-06-21 12:49:22
2007-06-21 15:02:33 | 2010-06-21 14:02:33
2007-06-21 15:05:26 | 2010-06-21 14:05:26
1999-09-30 13:00:00 | 2010-09-30 12:00:00
1997-06-07 13:00:00 | 2010-06-07 12:00:00
2010-06-15 20:51:01 | 2010-06-15 19:51:01
2006-08-26 15:33:02 | 2010-08-26 14:33:02
2009-12-15 11:07:06 | 2010-12-15 11:07:06
1997-06-28 13:00:00 | 2010-06-28 12:00:00
(10 rows)
As you can see, all timestamps are -1 hour comparing to original created
values. What's even more strange is that the one before last one (2010-12-15 11:07:06
) is not.
created
column is timestamp without time zone
type.
Any idea what I did wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
SQL 的问题在于它不会将日期转换为另一年的日期。它计算创建的和 2010-01-01 的增量并将其转换为日期。所以你实际上并没有删除年份部分,而是计算它是多久之前的。
这是解决该问题的另一种方法。它只会替换年份,而日期的其余部分保持不变。
您也可以使用子字符串来执行此操作。
TO_TIMESTAMP()
会将日期 2010-02-29 转换为 2010-03-01,因此可以安全使用。The problem with your SQL is that it does not turn a date into a date in another year. It calculates deltas for created and 2010-01-01 and converts that to a date. So you're not actually removing the year part, but calculating how long ago it was.
Here's another way to approach the problem. It will just replace the year, leaving the rest of the date untouched.
You could do this with substrings too.
TO_TIMESTAMP()
will cast the day 2010-02-29 to 2010-03-01, so it's safe to use.这是jmz提到的子串解决方案:
This is the substring solution jmz mentioned:
谢谢大家, jmz 和 a_horse_with_no_name 解决方案都工作正常。
我还修复了我的解决方案。问题出在 to_timestamp 上,它返回
带时区的时间戳
,而我期望不带时区的时间戳
。添加类型转换就足够了:Thanks guys, both jmz and a_horse_with_no_name solutions work fine.
I also fixed my solution. The problem was with to_timestamp which returns
timestamp with time zone
and I expectedtimestamp without time zone
. It was enough to add a typecast: