#c# #postgresql #datetime #npgsql
#c# #postgresql #дата и время #npgsql
Вопрос:
Я использую тип столбца «временная метка с часовым поясом» и устанавливаю свои даты и время следующим образом:
INSERT INTO mytable(col1)
VALUES(timestamp with time zone '2020-07-16 17:45:00.000000 00');
Всякий раз, когда я пытаюсь получить свои даты и время, они преобразуются в «локальный» вид.
Это не то, что я хочу, оно установлено как дата и время UTC, и я хочу вернуть его как UTC, я не хочу, чтобы он преобразовывался в local, входя в базу данных, и не возвращался обратно… это делает невозможным переход к UTC, не вызывая двусмысленности.
Я попытался установить переменную среды «PGTZ»; Я также выполнил следующий sql при открытии соединения:
Connection.ExecuteAsync( "SET TIMEZONE TO 'UTC'" );
Кажется, что ничего из того, что я пробовал, не работает, и, похоже, это сделано специально в соответствии с различными сообщениями, такими как:
https://github.com/npgsql/npgsql/issues/347
Мне это кажется совершенно неправильным, но я надеюсь, что кто-нибудь может указать мне на обходной путь для этого.
Я использую .net5 / asp.net и Dapper (не EFCore) и Npgsql версии 4.1.5.
Ответ №1:
Postgresql timestamptz
фактически не сохраняет часовой пояс, он просто сохраняет значения как в UTC. Это означает '2020-07-16 17:45:00.000000 00'
, что при вводе не будет преобразовано в UTC. Без указанного часового пояса он будет повернут от TimeZone
настройки до UTC
. При извлечении, однако, он будет использовать TimeZone
настройку для возврата к этому часовому поясу. Я подозреваю, что ваша настройка не выполняется в том же сеансе, в котором выполняется извлечение метки времени. Я бы попробовал что-то вроде SELECT timestamp_fld AT TIME ZONE 'UTC'
Ответ №2:
Это действительно разработано и соответствует PostgreSQL при запросе значений timestamptz в обычных текстовых запросах. Если вы используете запуск psql или pgadmin и выбираете столбец timestamptz, вы увидите локальную временную метку, основанную на вашем TimeZone
параметре сеанса.
Как упоминалось @adrian-klaver, timestamptz не предназначен для хранения часового пояса в базе данных — речь идет о применении преобразований часовых поясов при чтении и записи значений временных меток в базу данных на основе TimeZone
параметра. Если вы не хотите никаких таких преобразований, подумайте о переходе на временную метку (без часового пояса) и о том, чтобы все временные метки были как UTC по соглашению.
Комментарии:
1. Спасибо @Shay, я читал, что если вы хотите сохранить значения UTC, вы должны использовать
timestamp with time zone
, но я не учел это, поскольку я контролирую вещи с помощью кода, тогда я могу убедиться, что его utc, прежде чем устанавливать значение. Я должен сказать, что из всех баз данных postgres кажется чрезмерно сложным в этом отношении и склонным к ошибкам, поэтому спасибо за разъяснение2. Я согласен, что PG немного сбивает с толку (хотя FWIW, похоже, просто очень точно соответствует стандарту SQL). Возможно, вы захотите прочитать этот мой комментарий к timestamp с часовым поясом и без него; Я бы действительно рекомендовал использовать «UTC по соглашению»