Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitab14a73

Browse files
committed
Use EncodeDateTime instead of to_char to render JSON timestamps.
Per gripe from Peter Eisentraut and Tom Lane.The output is slightly different, but still ISO 8601 compliant: to_chardoesn't output the minutes when time zone offset is an integer number ofhours, while EncodeDateTime outputs ":00".The code is slightly adapted from code in xml.c
1 parent0ad1a81 commitab14a73

File tree

3 files changed

+56
-33
lines changed

3 files changed

+56
-33
lines changed

‎src/backend/utils/adt/json.c

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@
2121
#include"lib/stringinfo.h"
2222
#include"libpq/pqformat.h"
2323
#include"mb/pg_wchar.h"
24+
#include"miscadmin.h"
2425
#include"parser/parse_coerce.h"
2526
#include"utils/array.h"
2627
#include"utils/builtins.h"
27-
#include"utils/formatting.h"
28+
#include"utils/datetime.h"
2829
#include"utils/lsyscache.h"
2930
#include"utils/json.h"
3031
#include"utils/jsonapi.h"
@@ -63,13 +64,6 @@ typedef enum/* type categories for datum_to_json */
6364
JSONTYPE_OTHER/* all else */
6465
}JsonTypeCategory;
6566

66-
/*
67-
* to_char formats to turn timestamps and timpstamptzs into json strings
68-
* that are ISO 8601 compliant
69-
*/
70-
#defineTS_ISO8601_FMT "\\\"YYYY-MM-DD\"T\"HH24:MI:SS.US\\\""
71-
#defineTSTZ_ISO8601_FMT "\\\"YYYY-MM-DD\"T\"HH24:MI:SS.USOF\\\""
72-
7367
staticinlinevoidjson_lex(JsonLexContext*lex);
7468
staticinlinevoidjson_lex_string(JsonLexContext*lex);
7569
staticinlinevoidjson_lex_number(JsonLexContext*lex,char*s,bool*num_err);
@@ -1394,27 +1388,56 @@ datum_to_json(Datum val, bool is_null, StringInfo result,
13941388
pfree(outputstr);
13951389
break;
13961390
caseJSONTYPE_TIMESTAMP:
1397-
/*
1398-
* The timestamp format used here provides for quoting the string,
1399-
* so no escaping is required.
1400-
*/
1401-
jsontext=DatumGetTextP(
1402-
DirectFunctionCall2(timestamp_to_char,val,
1403-
CStringGetTextDatum(TS_ISO8601_FMT)));
1404-
outputstr=text_to_cstring(jsontext);
1405-
appendStringInfoString(result,outputstr);
1406-
pfree(outputstr);
1407-
pfree(jsontext);
1391+
{
1392+
Timestamptimestamp;
1393+
structpg_tmtm;
1394+
fsec_tfsec;
1395+
charbuf[MAXDATELEN+1];
1396+
1397+
timestamp=DatumGetTimestamp(val);
1398+
1399+
/* XSD doesn't support infinite values */
1400+
if (TIMESTAMP_NOT_FINITE(timestamp))
1401+
ereport(ERROR,
1402+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1403+
errmsg("timestamp out of range"),
1404+
errdetail("JSON does not support infinite timestamp values.")));
1405+
elseif (timestamp2tm(timestamp,NULL,&tm,&fsec,NULL,NULL)==0)
1406+
EncodeDateTime(&tm,fsec, false,0,NULL,USE_XSD_DATES,buf);
1407+
else
1408+
ereport(ERROR,
1409+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1410+
errmsg("timestamp out of range")));
1411+
1412+
appendStringInfo(result,"\"%s\"",buf);
1413+
}
14081414
break;
14091415
caseJSONTYPE_TIMESTAMPTZ:
1410-
/* same comment as for timestamp above */
1411-
jsontext=DatumGetTextP(
1412-
DirectFunctionCall2(timestamptz_to_char,val,
1413-
CStringGetTextDatum(TSTZ_ISO8601_FMT)));
1414-
outputstr=text_to_cstring(jsontext);
1415-
appendStringInfoString(result,outputstr);
1416-
pfree(outputstr);
1417-
pfree(jsontext);
1416+
{
1417+
TimestampTztimestamp;
1418+
structpg_tmtm;
1419+
inttz;
1420+
fsec_tfsec;
1421+
constchar*tzn=NULL;
1422+
charbuf[MAXDATELEN+1];
1423+
1424+
timestamp=DatumGetTimestamp(val);
1425+
1426+
/* XSD doesn't support infinite values */
1427+
if (TIMESTAMP_NOT_FINITE(timestamp))
1428+
ereport(ERROR,
1429+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1430+
errmsg("timestamp out of range"),
1431+
errdetail("JSON does not support infinite timestamp values.")));
1432+
elseif (timestamp2tm(timestamp,&tz,&tm,&fsec,&tzn,NULL)==0)
1433+
EncodeDateTime(&tm,fsec, true,tz,tzn,USE_XSD_DATES,buf);
1434+
else
1435+
ereport(ERROR,
1436+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
1437+
errmsg("timestamp out of range")));
1438+
1439+
appendStringInfo(result,"\"%s\"",buf);
1440+
}
14181441
break;
14191442
caseJSONTYPE_JSON:
14201443
/* JSON and JSONB output will already be escaped */

‎src/test/regress/expected/json.out

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,9 +420,9 @@ select to_json(timestamptz '2014-05-28 12:22:35.614298-04');
420420

421421
SET LOCAL TIME ZONE -8;
422422
select to_json(timestamptz '2014-05-28 12:22:35.614298-04');
423-
to_json
424-
---------------------------------
425-
"2014-05-28T08:22:35.614298-08"
423+
to_json
424+
------------------------------------
425+
"2014-05-28T08:22:35.614298-08:00"
426426
(1 row)
427427

428428
COMMIT;

‎src/test/regress/expected/json_1.out

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,9 +420,9 @@ select to_json(timestamptz '2014-05-28 12:22:35.614298-04');
420420

421421
SET LOCAL TIME ZONE -8;
422422
select to_json(timestamptz '2014-05-28 12:22:35.614298-04');
423-
to_json
424-
---------------------------------
425-
"2014-05-28T08:22:35.614298-08"
423+
to_json
424+
------------------------------------
425+
"2014-05-28T08:22:35.614298-08:00"
426426
(1 row)
427427

428428
COMMIT;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp