Я отвечал на этот вопрос stackoverflow и нашел странный результат:
select * from pg_timezone_names where name = 'Europe/Berlin' ;
name | abbrev | utc_offset | is_dst
---------------+--------+------------+--------
Europe/Berlin | CET | 01:00:00 | f
и следующий запрос
select id,
timestampwithtimezone,
timestampwithtimezone at time zone 'Europe/Berlin' as berlin,
timestampwithtimezone at time zone 'CET' as cet
from data ;
id | timestampwithtimezone | berlin | cet
-----+------------------------+---------------------+---------------------
205 | 2012-10-28 01:30:00+02 | 2012-10-28 01:30:00 | 2012-10-28 00:30:00
204 | 2012-10-28 02:00:00+02 | 2012-10-28 02:00:00 | 2012-10-28 01:00:00
203 | 2012-10-28 02:30:00+02 | 2012-10-28 02:30:00 | 2012-10-28 01:30:00
202 | 2012-10-28 02:59:59+02 | 2012-10-28 02:59:59 | 2012-10-28 01:59:59
106 | 2012-10-28 02:00:00+01 | 2012-10-28 02:00:00 | 2012-10-28 02:00:00
Я использую PostgreSQL 9.1.2 и Ubuntu 12.04.
Только что проверил, что на 8.2.11 результат такой же.
Согласно документации, не имеет значения, использую ли я имя или сокращение.
Это ошибка?
Я делаю что-то неправильно?
Может кто-нибудь объяснить этот результат?
РЕДАКТИРОВАТЬ Для комментария, что CET не Европа / Берлин.
Я просто выбираю значения из pg_timezone_names.
select * from pg_timezone_names where abbrev ='CEST';
name | abbrev | utc_offset | is_dst
------+--------+------------+--------
и
select * from pg_timezone_names where abbrev ='CET';
name | abbrev | utc_offset | is_dst
---------------------+--------+------------+--------
Africa/Tunis | CET | 01:00:00 | f
Africa/Algiers | CET | 01:00:00 | f
Africa/Ceuta | CET | 01:00:00 | f
CET | CET | 01:00:00 | f
Atlantic/Jan_Mayen | CET | 01:00:00 | f
Arctic/Longyearbyen | CET | 01:00:00 | f
Poland | CET | 01:00:00 | f
.....
Зимой Европа / Берлин +01. Летом это +02.
EDIT2
В 2012-10-28 часовом поясе изменился с летнего времени на зимнее время в 2:00.
Эти две записи имеют одинаковое значение в Европе / Берлине:
204 | 2012-10-28 02:00:00+02 | 2012-10-28 02:00:00 | 2012-10-28 01:00:00
106 | 2012-10-28 02:00:00+01 | 2012-10-28 02:00:00 | 2012-10-28 02:00:00
Это говорит о том, что если я использую одно из сокращений (CET или CEST) для большого диапазона данных (летнее и зимнее время), результат будет неправильным для некоторых записей. Будет хорошо, если я буду использовать «Европа / Берлин».
Я изменил системное время на «2012-01-17», а также изменилось имя pg_timezone_names.
select * from pg_timezone_names where name ='Europe/Berlin';
name | abbrev | utc_offset | is_dst
---------------+--------+------------+--------
Europe/Berlin | CEST | 02:00:00 | t
источник
2012-10-28 01:30:00
это CEST, а не CET.CET
, нетEurope/Berlin
- по крайней мере, во времена DST.Ответы:
На самом деле, в документации ясно сказано, что название часового пояса и аббревиатура будут вести себя по-разному.
FWIW, та же самая ссылка также говорит
источник
И это еще не суть! Я столкнулся с очень похожей проблемой некоторое время назад.
Основные недостатки аббревиатур часовых поясов уже представлены здесь: они не принимают во внимание летнее время (летнее время). Основное преимущество: простота, обеспечивающая превосходную производительность . Принимая во внимание правила летнего времени, имена часовых поясов становятся медленными по сравнению. Сокращения часового пояса - простые, символические смещения времени, названия часового пояса подчиняются постоянно меняющемуся набору правил. Я провел тесты в этом ответе на SO , разница замечательная. Но при применении к набору, как правило, необходимо использовать имена часовых поясов, чтобы охватить, возможно, различный статус DST для каждой строки (а также исторические различия).
Мы говорим о CET . Действительно сложная часть , что «CET» не только (очевидно) а зона сокращение времени , это также название часового пояса , по крайней мере , в соответствии с моей установки (PostgreSQL 9.1.6 на Debian Squeeze с локали «de_AT.UTF-8 ") и все остальные, которые я видел до сих пор. Я упоминаю эти детали, потому что Postgres использует информацию о локали базовой ОС, если она доступна.
Посмотреть на себя:
SQL Fiddle.
Postgres выбирает аббревиатуру над полным именем. Таким образом, даже несмотря на то, что я нашел CET в именах часовых поясов , выражение
'2012-01-18 01:00 CET'::timestamptz
интерпретируется в соответствии с слегка различающимися правилами для сокращений часовых поясов .Если это не заряженный пулемет, я не знаю что.
Чтобы избежать двусмысленности, используйте название часового пояса «Европа / Берлин» (или «Европа / Вена» в моем случае - что фактически одно и то же, за исключением исторических различий). Найдите больше деталей по теме в тесно связанном вопросе, который я упомянул выше .
В заключение я хотел бы высказать свое глубокое презрение к дебильной концепции DST. Это должно быть удалено из существования и никогда больше не упоминаться.
источник
Проверь это:
+02
CEST в Берлине, а не CET.источник