mirror of
https://github.com/postgres/postgres.git
synced 2025-06-13 07:41:39 +03:00
Fix date/time formats for XML Schema output.
Pavel Stehule
This commit is contained in:
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.177 2007/02/19 17:41:39 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/datetime.c,v 1.178 2007/03/01 14:52:03 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -3153,7 +3153,7 @@ datebsearch(const char *key, const datetkn *base, int nel)
|
|||||||
* Append representation of a numeric timezone offset to str.
|
* Append representation of a numeric timezone offset to str.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
EncodeTimezone(char *str, int tz)
|
EncodeTimezone(char *str, int tz, int style)
|
||||||
{
|
{
|
||||||
int hour,
|
int hour,
|
||||||
min,
|
min,
|
||||||
@ -3171,7 +3171,7 @@ EncodeTimezone(char *str, int tz)
|
|||||||
|
|
||||||
if (sec != 0)
|
if (sec != 0)
|
||||||
sprintf(str, "%02d:%02d:%02d", hour, min, sec);
|
sprintf(str, "%02d:%02d:%02d", hour, min, sec);
|
||||||
else if (min != 0)
|
else if (min != 0 || style == USE_XSD_DATES)
|
||||||
sprintf(str, "%02d:%02d", hour, min);
|
sprintf(str, "%02d:%02d", hour, min);
|
||||||
else
|
else
|
||||||
sprintf(str, "%02d", hour);
|
sprintf(str, "%02d", hour);
|
||||||
@ -3189,6 +3189,7 @@ EncodeDateOnly(struct pg_tm * tm, int style, char *str)
|
|||||||
switch (style)
|
switch (style)
|
||||||
{
|
{
|
||||||
case USE_ISO_DATES:
|
case USE_ISO_DATES:
|
||||||
|
case USE_XSD_DATES:
|
||||||
/* compatible with ISO date formats */
|
/* compatible with ISO date formats */
|
||||||
if (tm->tm_year > 0)
|
if (tm->tm_year > 0)
|
||||||
sprintf(str, "%04d-%02d-%02d",
|
sprintf(str, "%04d-%02d-%02d",
|
||||||
@ -3266,7 +3267,7 @@ EncodeTimeOnly(struct pg_tm * tm, fsec_t fsec, int *tzp, int style, char *str)
|
|||||||
sprintf(str + strlen(str), ":%02d", tm->tm_sec);
|
sprintf(str + strlen(str), ":%02d", tm->tm_sec);
|
||||||
|
|
||||||
if (tzp != NULL)
|
if (tzp != NULL)
|
||||||
EncodeTimezone(str, *tzp);
|
EncodeTimezone(str, *tzp, style);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} /* EncodeTimeOnly() */
|
} /* EncodeTimeOnly() */
|
||||||
@ -3279,6 +3280,7 @@ EncodeTimeOnly(struct pg_tm * tm, fsec_t fsec, int *tzp, int style, char *str)
|
|||||||
* SQL - mm/dd/yyyy hh:mm:ss.ss tz
|
* SQL - mm/dd/yyyy hh:mm:ss.ss tz
|
||||||
* ISO - yyyy-mm-dd hh:mm:ss+/-tz
|
* ISO - yyyy-mm-dd hh:mm:ss+/-tz
|
||||||
* German - dd.mm.yyyy hh:mm:ss tz
|
* German - dd.mm.yyyy hh:mm:ss tz
|
||||||
|
* XSD - yyyy-mm-ddThh:mm:ss.ss+/-tz
|
||||||
* Variants (affects order of month and day for Postgres and SQL styles):
|
* Variants (affects order of month and day for Postgres and SQL styles):
|
||||||
* US - mm/dd/yyyy
|
* US - mm/dd/yyyy
|
||||||
* European - dd/mm/yyyy
|
* European - dd/mm/yyyy
|
||||||
@ -3297,11 +3299,18 @@ EncodeDateTime(struct pg_tm * tm, fsec_t fsec, int *tzp, char **tzn, int style,
|
|||||||
switch (style)
|
switch (style)
|
||||||
{
|
{
|
||||||
case USE_ISO_DATES:
|
case USE_ISO_DATES:
|
||||||
|
case USE_XSD_DATES:
|
||||||
/* Compatible with ISO-8601 date formats */
|
/* Compatible with ISO-8601 date formats */
|
||||||
|
|
||||||
sprintf(str, "%04d-%02d-%02d %02d:%02d",
|
if (style == USE_ISO_DATES)
|
||||||
|
sprintf(str, "%04d-%02d-%02d %02d:%02d",
|
||||||
(tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1),
|
(tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1),
|
||||||
tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min);
|
tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min);
|
||||||
|
else
|
||||||
|
sprintf(str, "%04d-%02d-%02dT%02d:%02d",
|
||||||
|
(tm->tm_year > 0) ? tm->tm_year : -(tm->tm_year - 1),
|
||||||
|
tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print fractional seconds if any. The field widths here should
|
* Print fractional seconds if any. The field widths here should
|
||||||
@ -3333,7 +3342,7 @@ EncodeDateTime(struct pg_tm * tm, fsec_t fsec, int *tzp, char **tzn, int style,
|
|||||||
* a valid time zone translation.
|
* a valid time zone translation.
|
||||||
*/
|
*/
|
||||||
if (tzp != NULL && tm->tm_isdst >= 0)
|
if (tzp != NULL && tm->tm_isdst >= 0)
|
||||||
EncodeTimezone(str, *tzp);
|
EncodeTimezone(str, *tzp, style);
|
||||||
|
|
||||||
if (tm->tm_year <= 0)
|
if (tm->tm_year <= 0)
|
||||||
sprintf(str + strlen(str), " BC");
|
sprintf(str + strlen(str), " BC");
|
||||||
@ -3379,7 +3388,7 @@ EncodeDateTime(struct pg_tm * tm, fsec_t fsec, int *tzp, char **tzn, int style,
|
|||||||
if (*tzn != NULL)
|
if (*tzn != NULL)
|
||||||
sprintf(str + strlen(str), " %.*s", MAXTZLEN, *tzn);
|
sprintf(str + strlen(str), " %.*s", MAXTZLEN, *tzn);
|
||||||
else
|
else
|
||||||
EncodeTimezone(str, *tzp);
|
EncodeTimezone(str, *tzp, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tm->tm_year <= 0)
|
if (tm->tm_year <= 0)
|
||||||
@ -3423,7 +3432,7 @@ EncodeDateTime(struct pg_tm * tm, fsec_t fsec, int *tzp, char **tzn, int style,
|
|||||||
if (*tzn != NULL)
|
if (*tzn != NULL)
|
||||||
sprintf(str + strlen(str), " %.*s", MAXTZLEN, *tzn);
|
sprintf(str + strlen(str), " %.*s", MAXTZLEN, *tzn);
|
||||||
else
|
else
|
||||||
EncodeTimezone(str, *tzp);
|
EncodeTimezone(str, *tzp, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tm->tm_year <= 0)
|
if (tm->tm_year <= 0)
|
||||||
@ -3486,7 +3495,7 @@ EncodeDateTime(struct pg_tm * tm, fsec_t fsec, int *tzp, char **tzn, int style,
|
|||||||
* the date/time parser later. - thomas 2001-10-19
|
* the date/time parser later. - thomas 2001-10-19
|
||||||
*/
|
*/
|
||||||
sprintf(str + strlen(str), " ");
|
sprintf(str + strlen(str), " ");
|
||||||
EncodeTimezone(str, *tzp);
|
EncodeTimezone(str, *tzp, style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.32 2007/02/27 23:48:09 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.33 2007/03/01 14:52:04 petere Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -63,6 +63,8 @@
|
|||||||
#include "parser/parse_expr.h"
|
#include "parser/parse_expr.h"
|
||||||
#include "utils/array.h"
|
#include "utils/array.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/date.h"
|
||||||
|
#include "utils/datetime.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
#include "utils/xml.h"
|
#include "utils/xml.h"
|
||||||
@ -1513,12 +1515,81 @@ map_sql_value_to_xml_value(Datum value, Oid type)
|
|||||||
bool isvarlena;
|
bool isvarlena;
|
||||||
char *p, *str;
|
char *p, *str;
|
||||||
|
|
||||||
if (type == BOOLOID)
|
/*
|
||||||
|
* Special XSD formatting for some data types
|
||||||
|
*/
|
||||||
|
switch (type)
|
||||||
{
|
{
|
||||||
if (DatumGetBool(value))
|
case BOOLOID:
|
||||||
return "true";
|
if (DatumGetBool(value))
|
||||||
else
|
return "true";
|
||||||
return "false";
|
else
|
||||||
|
return "false";
|
||||||
|
|
||||||
|
case DATEOID:
|
||||||
|
{
|
||||||
|
DateADT date;
|
||||||
|
struct pg_tm tm;
|
||||||
|
char buf[MAXDATELEN + 1];
|
||||||
|
|
||||||
|
date = DatumGetDateADT(value);
|
||||||
|
j2date(date + POSTGRES_EPOCH_JDATE,
|
||||||
|
&(tm.tm_year), &(tm.tm_mon), &(tm.tm_mday));
|
||||||
|
EncodeDateOnly(&tm, USE_XSD_DATES, buf);
|
||||||
|
|
||||||
|
return pstrdup(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
case TIMESTAMPOID:
|
||||||
|
{
|
||||||
|
Timestamp timestamp;
|
||||||
|
struct pg_tm tm;
|
||||||
|
fsec_t fsec;
|
||||||
|
char *tzn = NULL;
|
||||||
|
char buf[MAXDATELEN + 1];
|
||||||
|
|
||||||
|
timestamp = DatumGetTimestamp(value);
|
||||||
|
|
||||||
|
/* XSD doesn't support infinite values */
|
||||||
|
if (TIMESTAMP_NOT_FINITE(timestamp))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||||
|
errmsg("timestamp out of range")));
|
||||||
|
else if (timestamp2tm(timestamp, NULL, &tm, &fsec, NULL, NULL) == 0)
|
||||||
|
EncodeDateTime(&tm, fsec, NULL, &tzn, USE_XSD_DATES, buf);
|
||||||
|
else
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||||
|
errmsg("timestamp out of range")));
|
||||||
|
|
||||||
|
return pstrdup(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
case TIMESTAMPTZOID:
|
||||||
|
{
|
||||||
|
TimestampTz timestamp;
|
||||||
|
struct pg_tm tm;
|
||||||
|
int tz;
|
||||||
|
fsec_t fsec;
|
||||||
|
char *tzn = NULL;
|
||||||
|
char buf[MAXDATELEN + 1];
|
||||||
|
|
||||||
|
timestamp = DatumGetTimestamp(value);
|
||||||
|
|
||||||
|
/* XSD doesn't support infinite values */
|
||||||
|
if (TIMESTAMP_NOT_FINITE(timestamp))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||||
|
errmsg("timestamp out of range")));
|
||||||
|
else if (timestamp2tm(timestamp, &tz, &tm, &fsec, &tzn, NULL) == 0)
|
||||||
|
EncodeDateTime(&tm, fsec, &tz, &tzn, USE_XSD_DATES, buf);
|
||||||
|
else
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
|
||||||
|
errmsg("timestamp out of range")));
|
||||||
|
|
||||||
|
return pstrdup(buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getTypeOutputInfo(type, &typeOut, &isvarlena);
|
getTypeOutputInfo(type, &typeOut, &isvarlena);
|
||||||
@ -2234,17 +2305,17 @@ map_sql_type_to_xmlschema_type(Oid typeoid, int typmod)
|
|||||||
|
|
||||||
if (typmod == -1)
|
if (typmod == -1)
|
||||||
appendStringInfo(&result,
|
appendStringInfo(&result,
|
||||||
" <xsd:restriction base=\"xsd:time\">\n"
|
" <xsd:restriction base=\"xsd:dateTime\">\n"
|
||||||
" <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}T\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}(.\\p{Nd}+)?%s\"/>\n"
|
" <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}T\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}(.\\p{Nd}+)?%s\"/>\n"
|
||||||
" </xsd:restriction>\n", tz);
|
" </xsd:restriction>\n", tz);
|
||||||
else if (typmod == 0)
|
else if (typmod == 0)
|
||||||
appendStringInfo(&result,
|
appendStringInfo(&result,
|
||||||
" <xsd:restriction base=\"xsd:time\">\n"
|
" <xsd:restriction base=\"xsd:dateTime\">\n"
|
||||||
" <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}T\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n"
|
" <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}T\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}%s\"/>\n"
|
||||||
" </xsd:restriction>\n", tz);
|
" </xsd:restriction>\n", tz);
|
||||||
else
|
else
|
||||||
appendStringInfo(&result,
|
appendStringInfo(&result,
|
||||||
" <xsd:restriction base=\"xsd:time\">\n"
|
" <xsd:restriction base=\"xsd:dateTime\">\n"
|
||||||
" <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}T\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}.\\p{Nd}{%d}%s\"/>\n"
|
" <xsd:pattern value=\"\\p{Nd}{4}-\\p{Nd}{2}-\\p{Nd}{2}T\\p{Nd}{2}:\\p{Nd}{2}:\\p{Nd}{2}.\\p{Nd}{%d}%s\"/>\n"
|
||||||
" </xsd:restriction>\n", typmod - VARHDRSZ, tz);
|
" </xsd:restriction>\n", typmod - VARHDRSZ, tz);
|
||||||
break;
|
break;
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.192 2007/02/15 23:23:23 alvherre Exp $
|
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.193 2007/03/01 14:52:04 petere Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* some of the information in this file should be moved to other files.
|
* some of the information in this file should be moved to other files.
|
||||||
@ -178,6 +178,7 @@ extern DLLIMPORT Oid MyDatabaseTableSpace;
|
|||||||
#define USE_ISO_DATES 1
|
#define USE_ISO_DATES 1
|
||||||
#define USE_SQL_DATES 2
|
#define USE_SQL_DATES 2
|
||||||
#define USE_GERMAN_DATES 3
|
#define USE_GERMAN_DATES 3
|
||||||
|
#define USE_XSD_DATES 4
|
||||||
|
|
||||||
/* valid DateOrder values */
|
/* valid DateOrder values */
|
||||||
#define DATEORDER_YMD 0
|
#define DATEORDER_YMD 0
|
||||||
|
Reference in New Issue
Block a user