Hello,

this patch ensures independency datetime fields on current datestyle setting. Add new internal datestyle USE_XSD_DATESTYLE. It's almoust same to USE_ISO_DATESTYLE. Differences are for timestamp:

ISO: yyyy-mm-dd hh24:mi:ss
XSD: yyyy-mm-ddThh24:mi:ss

I found one link about this topic: http://forums.oracle.com/forums/thread.jspa?threadID=467278&tstart=0

Regards
Pavel Stehule

_________________________________________________________________
Emotikony a pozadi programu MSN Messenger ozivi vasi konverzaci. http://messenger.msn.cz/
*** ./src/backend/utils/adt/datetime.c.orig	2007-02-19 21:46:54.000000000 +0100
--- ./src/backend/utils/adt/datetime.c	2007-02-19 22:06:20.000000000 +0100
***************
*** 3188,3193 ****
--- 3188,3194 ----
  	switch (style)
  	{
  		case USE_ISO_DATES:
+ 		case USE_XSD_DATES:
  			/* compatible with ISO date formats */
  			if (tm->tm_year > 0)
  				sprintf(str, "%04d-%02d-%02d",
***************
*** 3278,3283 ****
--- 3279,3285 ----
   *	SQL - mm/dd/yyyy hh:mm:ss.ss tz
   *	ISO - yyyy-mm-dd 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):
   *	US - mm/dd/yyyy
   *	European - dd/mm/yyyy
***************
*** 3296,3306 ****
  	switch (style)
  	{
  		case USE_ISO_DATES:
  			/* Compatible with ISO-8601 date formats */
  
! 			sprintf(str, "%04d-%02d-%02d %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
--- 3298,3315 ----
  	switch (style)
  	{
  		case USE_ISO_DATES:
+ 		case USE_XSD_DATES:
  			/* Compatible with ISO-8601 date formats */
  
! 			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_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
*** ./src/backend/utils/adt/xml.c.orig	2007-02-19 19:37:27.000000000 +0100
--- ./src/backend/utils/adt/xml.c	2007-02-19 22:33:11.000000000 +0100
***************
*** 65,73 ****
  #include "utils/builtins.h"
  #include "utils/lsyscache.h"
  #include "utils/memutils.h"
  #include "utils/xml.h"
  
- 
  #ifdef USE_LIBXML
  
  static StringInfo xml_err_buf = NULL;
--- 65,74 ----
  #include "utils/builtins.h"
  #include "utils/lsyscache.h"
  #include "utils/memutils.h"
+ #include "utils/date.h"
+ #include "utils/datetime.h"
  #include "utils/xml.h"
  
  #ifdef USE_LIBXML
  
  static StringInfo xml_err_buf = NULL;
***************
*** 1513,1526 ****
  		bool isvarlena;
  		char *p, *str;
  
! 		if (type == BOOLOID)
  		{
! 			if (DatumGetBool(value))
! 				return "true";
! 			else
! 				return "false";
! 		}
  
  		getTypeOutputInfo(type, &typeOut, &isvarlena);
  		str = OidOutputFunctionCall(typeOut, value);
  
--- 1514,1595 ----
  		bool isvarlena;
  		char *p, *str;
  
! 		/* xsd format doesn't depend on current settings */
! 		switch (type)
  		{
! 			case BOOLOID:
! 				if (DatumGetBool(value))
! 					return "true";
! 				else
! 					return "false";
! 			case DATEOID:
! 			{
!     				struct pg_tm tt,
!                     			   *tm = &tt;
!     				char            buf[MAXDATELEN + 1];
! 				DateADT 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 TIMEOID:
! 				/* datestyle hasn't affect on time formating */
! 				break;
! 
! 			case TIMESTAMPOID:
! 			{
! 			        Timestamp       timestamp = DatumGetTimestamp(value);
!     				struct pg_tm tt,
!                         		    *tm = &tt;
!     				fsec_t          fsec;
!     				char       *tzn = NULL;
!     				char            buf[MAXDATELEN + 1];
!                                                           
! 				/* 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       dt = DatumGetTimestamp(value);
+     				struct pg_tm tt,
+ 	                    		    *tm = &tt;
+ 				int			tz;
+     				fsec_t          fsec;
+     				char       *tzn = NULL;
+     				char            buf[MAXDATELEN + 1];
+ 
+ 				/* xsd doesn't support infinite values */
+     				if (TIMESTAMP_NOT_FINITE(dt))
+             				ereport(ERROR,
+                             			(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+                                 		errmsg("timestamp out of range")));            				
+     				else if (timestamp2tm(dt, &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);
  		str = OidOutputFunctionCall(typeOut, value);
  
*** ./src/include/miscadmin.h.orig	2007-02-19 21:44:41.000000000 +0100
--- ./src/include/miscadmin.h	2007-02-19 21:45:31.000000000 +0100
***************
*** 178,183 ****
--- 178,184 ----
  #define USE_ISO_DATES			1
  #define USE_SQL_DATES			2
  #define USE_GERMAN_DATES		3
+ #define USE_XSD_DATES			4
  
  /* valid DateOrder values */
  #define DATEORDER_YMD			0
*** ./src/test/regress/expected/xml.out.orig	2007-02-19 23:36:47.000000000 +0100
--- ./src/test/regress/expected/xml.out	2007-02-19 23:35:28.000000000 +0100
***************
*** 151,156 ****
--- 151,177 ----
   <foo>626172</foo>
  (1 row)
  
+ -- check independency and correct formating for date, time and timestamp types
+ SET DateStyle = 'German';
+ SELECT xmlelement(name foo, date  '19.02.2007');
+       xmlelement       
+ -----------------------
+  <foo>2007-02-19</foo>
+ (1 row)
+ 
+ SELECT xmlelement(name foo, timestamp with time zone '19.02.2007 23:30:06.789+01');
+               xmlelement               
+ ---------------------------------------
+  <foo>2007-02-19T14:30:06.789-08</foo>
+ (1 row)
+ 
+ SELECT xmlelement(name foo, timestamp without time zone '19.02.2007 23:30:06.789');
+              xmlelement             
+ ------------------------------------
+  <foo>2007-02-19T23:30:06.789</foo>
+ (1 row)
+ 
+ SET DATESTYLE TO DEFAULT;
  SELECT xmlparse(content 'abc');
   xmlparse 
  ----------

---------------------------(end of broadcast)---------------------------
TIP 7: You can help support the PostgreSQL project by donating at

                http://www.postgresql.org/about/donate

Reply via email to