web-dev-qa-db-ja.com

postgresの日付表現をISO 8601文字列に変換します

Postgresの日付表現をISO 8601文字列にフォーマットしようとしています。私はそれを行うことができるPostgres関数があると仮定していますが、ドキュメントの例が不足していることがわかりました。

私のクエリは

SELECT
  now()::timestamp

返す

[{{2016, 8, 9}, {3, 56, 55, 754181}}]

2016-8-9T03:56:55+00:00のような形式に日付を取得しようとしています。

そのためには、クエリにどのような変更を加える必要がありますか?ご協力いただきありがとうございます。

25
CallMeNorm

書式設定を行う方法を見つけたと思いますが、書式設定を自分で書いているので理想的ではありません。

解決策は次のとおりです。

SELECT to_char (now()::timestamp at time zone 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS"Z"')
24
CallMeNorm

たぶん誰かにとっては、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
19
Dattaya

これは、「PostgreSQLの日付表現をISO 8601文字列に変換する」簡単な方法です。

_SELECT to_json(now())#>>'{}'
_

_#>>_演算子をto_json()関数と組み合わせて使用​​します。両方ともこのページにあります: https://www.postgresql.org/docs/current/functions -json.html

演算子「指定されたパスのJSONオブジェクトをテキストとして取得[s]」。ただし、空の配列リテラル_'{}'_をパスとして指定すると、ルートオブジェクトが指定されます。

この方法を同様の方法と比較してください。

_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
_

短いですが、同じ結果が得られます。

5
adjenks

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. */

このブログ投稿 は非常に詳細な説明を提供します。

4
Hugh

タイムゾーンを設定する必要があるため、機能のみが機能しました。

ゾーンにデフォルト値のタイムゾーンを設定するには:

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)

this も見てください:

サーバーが別のタイムゾーンのタイムゾーン情報を返すようにする場合は、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)
3
rofrol