问题 时区感知date_trunc函数


以下查询

SELECT the_date FROM date_trunc('day', timestamp with time zone 
       '2001-01-1 00:00:00+0100') as the_date

结果

the_date
2000-12-31 00:00

有没有办法告诉date_trunc根据它所用的时区进行日/月/年转换?

预期的产出是: 2001-01-1 00:00+0100


4277
2018-06-04 14:22


起源

我觉得你很误 timestamp with time zone。 (这很常见,它是该类型实际语义的愚蠢名称)。 timestamp with time zone 实际上并不是带时区的时间戳。这是一个以UTC格式存储的时间戳,它被转换为/从 TimeZone I / O上的客户端。 - Craig Ringer
您的问题中存在错误。你称之为“约会”(the_date)实际上有一个形式 timestamp 真的应该是一个 timestamptz,因为显示的查询将返回。我们不知道这个结果是如何煮熟的。此外,时间戳的含义是不明确的,而不知道您当地的时区。 - Erwin Brandstetter
@ErwinBrandstetter我同意“the_date”在这种情况下具有误导性。但是我的当地时区与这个问题有什么关系呢? - Jannis
该 含义 一个 timestamp 值取决于您客户端中的当前时区设置。这可能有所帮助: stackoverflow.com/questions/9571392/... - Erwin Brandstetter


答案:


您需要指定要在其中显示的时区

select
    date_trunc(
        'day',
        timestamp with time zone '2001-01-1 00:00:00+0100' at time zone '-02'
    ) as the_date;
      the_date       
---------------------
 2001-01-01 00:00:00

AT TIME ZONE


14
2018-06-04 14:34



这修复了低端。但是“2001-12-31 24:00:00 + 0100”> 2002-01-01 00:00:00是什么? - Jannis
@Jay午夜是一个特例: 能够 从前一天引用,但始终属于第二天。即: select timestamptz '2001-12-31 24:00:00+00' 会屈服 2002-01-01 00:00:00+00 - pozs


虽然明确的答案可能对于OP的奇怪情况是正确的,但对其他人来说更可能是不正确的。您需要将date_trunc返回的时间戳转换为适当的时区。

select
    date_trunc(
        'day',
        some_timestamp at time zone users_timezone
    ) at time zone users_timezone as the_date;

重要的是要理解 date_trunc 返回一个 timestamp 没有附加时区。您需要将时间戳转换为适当的时区,因为数据库客户端或任何下游可能具有不同的时区。


0
2018-02-28 14:33