为什么在使用 UCT 值与时区名称时在 postgresql 中得到不同的值?
Why do I get different values in postgresql when using UCT values vs timezone names?
如果我运行这个查询:
SELECT ('2021-11-02 08:00:00+00' AT TIME ZONE 'UCT') at TIME ZONE 'UCT+2';
它给出了这个结果:
2021-11-02 10:00:00+00
这对我来说似乎是正确的...
但是,我的时区数据采用字符串格式,例如:“Africa/Johannesburg”,我知道它在 UCT+2 时区。
但是运行宁此查询:
SELECT ('2021-11-02 08:00:00+00' AT TIME ZONE 'UCT') at TIME ZONE 'Africa/Johannesburg';
给出这个结果:
2021-11-02 06:00:00+00
这与我预期的相反。我知道我可以编写代码将字符串转换为 UCT 值,但我不明白为什么字符串值似乎与使用 UCT 值相反。有人可以解释为什么会这样吗?
哇,这里有很多东西要打开。
最主要的是(对 mis-quote Inigo Montoya)我不认为 UTC+2
是你认为的那样。
这里的一件重要事情是精确的格式。
你说你得到这个结果:
2021-11-02 06:00:00+00
但我得到的是:
2021-11-02 06:00:00
这真的很重要,因为我得到的不包括 +00
。那是因为它仍然是 08:00
在 +00
时区。
AT TIME ZONE
语法表示“这个地方的本地人在这个特定的 UTC 时间会看到什么时间?”。约翰内斯堡的某个人会将其视为 10:00。伦敦(冬天)的人会将其视为 06:00。但这是同一时刻。
因此 AT TIME ZONE
的输出通常不包含与 UTC (+00
) 的时区偏移量。
您使用两个 AT TIME ZONE
子句进行的转换是多余的。因为它 知道 它在那个时区,因此 UCT 时间是多少。你会用一个 AT TIME ZONE
子句得到相同的结果(试一试)。
您得到不同答案的原因似乎是因为 PostgreSQL 不会将 UCT+2
解释为比 UCT 早 2 小时的时区。它解释为您指定 POSIX 时区定义,其中还可以包括夏令时规则等。
此页面:https://www.postgresql.org/docs/current/datatype-datetime.html 表示 PostgreSQL 将接受以 3 种方式指定的时区:
- 全名 - 例如'Africa/Johannesburg'
- 缩写 - 例如'SAST'
- Posix 格式,例如'CET-1CEST,M3.5.0,M10.5.0/3'(这显然是巴黎)
实际上,它不包括 Posix 格式示例,它位于此页面上:https://www.postgresql.org/docs/current/datetime-posix-timezone-specs.html
基本上,posix 格式是一种指定时区规则的方式。
类似
[abbreviation][offset][daylight savings abbrev][DST offset][dst rules]
所以说 'UCT+2' 可能是“错误的形式”,因为您试图更改具有标准用法的缩写词 'UTC' 的含义。
您可以确认它没有使用您所在时区的“UCT”部分来引用实际 UCT 时区。如果你这样做:
SELECT ('2021-11-02 08:00:00+00' AT TIME ZONE 'BOB')
PostgreSQL 会说它无法识别时区“BOB”。
但如果你这样做
SELECT ('2021-11-02 08:00:00+00' AT TIME ZONE 'BOB+2')
它会很乐意给你06:00:00
。事实上,如果你愿意,你可以把(几乎)任何东西粘在那里而不是“UCT”。它不会用于计算。
请注意,我链接的 posix 页面显示
POSIX time zone specifications are inadequate to deal with the
complexity of real-world time zone history, but there are sometimes
reasons to use them.
最后,'UCT' 是完全有效的,但它让我头疼。我只看到它是 'UTC',所以直到。
如果我运行这个查询:
SELECT ('2021-11-02 08:00:00+00' AT TIME ZONE 'UCT') at TIME ZONE 'UCT+2';
它给出了这个结果:
2021-11-02 10:00:00+00
这对我来说似乎是正确的...
但是,我的时区数据采用字符串格式,例如:“Africa/Johannesburg”,我知道它在 UCT+2 时区。
但是运行宁此查询:
SELECT ('2021-11-02 08:00:00+00' AT TIME ZONE 'UCT') at TIME ZONE 'Africa/Johannesburg';
给出这个结果:
2021-11-02 06:00:00+00
这与我预期的相反。我知道我可以编写代码将字符串转换为 UCT 值,但我不明白为什么字符串值似乎与使用 UCT 值相反。有人可以解释为什么会这样吗?
哇,这里有很多东西要打开。
最主要的是(对 mis-quote Inigo Montoya)我不认为 UTC+2
是你认为的那样。
这里的一件重要事情是精确的格式。
你说你得到这个结果:
2021-11-02 06:00:00+00
但我得到的是:
2021-11-02 06:00:00
这真的很重要,因为我得到的不包括 +00
。那是因为它仍然是 08:00
在 +00
时区。
AT TIME ZONE
语法表示“这个地方的本地人在这个特定的 UTC 时间会看到什么时间?”。约翰内斯堡的某个人会将其视为 10:00。伦敦(冬天)的人会将其视为 06:00。但这是同一时刻。
因此 AT TIME ZONE
的输出通常不包含与 UTC (+00
) 的时区偏移量。
您使用两个 AT TIME ZONE
子句进行的转换是多余的。因为它 知道 它在那个时区,因此 UCT 时间是多少。你会用一个 AT TIME ZONE
子句得到相同的结果(试一试)。
您得到不同答案的原因似乎是因为 PostgreSQL 不会将 UCT+2
解释为比 UCT 早 2 小时的时区。它解释为您指定 POSIX 时区定义,其中还可以包括夏令时规则等。
此页面:https://www.postgresql.org/docs/current/datatype-datetime.html 表示 PostgreSQL 将接受以 3 种方式指定的时区:
- 全名 - 例如'Africa/Johannesburg'
- 缩写 - 例如'SAST'
- Posix 格式,例如'CET-1CEST,M3.5.0,M10.5.0/3'(这显然是巴黎)
实际上,它不包括 Posix 格式示例,它位于此页面上:https://www.postgresql.org/docs/current/datetime-posix-timezone-specs.html
基本上,posix 格式是一种指定时区规则的方式。
类似
[abbreviation][offset][daylight savings abbrev][DST offset][dst rules]
所以说 'UCT+2' 可能是“错误的形式”,因为您试图更改具有标准用法的缩写词 'UTC' 的含义。
您可以确认它没有使用您所在时区的“UCT”部分来引用实际 UCT 时区。如果你这样做:
SELECT ('2021-11-02 08:00:00+00' AT TIME ZONE 'BOB')
PostgreSQL 会说它无法识别时区“BOB”。
但如果你这样做
SELECT ('2021-11-02 08:00:00+00' AT TIME ZONE 'BOB+2')
它会很乐意给你06:00:00
。事实上,如果你愿意,你可以把(几乎)任何东西粘在那里而不是“UCT”。它不会用于计算。
请注意,我链接的 posix 页面显示
POSIX time zone specifications are inadequate to deal with the complexity of real-world time zone history, but there are sometimes reasons to use them.
最后,'UCT' 是完全有效的,但它让我头疼。我只看到它是 'UTC',所以直到。