将 postgres 日期表示转换为 ISO 8601 字符串
Turn postgres date representation into ISO 8601 string
我正在尝试将 Postgres 日期表示形式格式化为 ISO 8601 字符串。我假设有一个 Postgres 函数可以做到这一点,但我发现文档中的示例很少。
我的查询是
SELECT
now()::timestamp
哪个returns
[{{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"')
只有功能对我有用,因为你需要设置时区。
要使用带默认值的时区:
create table somedata (
release_date timestamptz DEFAULT NOW()
)
创建 function:
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:
If you want the server to return time zone information respective of
another time zone, I believe you'll need to use SET TIME ZONE.
Otherwise, the server automatically (converts the timestamp) and
returns the time zone of the server.
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)
也许对于某些人来说,了解自 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
将 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. */
This blog post解释的很详细
这是“将 PostgreSQL 日期表示形式转换为 ISO 8601 字符串”的简洁方法:
SELECT to_json(now())#>>'{}'
它结合使用 #>>
运算符和 to_json()
函数,两者都可以在此页面上找到:
https://www.postgresql.org/docs/current/functions-json.html
运算符“获取[s] JSON 指定路径的对象作为文本”。但是,当您将空数组文字 '{}'
指定为路径时,它会指定根对象。
将此方法与类似方法进行比较:
SELECT
to_char(now(), 'YYYY-MM-DD"T"HH24:MI:SSOF') AS most_lengthy, -- See note: *
trim(both '"' from to_json(now())::text) AS a_bit_lengthy,
to_json(now())::text AS unwanted_quotes,
to_json(now())#>>'{}' AS just_right
它更短但产生相同的结果。
用户@atoth 指出亚秒分量使用 to_json()
删除了尾随零,因此 2022-03-31 17:39:23.500
被转换为 2022-03-31T17:39:23.5Z
。由于一些日期收件人需要非常特定的格式,我测试了以下内容:
SELECT
to_char('2022-03-31 17:39:23.5'::timestamp, 'YYYY-MM-DD"T"HH24:MI:SS.MSOF'),
to_char('2022-03-31 17:39:23.500'::timestamp, 'YYYY-MM-DD"T"HH24:MI:SS.MSOF'),
to_char('2022-03-31 17:39:23.5123456789'::timestamp, 'YYYY-MM-DD"T"HH24:MI:SS.MSOF'),
to_char('2022-03-31 17:39:23.5123456789'::timestamp, 'YYYY-MM-DD"T"HH24:MI:SS.USOF')
这是 Postgres 10 的输出:
"2022-03-31T17:39:23.500+00", "2022-03-31T17:39:23.500+00", "2022-03-31T17:39:23.512+00", "2022-03-31T17:39:23.512346+00"
所以看起来 MS
您可以指定 3 位小数,不多也不少,而 US
您将得到 6 位小数,不多也不少。除了这两个精度选项之外,您还必须进行一些时髦的字符串操作。
玩得开心!
* 此外,JavaScript 不会通过 Date()
构造函数解析第一个方法的输出,因为它期望 simplification of the ISO 8601 只接受 中的时区( +/-)HH:mm 或 Z 格式,但 OF
returns (+/-)HH 没有分钟的格式,除非输入时区是小时的一小部分,例如在会话开始时使用 SET timezone=-4.5;
。或者,您可以手动将时区作为字符串附加到冗长的版本中,并排除 OF
Simple/trivial:
SELECT REPLACE(NOW()::TEXT, ' ', 'T');
或者如果爱好者需要使用
REGEXP_REPLACE()
我正在尝试将 Postgres 日期表示形式格式化为 ISO 8601 字符串。我假设有一个 Postgres 函数可以做到这一点,但我发现文档中的示例很少。
我的查询是
SELECT
now()::timestamp
哪个returns
[{{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"')
只有功能对我有用,因为你需要设置时区。
要使用带默认值的时区:
create table somedata (
release_date timestamptz DEFAULT NOW()
)
创建 function:
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:
If you want the server to return time zone information respective of another time zone, I believe you'll need to use SET TIME ZONE. Otherwise, the server automatically (converts the timestamp) and returns the time zone of the server.
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)
也许对于某些人来说,了解自 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
将 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. */
This blog post解释的很详细
这是“将 PostgreSQL 日期表示形式转换为 ISO 8601 字符串”的简洁方法:
SELECT to_json(now())#>>'{}'
它结合使用 #>>
运算符和 to_json()
函数,两者都可以在此页面上找到:
https://www.postgresql.org/docs/current/functions-json.html
运算符“获取[s] JSON 指定路径的对象作为文本”。但是,当您将空数组文字 '{}'
指定为路径时,它会指定根对象。
将此方法与类似方法进行比较:
SELECT
to_char(now(), 'YYYY-MM-DD"T"HH24:MI:SSOF') AS most_lengthy, -- See note: *
trim(both '"' from to_json(now())::text) AS a_bit_lengthy,
to_json(now())::text AS unwanted_quotes,
to_json(now())#>>'{}' AS just_right
它更短但产生相同的结果。
用户@atoth 指出亚秒分量使用 to_json()
删除了尾随零,因此 2022-03-31 17:39:23.500
被转换为 2022-03-31T17:39:23.5Z
。由于一些日期收件人需要非常特定的格式,我测试了以下内容:
SELECT
to_char('2022-03-31 17:39:23.5'::timestamp, 'YYYY-MM-DD"T"HH24:MI:SS.MSOF'),
to_char('2022-03-31 17:39:23.500'::timestamp, 'YYYY-MM-DD"T"HH24:MI:SS.MSOF'),
to_char('2022-03-31 17:39:23.5123456789'::timestamp, 'YYYY-MM-DD"T"HH24:MI:SS.MSOF'),
to_char('2022-03-31 17:39:23.5123456789'::timestamp, 'YYYY-MM-DD"T"HH24:MI:SS.USOF')
这是 Postgres 10 的输出:
"2022-03-31T17:39:23.500+00", "2022-03-31T17:39:23.500+00", "2022-03-31T17:39:23.512+00", "2022-03-31T17:39:23.512346+00"
所以看起来 MS
您可以指定 3 位小数,不多也不少,而 US
您将得到 6 位小数,不多也不少。除了这两个精度选项之外,您还必须进行一些时髦的字符串操作。
玩得开心!
* 此外,JavaScript 不会通过 Date()
构造函数解析第一个方法的输出,因为它期望 simplification of the ISO 8601 只接受 中的时区( +/-)HH:mm 或 Z 格式,但 OF
returns (+/-)HH 没有分钟的格式,除非输入时区是小时的一小部分,例如在会话开始时使用 SET timezone=-4.5;
。或者,您可以手动将时区作为字符串附加到冗长的版本中,并排除 OF
Simple/trivial:
SELECT REPLACE(NOW()::TEXT, ' ', 'T');
或者如果爱好者需要使用
REGEXP_REPLACE()