Datetime input-parsing shortcoming

Started by Tom Lanealmost 27 years ago2 messages
#1Tom Lane
tgl@sss.pgh.pa.us

Seen with current sources and with 6.4.2:

When datestyle = 'Postgres,European', the datetime parser will accept
dates written in either US or Euro order:

regression=> set datestyle = 'Postgres,European';
SET VARIABLE
regression=> select 'Wed 06 Jan 16:10:00 1999 EST'::datetime;
?column?
----------------------------
Wed 06 Jan 16:10:00 1999 EST
(1 row)

regression=> select 'Wed Jan 06 16:10:00 1999 EST'::datetime;
?column?
----------------------------
Wed 06 Jan 16:10:00 1999 EST
(1 row)

But when datestyle = 'Postgres,US' it won't:

regression=> set datestyle = 'Postgres,US';
SET VARIABLE
regression=> select 'Wed Jan 06 16:10:00 1999 EST'::datetime;
?column?
----------------------------
Wed Jan 06 16:10:00 1999 EST
(1 row)
regression=> select 'Wed 06 Jan 16:10:00 1999 EST'::datetime;
ERROR: Bad datetime external representation 'Wed 06 Jan 16:10:00 1999 EST'

A bug, no??

regards, tom lane

#2Thomas G. Lockhart
lockhart@alumni.caltech.edu
In reply to: Tom Lane (#1)
1 attachment(s)
Re: [HACKERS] Datetime input-parsing shortcoming

Seen with current sources and with 6.4.2:
When datestyle = 'Postgres,European', the datetime parser will accept
dates written in either US or Euro order:
But when datestyle = 'Postgres,US' it won't:
regression=> select 'Wed 06 Jan 16:10:00 1999 EST'::datetime;
ERROR: Bad datetime external representation
A bug, no??

Si, though I would prefer to think of it as a "feature omission" since
it would have accepted a date sometimes (if the day of month was greater
than 12) :)

postgres=> show DateStyle;
NOTICE: DateStyle is Postgres with US (NonEuropean) conventions
postgres=> select 'Wed 06 Jan 16:10:00 1999 EST'::datetime;
----------------------------
Wed Jan 06 21:10:00 1999 GMT
(1 row)

Will apply to the development tree soon...

- Tom

Attachments:

dt.c.patchtext/plain; charset=us-ascii; name=dt.c.patchDownload
*** dt.c.orig	Sat Jan 23 03:12:23 1999
--- dt.c	Tue Feb  9 14:12:28 1999
***************
*** 2814,2819 ****
--- 2814,2820 ----
  	int			flen,
  				val;
  	int			mer = HR24;
+ 	int			haveTextMonth = FALSE;
  	int			is2digits = FALSE;
  	int			bc = FALSE;
  
***************
*** 2955,2968 ****
  #ifdef DATEDEBUG
  						printf("DecodeDateTime- month field %s value is %d\n", field[i], val);
  #endif
  						tm->tm_mon = val;
  						break;
  
- 						/*
- 						 * daylight savings time modifier (solves "MET
- 						 * DST" syntax)
- 						 */
  					case DTZMOD:
  						tmask |= DTK_M(DTZ);
  						tm->tm_isdst = 1;
  						if (tzp == NULL)
--- 2956,2978 ----
  #ifdef DATEDEBUG
  						printf("DecodeDateTime- month field %s value is %d\n", field[i], val);
  #endif
+ 						/* already have a (numeric) month? then see if we can substitute... */
+ 						if ((fmask & DTK_M(MONTH)) && (! haveTextMonth)
+ 						  && (!(fmask & DTK_M(DAY)))
+ 						  && ((tm->tm_mon >= 1) && (tm->tm_mon <= 31)))
+ 						{
+ 							tm->tm_mday = tm->tm_mon;
+ 							tmask = DTK_M(DAY);
+ #ifdef DATEDEBUG
+ 							printf("DecodeNumber- misidentified month previously; assign as day %d\n", tm->tm_mday);
+ #endif
+ 						}
+ 						haveTextMonth = TRUE;
  						tm->tm_mon = val;
  						break;
  
  					case DTZMOD:
+ 						/* daylight savings time modifier (solves "MET DST" syntax) */
  						tmask |= DTK_M(DTZ);
  						tm->tm_isdst = 1;
  						if (tzp == NULL)
***************
*** 3466,3482 ****
  		*tmask = DTK_M(YEAR);
  
  		/* already have a year? then see if we can substitute... */
! 		if (fmask & DTK_M(YEAR))
  		{
! 			if ((!(fmask & DTK_M(DAY)))
! 				&& ((tm->tm_year >= 1) && (tm->tm_year <= 31)))
! 			{
  #ifdef DATEDEBUG
! 				printf("DecodeNumber- misidentified year previously; swap with day %d\n", tm->tm_mday);
  #endif
- 				tm->tm_mday = tm->tm_year;
- 				*tmask = DTK_M(DAY);
- 			}
  		}
  
  		tm->tm_year = val;
--- 3476,3489 ----
  		*tmask = DTK_M(YEAR);
  
  		/* already have a year? then see if we can substitute... */
! 		if ((fmask & DTK_M(YEAR)) && (!(fmask & DTK_M(DAY)))
! 		  && ((tm->tm_year >= 1) && (tm->tm_year <= 31)))
  		{
! 			tm->tm_mday = tm->tm_year;
! 			*tmask = DTK_M(DAY);
  #ifdef DATEDEBUG
! 			printf("DecodeNumber- misidentified year previously; assign as day %d\n", tm->tm_mday);
  #endif
  		}
  
  		tm->tm_year = val;