Ответ 1
Я думаю, что нашел способ сделать форматирование, но это не идеально, потому что я сам пишу форматирование.
Вот потенциальное решение:
SELECT to_char (now()::timestamp at time zone 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')
Я пытаюсь отформатировать представление даты Postgres в строку ISO 8601. Я предполагаю, что есть функция Postgres, которая может это сделать, но я нашел документацию на примерах.
Мой запрос
SELECT
now()::timestamp
который возвращает
[{{2016, 8, 9}, {3, 56, 55, 754181}}]
Я пытаюсь получить дату в формате, который больше похож на
2016-8-9T03:56:55+00:00
.
Какие изменения необходимо внести в мой запрос, чтобы это произошло? Благодарим за помощь.
Я думаю, что нашел способ сделать форматирование, но это не идеально, потому что я сам пишу форматирование.
Вот потенциальное решение:
SELECT to_char (now()::timestamp at time zone 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')
Возможно, для кого-то было бы полезно знать, что поскольку функция Postgres 9.4 to_json
(а также row_to_json
) также преобразует временную метку в соответствующий ISO 8601 формат, но, кроме того, она переносит значение в кавычки, которые могут не быть желательно:
SELECT now();
2017-05-10 15:57:23.736054+03
SELECT to_json(now());
"2017-05-10T15:57:23.769561+03:00"
-- in case you want to trim the quotes
SELECT trim(both '"' from to_json(now())::text);
2017-05-10T15:57:23.806563+03:00
Только функция работала для меня, потому что вам нужно установить часовой пояс.
Чтобы установить часовой пояс по умолчанию с зоной:
create table somedata (
release_date timestamptz DEFAULT NOW()
)
Создать функция:
CREATE OR REPLACE FUNCTION date_display_tz(param_dt timestamp with time zone)
RETURNS text AS
$$
DECLARE var_result varchar;
BEGIN
PERFORM set_config('timezone', 'UTC', true);
var_result := to_char(param_dt , 'YYYY-MM-DD"T"HH24:MI:SS:MS"Z"');
RETURN var_result;
END;
$$ language plpgsql VOLATILE;
И вывод:
# SELECT
# localtimestamp, current_timestamp,
# to_char(localtimestamp, 'YYYY-MM-DD"T"HH24:MI:SS:MS"Z"'),
# to_char(current_timestamp, 'YYYY-MM-DD"T"HH24:MI:SS:MS"Z"'),
# date_display_tz(localtimestamp), date_display_tz(current_timestamp);
timestamp | now | to_char | to_char | date_display_tz | date_display_tz
----------------------------+-------------------------------+--------------------------+--------------------------+--------------------------+--------------------------
2017-04-27 23:48:03.802764 | 2017-04-27 21:48:03.802764+00 | 2017-04-27T23:48:03:802Z | 2017-04-27T23:48:03:802Z | 2017-04-27T21:48:03:802Z | 2017-04-27T21:48:03:802Z
(1 row)
Посмотрите это:
Если вы хотите, чтобы сервер возвращал информацию о часовом поясе, соответствующую другой часовой пояс, я считаю, что вам нужно использовать SET TIME ZONE. В противном случае сервер автоматически (преобразует временную метку) и возвращает часовой пояс сервера.
test=# select (current_timestamp at time zone 'UTC') at time zone 'UTC';
timezone
-------------------------------
2005-04-22 16:26:57.209082+09
(1 row)
test=# set time zone 'UTC';
SET
test=# select (current_timestamp at time zone 'UTC') at time zone 'UTC';
timezone
-------------------------------
2005-04-22 07:27:55.841596+00
(1 row)
test=# select (current_timestamp at time zone 'UTC');
timezone
----------------------------
2005-04-22 07:28:48.888154
(1 row)
test=# select (current_timestamp at time zone 'UTC')::timestamptz;
timezone
-------------------------------
2005-04-22 07:38:19.979511+00
(1 row)
Установите переменную сеанса timezone
в любой часовой пояс, в который вы хотите включить вывод, затем используйте to_char(now(), 'YYYY-MM-DD"T"HH24:MI:SSOF')
Если вы используете at time zone '...'
, помните, что это отключит любую информацию о часовом поясе и предположит, что пользователь уже знает часовой пояс.
Если вы используете at time zone 'UTC'
, тогда выход всегда должен быть временем UTC с правильной информацией о часовом поясе (без смещения).
set timezone='UTC';
select to_char(now(), 'YYYY-MM-DD"T"HH24:MI:SSOF');
2017-11-17T02:02:26+00 /* UTC time */
select to_char(now() at time zone 'Australia/Sydney', 'YYYY-MM-DD"T"HH24:MI:SSOF');
2017-11-17T13:02:26+00 /* Local Sydney time, but note timezone is incorrect. */
set timezone='Australia/Sydney';
select to_char(now(), 'YYYY-MM-DD"T"HH24:MI:SSOF');
2017-11-17T13:02:26+11 /* Local Sydney time with correct time zone! */
select to_char(now() at time zone 'Australia/Sydney', 'YYYY-MM-DD"T"HH24:MI:SSOF');
2017-11-17T13:02:26+00 /* Still local Sydney time, but time zone info has been removed. */
select to_char(now() at time zone 'UTC', 'YYYY-MM-DD"T"HH24:MI:SSOF');
2017-11-17T02:02:26+00 /* Correct UTC time with correct offset. */
Это сообщение в блоге дает довольно подробное объяснение.
Это краткий способ "превратить представление даты PostgreSQL в строку ISO 8601":
SELECT to_json(now())#>>'{}'
Он использует оператор #>>
в сочетании с to_json()
, которую можно найти на этой странице: https://www.postgresql.org/docs/current/functions-json.html.
Оператор "Получить [s] объект JSON по указанному пути как текст". Однако, когда вы указываете пустой литерал массива '{}'
в качестве пути, он указывает корневой объект.
Сравните этот метод с похожим методом:
SELECT
to_json(now())::text AS has_unwanted_quotes,
trim(both '"' from to_json(now())::text) AS a_bit_lengthy,
to_json(now())#>>'{}' AS just_right
Это короче, но дает те же результаты.
Это краткий способ "превратить представление даты PostgreSQL в строку ISO 8601":
SELECT to_json(now())#>>'{}'
Он использует оператор #>>
в сочетании с to_json()
, которую можно найти на этой странице: https://www.postgresql.org/docs/current/functions-json.html.
Оператор "Получить [s] объект JSON по указанному пути как текст". Однако, когда вы указываете {}
в качестве пути, он указывает корневой объект.
Сравните этот метод с похожим методом:
SELECT
to_json(now())::text AS has_unwanted_quotes,
trim(both '"' from to_json(now())::text) AS a_bit_lengthy,
to_json(now())#>>'{}' AS just_right
Это короче, но дает те же результаты.