Index: src/include/utils/datetime.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/datetime.h,v
retrieving revision 1.62
diff -c -r1.62 datetime.h
*** src/include/utils/datetime.h	18 Oct 2006 16:43:14 -0000	1.62
--- src/include/utils/datetime.h	9 Nov 2006 18:52:48 -0000
***************
*** 165,170 ****
--- 165,171 ----
  #define DTK_DOY			33
  #define DTK_TZ_HOUR		34
  #define DTK_TZ_MINUTE	35
+ #define DTK_ISOYEAR		36
  
  
  /*
Index: src/include/utils/timestamp.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/timestamp.h,v
retrieving revision 1.64
diff -c -r1.64 timestamp.h
*** src/include/utils/timestamp.h	4 Oct 2006 00:30:11 -0000	1.64
--- src/include/utils/timestamp.h	9 Nov 2006 18:52:48 -0000
***************
*** 325,332 ****
  /* timestamp comparison works for timestamptz also */
  #define timestamptz_cmp_internal(dt1,dt2)	timestamp_cmp_internal(dt1, dt2)
  
! extern void isoweek2date(int woy, int *year, int *mon, int *mday);
  extern int	date2isoweek(int year, int mon, int mday);
  extern int	date2isoyear(int year, int mon, int mday);
  
  #endif   /* TIMESTAMP_H */
--- 325,335 ----
  /* timestamp comparison works for timestamptz also */
  #define timestamptz_cmp_internal(dt1,dt2)	timestamp_cmp_internal(dt1, dt2)
  
! extern int	isoweek2j(int year, int week);
! extern void	isoweek2date(int woy, int *year, int *mon, int *mday);
! extern void	isoweekdate2date(int isoweek, int isowday, int *year, int *mon, int *mday);
  extern int	date2isoweek(int year, int mon, int mday);
  extern int	date2isoyear(int year, int mon, int mday);
+ extern int	date2isoyearday(int year, int mon, int mday);
  
  #endif   /* TIMESTAMP_H */
Index: src/interfaces/ecpg/pgtypeslib/dt.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/interfaces/ecpg/pgtypeslib/dt.h,v
retrieving revision 1.34
diff -c -r1.34 dt.h
*** src/interfaces/ecpg/pgtypeslib/dt.h	11 Mar 2006 04:38:39 -0000	1.34
--- src/interfaces/ecpg/pgtypeslib/dt.h	9 Nov 2006 18:52:48 -0000
***************
*** 157,162 ****
--- 157,163 ----
  #define DTK_DOY			33
  #define DTK_TZ_HOUR		34
  #define DTK_TZ_MINUTE	35
+ #define DTK_ISOYEAR		36
  
  
  /*
Index: src/backend/utils/adt/datetime.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/datetime.c,v
retrieving revision 1.174
diff -c -r1.174 datetime.c
*** src/backend/utils/adt/datetime.c	18 Oct 2006 16:43:13 -0000	1.174
--- src/backend/utils/adt/datetime.c	9 Nov 2006 18:52:49 -0000
***************
*** 125,130 ****
--- 125,131 ----
  	{"h", UNITS, DTK_HOUR},		/* "hour" */
  	{LATE, RESERV, DTK_LATE},	/* "infinity" reserved for "late time" */
  	{INVALID, RESERV, DTK_INVALID},		/* "invalid" reserved for bad time */
+ 	{"isoyear", UNITS, DTK_ISOYEAR},	/* year in terms of the ISO week date */
  	{"j", UNITS, DTK_JULIAN},
  	{"jan", MONTH, 1},
  	{"january", MONTH, 1},
Index: src/backend/utils/adt/timestamp.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v
retrieving revision 1.168
diff -c -r1.168 timestamp.c
*** src/backend/utils/adt/timestamp.c	4 Oct 2006 00:29:59 -0000	1.168
--- src/backend/utils/adt/timestamp.c	9 Nov 2006 18:52:50 -0000
***************
*** 3498,3529 ****
  	PG_RETURN_INTERVAL_P(result);
  }
  
! /* isoweek2date()
!  * Convert ISO week of year number to date.
!  * The year field must be specified with the ISO year!
!  * karel 2000/08/07
   */
! void
! isoweek2date(int woy, int *year, int *mon, int *mday)
  {
  	int			day0,
! 				day4,
! 				dayn;
  
! 	if (!*year)
  		ereport(ERROR,
  				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
  		   errmsg("cannot calculate week number without year information")));
  
  	/* fourth day of current year */
! 	day4 = date2j(*year, 1, 4);
  
  	/* day0 == offset to first day of week (Monday) */
  	day0 = j2day(day4 - 1);
  
! 	dayn = ((woy - 1) * 7) + (day4 - day0);
  
! 	j2date(dayn, year, mon, mday);
  }
  
  /* date2isoweek()
--- 3498,3554 ----
  	PG_RETURN_INTERVAL_P(result);
  }
  
! /* isoweek2j()
!  *
!  * 	Return the Julian day which corresponds to the first day (Monday) of the given ISO 8601 year and week.
!  * 	Julian days are used to convert between ISO week dates and Gregorian dates.
   */
! int
! isoweek2j(int year, int week)
  {
  	int			day0,
! 				day4;
  
! 	if (!year)
  		ereport(ERROR,
  				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
  		   errmsg("cannot calculate week number without year information")));
  
  	/* fourth day of current year */
! 	day4 = date2j(year, 1, 4);
  
  	/* day0 == offset to first day of week (Monday) */
  	day0 = j2day(day4 - 1);
  
! 	return ((week - 1) * 7) + (day4 - day0);
! }
! 
! /* isoweek2date()
!  * Convert ISO week of year number to date.
!  * The year field must be specified with the ISO year!
!  * karel 2000/08/07
!  */
! void
! isoweek2date(int woy, int *year, int *mon, int *mday)
! {
! 	j2date(isoweek2j(*year, woy), year, mon, mday);
! }
! 
! /* isoweekdate2date()
!  *
!  * 	Convert an ISO 8601 week date (ISO year, ISO week and day of week) into a Gregorian date.
!  * 	Populates year, mon, and mday with the correct Gregorian values.
!  * 	year must be passed in as the ISO year.
!  */
! void
! isoweekdate2date(int isoweek, int isowday, int *year, int *mon, int *mday)
! {
! 	int jday;
! 
! 	jday = isoweek2j(*year, isoweek);
! 	jday += isowday - 1;
  
! 	j2date(jday, year, mon, mday);
  }
  
  /* date2isoweek()
***************
*** 3636,3641 ****
--- 3661,3677 ----
  }
  
  
+ /* date2isoyearday()
+  *
+  * 	Returns the ISO 8601 day-of-year, given a Gregorian year, month and day.
+  * 	Possible return values are 1 through 371 (364 in non-leap years).
+  */
+ int
+ date2isoyearday(int year, int mon, int mday)
+ {
+ 	return date2j(year, mon, mday) - isoweek2j(date2isoyear(year, mon, mday), 1) + 1;
+ }
+ 
  /* timestamp_part()
   * Extract specified field from timestamp.
   */
***************
*** 3778,3783 ****
--- 3814,3823 ----
  #endif
  				break;
  
+ 			case DTK_ISOYEAR:
+ 				result = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday);
+ 				break;
+ 
  			case DTK_TZ:
  			case DTK_TZ_MINUTE:
  			case DTK_TZ_HOUR:
***************
*** 4005,4010 ****
--- 4045,4054 ----
  #endif
  				break;
  
+ 			case DTK_ISOYEAR:
+ 				result = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday);
+ 				break;
+ 
  			default:
  				ereport(ERROR,
  						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
Index: src/backend/utils/adt/date.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/date.c,v
retrieving revision 1.125
diff -c -r1.125 date.c
*** src/backend/utils/adt/date.c	14 Jul 2006 14:52:23 -0000	1.125
--- src/backend/utils/adt/date.c	9 Nov 2006 18:52:50 -0000
***************
*** 1677,1682 ****
--- 1677,1683 ----
  			case DTK_DECADE:
  			case DTK_CENTURY:
  			case DTK_MILLENNIUM:
+ 			case DTK_ISOYEAR:
  			default:
  				ereport(ERROR,
  						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
Index: src/backend/utils/adt/formatting.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/formatting.c,v
retrieving revision 1.113
diff -c -r1.113 formatting.c
*** src/backend/utils/adt/formatting.c	4 Oct 2006 00:29:59 -0000	1.113
--- src/backend/utils/adt/formatting.c	9 Nov 2006 18:52:51 -0000
***************
*** 378,383 ****
--- 378,384 ----
  				ddd,
  				mm,
  				ms,
+ 				iyear,
  				year,
  				bc,
  				iw,
***************
*** 527,533 ****
   * position or -1 if char is not used in the KeyWord. Search example for
   * string "MM":
   *	1)	see in index to index['M' - 32],
!  *	2)	take keywords position (enum DCH_MM) from index
   *	3)	run sequential search in keywords[] from this position
   *
   * ----------
--- 528,534 ----
   * position or -1 if char is not used in the KeyWord. Search example for
   * string "MM":
   *	1)	see in index to index['M' - 32],
!  *	2)	take keywords position (enum DCH_MI) from index
   *	3)	run sequential search in keywords[] from this position
   *
   * ----------
***************
*** 553,558 ****
--- 554,561 ----
  	DCH_HH24,
  	DCH_HH12,
  	DCH_HH,
+ 	DCH_IDDD,
+ 	DCH_ID,
  	DCH_IW,
  	DCH_IYYY,
  	DCH_IYY,
***************
*** 597,602 ****
--- 600,607 ----
  	DCH_hh24,
  	DCH_hh12,
  	DCH_hh,
+ 	DCH_iddd,
+ 	DCH_id,
  	DCH_iw,
  	DCH_iyyy,
  	DCH_iyy,
***************
*** 695,707 ****
  	{"HH24", 4, dch_time, DCH_HH24, TRUE},		/* H */
  	{"HH12", 4, dch_time, DCH_HH12, TRUE},
  	{"HH", 2, dch_time, DCH_HH, TRUE},
! 	{"IW", 2, dch_date, DCH_IW, TRUE},	/* I */
  	{"IYYY", 4, dch_date, DCH_IYYY, TRUE},
  	{"IYY", 3, dch_date, DCH_IYY, TRUE},
  	{"IY", 2, dch_date, DCH_IY, TRUE},
  	{"I", 1, dch_date, DCH_I, TRUE},
  	{"J", 1, dch_date, DCH_J, TRUE},	/* J */
! 	{"MI", 2, dch_time, DCH_MI, TRUE},
  	{"MM", 2, dch_date, DCH_MM, TRUE},
  	{"MONTH", 5, dch_date, DCH_MONTH, FALSE},
  	{"MON", 3, dch_date, DCH_MON, FALSE},
--- 700,714 ----
  	{"HH24", 4, dch_time, DCH_HH24, TRUE},		/* H */
  	{"HH12", 4, dch_time, DCH_HH12, TRUE},
  	{"HH", 2, dch_time, DCH_HH, TRUE},
! 	{"IDDD", 4, dch_date, DCH_IDDD, TRUE},	/* I */
! 	{"ID", 2, dch_date, DCH_ID, TRUE},
! 	{"IW", 2, dch_date, DCH_IW, TRUE},
  	{"IYYY", 4, dch_date, DCH_IYYY, TRUE},
  	{"IYY", 3, dch_date, DCH_IYY, TRUE},
  	{"IY", 2, dch_date, DCH_IY, TRUE},
  	{"I", 1, dch_date, DCH_I, TRUE},
  	{"J", 1, dch_date, DCH_J, TRUE},	/* J */
! 	{"MI", 2, dch_time, DCH_MI, TRUE},	/* M */
  	{"MM", 2, dch_date, DCH_MM, TRUE},
  	{"MONTH", 5, dch_date, DCH_MONTH, FALSE},
  	{"MON", 3, dch_date, DCH_MON, FALSE},
***************
*** 739,745 ****
  	{"hh24", 4, dch_time, DCH_HH24, TRUE},		/* h */
  	{"hh12", 4, dch_time, DCH_HH12, TRUE},
  	{"hh", 2, dch_time, DCH_HH, TRUE},
! 	{"iw", 2, dch_date, DCH_IW, TRUE},	/* i */
  	{"iyyy", 4, dch_date, DCH_IYYY, TRUE},
  	{"iyy", 3, dch_date, DCH_IYY, TRUE},
  	{"iy", 2, dch_date, DCH_IY, TRUE},
--- 746,754 ----
  	{"hh24", 4, dch_time, DCH_HH24, TRUE},		/* h */
  	{"hh12", 4, dch_time, DCH_HH12, TRUE},
  	{"hh", 2, dch_time, DCH_HH, TRUE},
! 	{"iddd", 4, dch_date, DCH_IDDD, TRUE},	/* i */
! 	{"id", 2, dch_date, DCH_ID, TRUE},
! 	{"iw", 2, dch_date, DCH_IW, TRUE},
  	{"iyyy", 4, dch_date, DCH_IYYY, TRUE},
  	{"iyy", 3, dch_date, DCH_IYY, TRUE},
  	{"iy", 2, dch_date, DCH_IY, TRUE},
***************
*** 829,838 ****
  	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  	-1, -1, -1, -1, -1, DCH_A_D, DCH_B_C, DCH_CC, DCH_DAY, -1,
! 	DCH_FX, -1, DCH_HH24, DCH_IW, DCH_J, -1, -1, DCH_MI, -1, -1,
  	DCH_P_M, DCH_Q, DCH_RM, DCH_SSSS, DCH_TZ, DCH_US, -1, DCH_WW, -1, DCH_Y_YYY,
  	-1, -1, -1, -1, -1, -1, -1, DCH_a_d, DCH_b_c, DCH_cc,
! 	DCH_day, -1, DCH_fx, -1, DCH_hh24, DCH_iw, DCH_j, -1, -1, DCH_mi,
  	-1, -1, DCH_p_m, DCH_q, DCH_rm, DCH_ssss, DCH_tz, DCH_us, -1, DCH_ww,
  	-1, DCH_y_yyy, -1, -1, -1, -1
  
--- 838,847 ----
  	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  	-1, -1, -1, -1, -1, DCH_A_D, DCH_B_C, DCH_CC, DCH_DAY, -1,
! 	DCH_FX, -1, DCH_HH24, DCH_IDDD, DCH_J, -1, -1, DCH_MI, -1, -1,
  	DCH_P_M, DCH_Q, DCH_RM, DCH_SSSS, DCH_TZ, DCH_US, -1, DCH_WW, -1, DCH_Y_YYY,
  	-1, -1, -1, -1, -1, -1, -1, DCH_a_d, DCH_b_c, DCH_cc,
! 	DCH_day, -1, DCH_fx, -1, DCH_hh24, DCH_iddd, DCH_j, -1, -1, DCH_mi,
  	-1, -1, DCH_p_m, DCH_q, DCH_rm, DCH_ssss, DCH_tz, DCH_us, -1, DCH_ww,
  	-1, DCH_y_yyy, -1, -1, -1, -1
  
***************
*** 2323,2331 ****
  			return strlen(p_inout);
  
  		case DCH_DDD:
  			if (is_to_char)
  			{
! 				sprintf(inout, "%0*d", S_FM(suf) ? 0 : 3, tm->tm_yday);
  				if (S_THth(suf))
  					str_numth(p_inout, inout, S_TH_TYPE(suf));
  				return strlen(p_inout);
--- 2332,2344 ----
  			return strlen(p_inout);
  
  		case DCH_DDD:
+ 		case DCH_IDDD:
  			if (is_to_char)
  			{
! 				sprintf(inout, "%0*d", S_FM(suf) ? 0 : 3, 
! 					(arg == DCH_DDD) ? 
! 					tm->tm_yday :
! 					date2isoyearday(tm->tm_year, tm->tm_mon, tm->tm_mday));
  				if (S_THth(suf))
  					str_numth(p_inout, inout, S_TH_TYPE(suf));
  				return strlen(p_inout);
***************
*** 2367,2376 ****
  			}
  			break;
  		case DCH_D:
  			INVALID_FOR_INTERVAL;
  			if (is_to_char)
  			{
! 				sprintf(inout, "%d", tm->tm_wday + 1);
  				if (S_THth(suf))
  					str_numth(p_inout, inout, S_TH_TYPE(suf));
  				return strlen(p_inout);
--- 2380,2393 ----
  			}
  			break;
  		case DCH_D:
+ 		case DCH_ID:
  			INVALID_FOR_INTERVAL;
  			if (is_to_char)
  			{
! 				if (arg == DCH_D)
! 					sprintf(inout, "%d", tm->tm_wday + 1);
! 				else
! 					sprintf(inout, "%d", (tm->tm_wday == 0) ? 7 : tm->tm_wday);
  				if (S_THth(suf))
  					str_numth(p_inout, inout, S_TH_TYPE(suf));
  				return strlen(p_inout);
***************
*** 2378,2383 ****
--- 2395,2403 ----
  			else
  			{
  				sscanf(inout, "%1d", &tmfc->d);
+ 				if (arg == DCH_D)
+ 					tmfc->d -= 1;
+ 
  				return strspace_len(inout) + 1 + SKIP_THth(suf);
  			}
  			break;
***************
*** 2515,2529 ****
  			}
  			else
  			{
  				if (S_FM(suf) || is_next_separator(node))
  				{
! 					sscanf(inout, "%d", &tmfc->year);
  					tmfc->yysz = 4;
  					return strdigits_len(inout) + SKIP_THth(suf);
  				}
  				else
  				{
! 					sscanf(inout, "%04d", &tmfc->year);
  					tmfc->yysz = 4;
  					return strspace_len(inout) + 4 + SKIP_THth(suf);
  				}
--- 2535,2552 ----
  			}
  			else
  			{
+ 				int *field;
+ 				field = (arg == DCH_YYYY) ? &tmfc->year : &tmfc->iyear;
+ 
  				if (S_FM(suf) || is_next_separator(node))
  				{
! 					sscanf(inout, "%d", field);
  					tmfc->yysz = 4;
  					return strdigits_len(inout) + SKIP_THth(suf);
  				}
  				else
  				{
! 					sscanf(inout, "%04d", field);
  					tmfc->yysz = 4;
  					return strspace_len(inout) + 4 + SKIP_THth(suf);
  				}
***************
*** 2547,2562 ****
  			}
  			else
  			{
! 				sscanf(inout, "%03d", &tmfc->year);
  
  				/*
  				 * 3-digit year: '100' ... '999' = 1100 ... 1999 '000' ...
  				 * '099' = 2000 ... 2099
  				 */
! 				if (tmfc->year >= 100)
! 					tmfc->year += 1000;
  				else
! 					tmfc->year += 2000;
  				tmfc->yysz = 3;
  				return strspace_len(inout) + 3 + SKIP_THth(suf);
  			}
--- 2570,2588 ----
  			}
  			else
  			{
! 				int *field;
! 				field = (arg == DCH_YYY) ? &tmfc->year : &tmfc->iyear;
! 
! 				sscanf(inout, "%03d", field);
  
  				/*
  				 * 3-digit year: '100' ... '999' = 1100 ... 1999 '000' ...
  				 * '099' = 2000 ... 2099
  				 */
! 				if (*field >= 100)
! 					*field += 1000;
  				else
! 					*field += 2000;
  				tmfc->yysz = 3;
  				return strspace_len(inout) + 3 + SKIP_THth(suf);
  			}
***************
*** 2579,2594 ****
  			}
  			else
  			{
! 				sscanf(inout, "%02d", &tmfc->year);
  
  				/*
  				 * 2-digit year: '00' ... '69'	= 2000 ... 2069 '70' ... '99'
  				 * = 1970 ... 1999
  				 */
! 				if (tmfc->year < 70)
! 					tmfc->year += 2000;
  				else
! 					tmfc->year += 1900;
  				tmfc->yysz = 2;
  				return strspace_len(inout) + 2 + SKIP_THth(suf);
  			}
--- 2605,2623 ----
  			}
  			else
  			{
! 				int *field;
! 				field = (arg == DCH_YY) ? &tmfc->year : &tmfc->iyear;
! 
! 				sscanf(inout, "%02d", field);
  
  				/*
  				 * 2-digit year: '00' ... '69'	= 2000 ... 2069 '70' ... '99'
  				 * = 1970 ... 1999
  				 */
! 				if (*field < 70)
! 					*field += 2000;
  				else
! 					*field += 1900;
  				tmfc->yysz = 2;
  				return strspace_len(inout) + 2 + SKIP_THth(suf);
  			}
***************
*** 2611,2622 ****
  			}
  			else
  			{
! 				sscanf(inout, "%1d", &tmfc->year);
  
  				/*
  				 * 1-digit year: always +2000
  				 */
! 				tmfc->year += 2000;
  				tmfc->yysz = 1;
  				return strspace_len(inout) + 1 + SKIP_THth(suf);
  			}
--- 2640,2654 ----
  			}
  			else
  			{
! 				int *field;
! 				field = (arg == DCH_Y) ? &tmfc->year : &tmfc->iyear;
! 
! 				sscanf(inout, "%1d", field);
  
  				/*
  				 * 1-digit year: always +2000
  				 */
! 				*field += 2000;
  				tmfc->yysz = 1;
  				return strspace_len(inout) + 1 + SKIP_THth(suf);
  			}
***************
*** 3187,3193 ****
  {
  	FormatNode *format;
  	TmFromChar	tmfc;
! 	int			fmt_len;
  
  	ZERO_tm(tm);
  	*fsec = 0;
--- 3219,3226 ----
  {
  	FormatNode *format;
  	TmFromChar	tmfc;
! 	int			fmt_len,
! 				year;
  
  	ZERO_tm(tm);
  	*fsec = 0;
***************
*** 3340,3364 ****
  			break;
  	}
  
! 	if (tmfc.year)
  	{
  		if (tmfc.yysz == 2 && tmfc.cc)
  		{
  			/*
  			 * CC and YY defined why -[2000|1900]? See dch_date() DCH_YY code.
  			 */
! 			tm->tm_year = (tmfc.cc - 1) * 100 + (tmfc.year >= 2000 ? tmfc.year - 2000 : tmfc.year - 1900);
  		}
  		else if (tmfc.yysz == 1 && tmfc.cc)
  		{
  			/*
  			 * CC and Y defined
  			 */
! 			tm->tm_year = (tmfc.cc - 1) * 100 + tmfc.year - 2000;
  		}
  		else
  			/* set year (and ignore CC if defined) */
! 			tm->tm_year = tmfc.year;
  	}
  	if (tmfc.bc)
  	{
--- 3373,3403 ----
  			break;
  	}
  
! 	/*
! 	 * Only one year value is used.  If iyear (the ISO year) is defined, it takes precedence.  
! 	 * Otherwise year (the Gregorian year) is used.
! 	 */
! 	year = (tmfc.iyear) ? tmfc.iyear : tmfc.year;
! 
! 	if (year)
  	{
  		if (tmfc.yysz == 2 && tmfc.cc)
  		{
  			/*
  			 * CC and YY defined why -[2000|1900]? See dch_date() DCH_YY code.
  			 */
! 			tm->tm_year = (tmfc.cc - 1) * 100 + (year >= 2000 ? year - 2000 : year - 1900);
  		}
  		else if (tmfc.yysz == 1 && tmfc.cc)
  		{
  			/*
  			 * CC and Y defined
  			 */
! 			tm->tm_year = (tmfc.cc - 1) * 100 + year - 2000;
  		}
  		else
  			/* set year (and ignore CC if defined) */
! 			tm->tm_year = year;
  	}
  	if (tmfc.bc)
  	{
***************
*** 3375,3422 ****
  		j2date(tmfc.j, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
  
  	if (tmfc.iw)
! 		isoweek2date(tmfc.iw, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
  
  	if (tmfc.d)
  		tm->tm_wday = tmfc.d;
  	if (tmfc.dd)
  		tm->tm_mday = tmfc.dd;
! 	if (tmfc.ddd)
  		tm->tm_yday = tmfc.ddd;
  	if (tmfc.mm)
  		tm->tm_mon = tmfc.mm;
  
- 	/*
- 	 * we don't ignore DDD
- 	 */
  	if (tmfc.ddd && (tm->tm_mon <= 1 || tm->tm_mday <= 1))
  	{
! 		/* count mday and mon from yday */
! 		int		   *y,
! 					i;
! 
! 		int			ysum[2][13] = {
! 			{31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 0},
! 		{31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366, 0}};
  
! 		if (!tm->tm_year)
! 			ereport(ERROR,
! 					(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
! 			errmsg("cannot calculate day of year without year information")));
  
! 		y = ysum[isleap(tm->tm_year)];
  
! 		for (i = 0; i <= 11; i++)
! 		{
! 			if (tm->tm_yday < y[i])
! 				break;
! 		}
! 		if (tm->tm_mon <= 1)
! 			tm->tm_mon = i + 1;
  
! 		if (tm->tm_mday <= 1)
! 			tm->tm_mday = i == 0 ? tm->tm_yday :
! 				tm->tm_yday - y[i - 1];
  	}
  
  #ifdef HAVE_INT64_TIMESTAMP
--- 3414,3491 ----
  		j2date(tmfc.j, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
  
  	if (tmfc.iw)
! 	{
! 		/* 
! 		 * Since the user has employed the IW field, it is assumed that the value in tmfc.d 
! 		 * is in ISO day-of-week form (1 = Monday), as set by the ID field.  Mixing IW and D 
! 		 * will yield weird results.
! 		 *
! 		 * tmfc.iyear must have been set (e.g., with IYYY) for this to work properly (an ISO week
! 		 * without an ISO year is meaningless).
! 		 *
! 		 * If tmfc.d is not set, then the date is left at the beginning of the ISO week (Monday).
! 		 */
! 		if (tmfc.d)
! 		{
! 			isoweekdate2date(tmfc.iw, tmfc.d, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
! 		}
! 		else
! 			isoweek2date(tmfc.iw, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
! 	}
! 
  
  	if (tmfc.d)
  		tm->tm_wday = tmfc.d;
  	if (tmfc.dd)
  		tm->tm_mday = tmfc.dd;
! 	if (tmfc.ddd && !tmfc.iyear)
  		tm->tm_yday = tmfc.ddd;
  	if (tmfc.mm)
  		tm->tm_mon = tmfc.mm;
  
  	if (tmfc.ddd && (tm->tm_mon <= 1 || tm->tm_mday <= 1))
  	{
! 		/*
! 		 * If the iyear field is set, the value of ddd is taken to be an ISO day-of-year.
! 		 * Otherwise, it is a Gregorian day-of-year.
! 		 * Either way, since the month and day fields have not been set by some other means,
! 		 * the value of ddd will be used to compute them.
! 		 */
! 		if (tmfc.iyear)
! 		{
! 			int j0;		// zeroth day of the ISO year, in Julian
! 			j0 = isoweek2j(tmfc.iyear, 1) - 1;
  
! 			j2date(j0 + tmfc.ddd, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
! 		}
! 		else
! 		{
! 			int		   *y,
! 						i;
  
! 			int			ysum[2][13] = {
! 				{31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 0},
! 			{31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366, 0}};
  
! 			if (!tm->tm_year)
! 				ereport(ERROR,
! 						(errcode(ERRCODE_INVALID_DATETIME_FORMAT),
! 				errmsg("cannot calculate day of year without year information")));
  
! 			y = ysum[isleap(tm->tm_year)];
! 
! 			for (i = 0; i <= 11; i++)
! 			{
! 				if (tm->tm_yday < y[i])
! 					break;
! 			}
! 			if (tm->tm_mon <= 1)
! 				tm->tm_mon = i + 1;
! 
! 			if (tm->tm_mday <= 1)
! 				tm->tm_mday = i == 0 ? tm->tm_yday :
! 					tm->tm_yday - y[i - 1];
! 		}
  	}
  
  #ifdef HAVE_INT64_TIMESTAMP
Index: src/test/regress/sql/timestamp.sql
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/sql/timestamp.sql,v
retrieving revision 1.17
diff -c -r1.17 timestamp.sql
*** src/test/regress/sql/timestamp.sql	17 Oct 2006 21:03:21 -0000	1.17
--- src/test/regress/sql/timestamp.sql	9 Nov 2006 18:52:51 -0000
***************
*** 171,176 ****
--- 171,181 ----
     date_part( 'usec', d1) AS usec
     FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01';
  
+ SELECT '' AS "54", d1 as "timestamp",
+    date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week,
+    date_part( 'dow', d1) AS dow
+    FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01';
+ 
  -- TO_CHAR()
  SELECT '' AS to_char_1, to_char(d1, 'DAY Day day DY Dy dy MONTH Month month RM MON Mon mon') 
     FROM TIMESTAMP_TBL;
***************
*** 199,204 ****
--- 204,215 ----
  SELECT '' AS to_char_9, to_char(d1, 'YYYY A.D. YYYY a.d. YYYY bc HH:MI:SS P.M. HH:MI:SS p.m. HH:MI:SS pm') 
     FROM TIMESTAMP_TBL;   
  
+ SELECT '' AS to_char_10, to_char(d1, 'IYYY IYY IY I IW IDDD ID')
+    FROM TIMESTAMP_TBL;
+ 
+ SELECT '' AS to_char_11, to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID')
+    FROM TIMESTAMP_TBL;
+ 
  -- TO_TIMESTAMP()
  SELECT '' AS to_timestamp_1, to_timestamp('0097/Feb/16 --> 08:14:30', 'YYYY/Mon/DD --> HH:MI:SS');
  
***************
*** 230,233 ****
--- 241,258 ----
  
  SELECT '' AS to_timestamp_14, to_timestamp('995-1116', 'YYY-MMDD');
  
+ SELECT '' AS to_timestamp_15, to_timestamp('2005426', 'YYYYWWD');
+ 
+ SELECT '' AS to_timestamp_16, to_timestamp('2005300', 'YYYYDDD');
+ 
+ SELECT '' AS to_timestamp_17, to_timestamp('2005527', 'IYYYIWID');
+ 
+ SELECT '' AS to_timestamp_18, to_timestamp('005527', 'IYYIWID');
+ 
+ SELECT '' AS to_timestamp_19, to_timestamp('05527', 'IYIWID');
+ 
+ SELECT '' AS to_timestamp_20, to_timestamp('5527', 'IIWID');
+ 
+ SELECT '' AS to_timestamp_21, to_timestamp('2005364', 'IYYYIDDD');
+ 
  SET DateStyle TO DEFAULT;
Index: src/test/regress/sql/timestamptz.sql
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/sql/timestamptz.sql,v
retrieving revision 1.10
diff -c -r1.10 timestamptz.sql
*** src/test/regress/sql/timestamptz.sql	17 Oct 2006 21:03:21 -0000	1.10
--- src/test/regress/sql/timestamptz.sql	9 Nov 2006 18:52:52 -0000
***************
*** 169,174 ****
--- 169,179 ----
     date_part( 'usec', d1) AS usec
     FROM TIMESTAMPTZ_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01';
  
+ SELECT '' AS "54", d1 as "timestamp",
+    date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week,
+    date_part( 'dow', d1) AS dow
+    FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01';
+ 
  -- TO_CHAR()
  SELECT '' AS to_char_1, to_char(d1, 'DAY Day day DY Dy dy MONTH Month month RM MON Mon mon') 
     FROM TIMESTAMPTZ_TBL;
***************
*** 197,204 ****
  SELECT '' AS to_char_9, to_char(d1, 'YYYY A.D. YYYY a.d. YYYY bc HH:MI:SS P.M. HH:MI:SS p.m. HH:MI:SS pm') 
     FROM TIMESTAMPTZ_TBL;   
  
! SELECT '' AS to_char_10, to_char(d1, 'YYYY WW IYYY IYY IY I IW') 
!    FROM TIMESTAMPTZ_TBL;
  
  -- TO_TIMESTAMP()
  SELECT '' AS to_timestamp_1, to_timestamp('0097/Feb/16 --> 08:14:30', 'YYYY/Mon/DD --> HH:MI:SS');
--- 202,212 ----
  SELECT '' AS to_char_9, to_char(d1, 'YYYY A.D. YYYY a.d. YYYY bc HH:MI:SS P.M. HH:MI:SS p.m. HH:MI:SS pm') 
     FROM TIMESTAMPTZ_TBL;   
  
! SELECT '' AS to_char_10, to_char(d1, 'IYYY IYY IY I IW IDDD ID')
!    FROM TIMESTAMP_TBL;
! 
! SELECT '' AS to_char_11, to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID')
!    FROM TIMESTAMP_TBL;
  
  -- TO_TIMESTAMP()
  SELECT '' AS to_timestamp_1, to_timestamp('0097/Feb/16 --> 08:14:30', 'YYYY/Mon/DD --> HH:MI:SS');
***************
*** 231,239 ****
  
  SELECT '' AS to_timestamp_14, to_timestamp('995-1116', 'YYY-MMDD');
  
! SELECT '' AS to_timestamp_15, to_timestamp('200401', 'IYYYIW');
  
! SELECT '' AS to_timestamp_16, to_timestamp('200401', 'YYYYWW');
  
  
  SET DateStyle TO DEFAULT;
--- 239,256 ----
  
  SELECT '' AS to_timestamp_14, to_timestamp('995-1116', 'YYY-MMDD');
  
! SELECT '' AS to_timestamp_15, to_timestamp('2005426', 'YYYYWWD');
! 
! SELECT '' AS to_timestamp_16, to_timestamp('2005300', 'YYYYDDD');
! 
! SELECT '' AS to_timestamp_17, to_timestamp('2005527', 'IYYYIWID');
! 
! SELECT '' AS to_timestamp_18, to_timestamp('005527', 'IYYIWID');
! 
! SELECT '' AS to_timestamp_19, to_timestamp('05527', 'IYIWID');
  
! SELECT '' AS to_timestamp_20, to_timestamp('5527', 'IIWID');
  
+ SELECT '' AS to_timestamp_21, to_timestamp('2005364', 'IYYYIDDD');
  
  SET DateStyle TO DEFAULT;
Index: src/test/regress/expected/timestamp.out
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/expected/timestamp.out,v
retrieving revision 1.31
diff -c -r1.31 timestamp.out
*** src/test/regress/expected/timestamp.out	17 Oct 2006 21:03:21 -0000	1.31
--- src/test/regress/expected/timestamp.out	9 Nov 2006 18:52:52 -0000
***************
*** 703,708 ****
--- 703,771 ----
      | Mon Jan 01 17:32:01 2001    |       1 |  1000 |  1000000
  (55 rows)
  
+ SELECT '' AS "54", d1 as "timestamp",
+    date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week,
+    date_part( 'dow', d1) AS dow
+    FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01';
+  54 |          timestamp          | isoyear | week | dow 
+ ----+-----------------------------+---------+------+-----
+     | Thu Jan 01 00:00:00 1970    |    1970 |    1 |   4
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:02 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01.40 1997 |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01.50 1997 |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01.60 1997 |    1997 |    7 |   1
+     | Thu Jan 02 00:00:00 1997    |    1997 |    1 |   4
+     | Thu Jan 02 03:04:05 1997    |    1997 |    1 |   4
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Tue Jun 10 17:32:01 1997    |    1997 |   24 |   2
+     | Sat Sep 22 18:19:20 2001    |    2001 |   38 |   6
+     | Wed Mar 15 08:14:01 2000    |    2000 |   11 |   3
+     | Wed Mar 15 13:14:02 2000    |    2000 |   11 |   3
+     | Wed Mar 15 12:14:03 2000    |    2000 |   11 |   3
+     | Wed Mar 15 03:14:04 2000    |    2000 |   11 |   3
+     | Wed Mar 15 02:14:05 2000    |    2000 |   11 |   3
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:00 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Tue Jun 10 18:32:01 1997    |    1997 |   24 |   2
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Tue Feb 11 17:32:01 1997    |    1997 |    7 |   2
+     | Wed Feb 12 17:32:01 1997    |    1997 |    7 |   3
+     | Thu Feb 13 17:32:01 1997    |    1997 |    7 |   4
+     | Fri Feb 14 17:32:01 1997    |    1997 |    7 |   5
+     | Sat Feb 15 17:32:01 1997    |    1997 |    7 |   6
+     | Sun Feb 16 17:32:01 1997    |    1997 |    7 |   0
+     | Sun Feb 16 17:32:01 1997    |    1997 |    7 |   0
+     | Wed Feb 28 17:32:01 1996    |    1996 |    9 |   3
+     | Thu Feb 29 17:32:01 1996    |    1996 |    9 |   4
+     | Fri Mar 01 17:32:01 1996    |    1996 |    9 |   5
+     | Mon Dec 30 17:32:01 1996    |    1997 |    1 |   1
+     | Tue Dec 31 17:32:01 1996    |    1997 |    1 |   2
+     | Wed Jan 01 17:32:01 1997    |    1997 |    1 |   3
+     | Fri Feb 28 17:32:01 1997    |    1997 |    9 |   5
+     | Sat Mar 01 17:32:01 1997    |    1997 |    9 |   6
+     | Tue Dec 30 17:32:01 1997    |    1998 |    1 |   2
+     | Wed Dec 31 17:32:01 1997    |    1998 |    1 |   3
+     | Fri Dec 31 17:32:01 1999    |    1999 |   52 |   5
+     | Sat Jan 01 17:32:01 2000    |    1999 |   52 |   6
+     | Sun Dec 31 17:32:01 2000    |    2000 |   52 |   0
+     | Mon Jan 01 17:32:01 2001    |    2001 |    1 |   1
+ (55 rows)
+ 
  -- TO_CHAR()
  SELECT '' AS to_char_1, to_char(d1, 'DAY Day day DY Dy dy MONTH Month month RM MON Mon mon') 
     FROM TIMESTAMP_TBL;
***************
*** 1344,1349 ****
--- 1407,1554 ----
             | 2001 A.D. 2001 a.d. 2001 ad 05:32:01 P.M. 05:32:01 p.m. 05:32:01 pm
  (65 rows)
  
+ SELECT '' AS to_char_10, to_char(d1, 'IYYY IYY IY I IW IDDD ID')
+    FROM TIMESTAMP_TBL;
+  to_char_10 |        to_char         
+ ------------+------------------------
+             | 
+             | 
+             | 1970 970 70 0 01 004 4
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 01 004 4
+             | 1997 997 97 7 01 004 4
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 24 163 2
+             | 2001 001 01 1 38 265 6
+             | 2000 000 00 0 11 073 3
+             | 2000 000 00 0 11 073 3
+             | 2000 000 00 0 11 073 3
+             | 2000 000 00 0 11 073 3
+             | 2000 000 00 0 11 073 3
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 24 163 2
+             | 1997 997 97 7 07 043 1
+             | 1997 997 97 7 07 044 2
+             | 1997 997 97 7 07 045 3
+             | 1997 997 97 7 07 046 4
+             | 1997 997 97 7 07 047 5
+             | 1997 997 97 7 07 048 6
+             | 1997 997 97 7 07 049 7
+             | 0097 097 97 7 07 044 2
+             | 0097 097 97 7 07 048 6
+             | 0597 597 97 7 07 046 4
+             | 1097 097 97 7 07 044 2
+             | 1697 697 97 7 07 048 6
+             | 1797 797 97 7 07 046 4
+             | 1897 897 97 7 07 044 2
+             | 1997 997 97 7 07 049 7
+             | 2097 097 97 7 07 048 6
+             | 1996 996 96 6 09 059 3
+             | 1996 996 96 6 09 060 4
+             | 1996 996 96 6 09 061 5
+             | 1997 997 97 7 01 001 1
+             | 1997 997 97 7 01 002 2
+             | 1997 997 97 7 01 003 3
+             | 1997 997 97 7 09 061 5
+             | 1997 997 97 7 09 062 6
+             | 1998 998 98 8 01 002 2
+             | 1998 998 98 8 01 003 3
+             | 1999 999 99 9 52 362 5
+             | 1999 999 99 9 52 363 6
+             | 2000 000 00 0 52 364 7
+             | 2001 001 01 1 01 001 1
+ (65 rows)
+ 
+ SELECT '' AS to_char_11, to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID')
+    FROM TIMESTAMP_TBL;
+  to_char_11 |        to_char         
+ ------------+------------------------
+             | 
+             | 
+             | 1970 970 70 0 1 4 4
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 1 4 4
+             | 1997 997 97 7 1 4 4
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 24 163 2
+             | 2001 001 01 1 38 265 6
+             | 2000 000 00 0 11 73 3
+             | 2000 000 00 0 11 73 3
+             | 2000 000 00 0 11 73 3
+             | 2000 000 00 0 11 73 3
+             | 2000 000 00 0 11 73 3
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 24 163 2
+             | 1997 997 97 7 7 43 1
+             | 1997 997 97 7 7 44 2
+             | 1997 997 97 7 7 45 3
+             | 1997 997 97 7 7 46 4
+             | 1997 997 97 7 7 47 5
+             | 1997 997 97 7 7 48 6
+             | 1997 997 97 7 7 49 7
+             | 97 097 97 7 7 44 2
+             | 97 097 97 7 7 48 6
+             | 597 597 97 7 7 46 4
+             | 1097 097 97 7 7 44 2
+             | 1697 697 97 7 7 48 6
+             | 1797 797 97 7 7 46 4
+             | 1897 897 97 7 7 44 2
+             | 1997 997 97 7 7 49 7
+             | 2097 097 97 7 7 48 6
+             | 1996 996 96 6 9 59 3
+             | 1996 996 96 6 9 60 4
+             | 1996 996 96 6 9 61 5
+             | 1997 997 97 7 1 1 1
+             | 1997 997 97 7 1 2 2
+             | 1997 997 97 7 1 3 3
+             | 1997 997 97 7 9 61 5
+             | 1997 997 97 7 9 62 6
+             | 1998 998 98 8 1 2 2
+             | 1998 998 98 8 1 3 3
+             | 1999 999 99 9 52 362 5
+             | 1999 999 99 9 52 363 6
+             | 2000 000 00 0 52 364 7
+             | 2001 001 01 1 1 1 1
+ (65 rows)
+ 
  -- TO_TIMESTAMP()
  SELECT '' AS to_timestamp_1, to_timestamp('0097/Feb/16 --> 08:14:30', 'YYYY/Mon/DD --> HH:MI:SS');
   to_timestamp_1 |         to_timestamp         
***************
*** 1428,1431 ****
--- 1633,1678 ----
                   | Thu Nov 16 00:00:00 1995 PST
  (1 row)
  
+ SELECT '' AS to_timestamp_15, to_timestamp('2005426', 'YYYYWWD');
+  to_timestamp_15 |         to_timestamp         
+ -----------------+------------------------------
+                  | Sat Oct 15 00:00:00 2005 PDT
+ (1 row)
+ 
+ SELECT '' AS to_timestamp_16, to_timestamp('2005300', 'YYYYDDD');
+  to_timestamp_16 |         to_timestamp         
+ -----------------+------------------------------
+                  | Thu Oct 27 00:00:00 2005 PDT
+ (1 row)
+ 
+ SELECT '' AS to_timestamp_17, to_timestamp('2005527', 'IYYYIWID');
+  to_timestamp_17 |         to_timestamp         
+ -----------------+------------------------------
+                  | Sun Jan 01 00:00:00 2006 PST
+ (1 row)
+ 
+ SELECT '' AS to_timestamp_18, to_timestamp('005527', 'IYYIWID');
+  to_timestamp_18 |         to_timestamp         
+ -----------------+------------------------------
+                  | Sun Jan 01 00:00:00 2006 PST
+ (1 row)
+ 
+ SELECT '' AS to_timestamp_19, to_timestamp('05527', 'IYIWID');
+  to_timestamp_19 |         to_timestamp         
+ -----------------+------------------------------
+                  | Sun Jan 01 00:00:00 2006 PST
+ (1 row)
+ 
+ SELECT '' AS to_timestamp_20, to_timestamp('5527', 'IIWID');
+  to_timestamp_20 |         to_timestamp         
+ -----------------+------------------------------
+                  | Sun Jan 01 00:00:00 2006 PST
+ (1 row)
+ 
+ SELECT '' AS to_timestamp_21, to_timestamp('2005364', 'IYYYIDDD');
+  to_timestamp_21 |         to_timestamp         
+ -----------------+------------------------------
+                  | Sun Jan 01 00:00:00 2006 PST
+ (1 row)
+ 
  SET DateStyle TO DEFAULT;
Index: src/test/regress/expected/timestamptz.out
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/expected/timestamptz.out,v
retrieving revision 1.21
diff -c -r1.21 timestamptz.out
*** src/test/regress/expected/timestamptz.out	17 Oct 2006 21:03:21 -0000	1.21
--- src/test/regress/expected/timestamptz.out	9 Nov 2006 18:52:53 -0000
***************
*** 720,725 ****
--- 720,788 ----
      | Mon Jan 01 17:32:01 2001 PST    |       1 |  1000 |  1000000
  (56 rows)
  
+ SELECT '' AS "54", d1 as "timestamp",
+    date_part( 'isoyear', d1) AS isoyear, date_part( 'week', d1) AS week,
+    date_part( 'dow', d1) AS dow
+    FROM TIMESTAMP_TBL WHERE d1 BETWEEN '1902-01-01' AND '2038-01-01';
+  54 |          timestamp          | isoyear | week | dow 
+ ----+-----------------------------+---------+------+-----
+     | Thu Jan 01 00:00:00 1970    |    1970 |    1 |   4
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:02 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01.40 1997 |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01.50 1997 |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01.60 1997 |    1997 |    7 |   1
+     | Thu Jan 02 00:00:00 1997    |    1997 |    1 |   4
+     | Thu Jan 02 03:04:05 1997    |    1997 |    1 |   4
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Tue Jun 10 17:32:01 1997    |    1997 |   24 |   2
+     | Sat Sep 22 18:19:20 2001    |    2001 |   38 |   6
+     | Wed Mar 15 08:14:01 2000    |    2000 |   11 |   3
+     | Wed Mar 15 13:14:02 2000    |    2000 |   11 |   3
+     | Wed Mar 15 12:14:03 2000    |    2000 |   11 |   3
+     | Wed Mar 15 03:14:04 2000    |    2000 |   11 |   3
+     | Wed Mar 15 02:14:05 2000    |    2000 |   11 |   3
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:00 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Tue Jun 10 18:32:01 1997    |    1997 |   24 |   2
+     | Mon Feb 10 17:32:01 1997    |    1997 |    7 |   1
+     | Tue Feb 11 17:32:01 1997    |    1997 |    7 |   2
+     | Wed Feb 12 17:32:01 1997    |    1997 |    7 |   3
+     | Thu Feb 13 17:32:01 1997    |    1997 |    7 |   4
+     | Fri Feb 14 17:32:01 1997    |    1997 |    7 |   5
+     | Sat Feb 15 17:32:01 1997    |    1997 |    7 |   6
+     | Sun Feb 16 17:32:01 1997    |    1997 |    7 |   0
+     | Sun Feb 16 17:32:01 1997    |    1997 |    7 |   0
+     | Wed Feb 28 17:32:01 1996    |    1996 |    9 |   3
+     | Thu Feb 29 17:32:01 1996    |    1996 |    9 |   4
+     | Fri Mar 01 17:32:01 1996    |    1996 |    9 |   5
+     | Mon Dec 30 17:32:01 1996    |    1997 |    1 |   1
+     | Tue Dec 31 17:32:01 1996    |    1997 |    1 |   2
+     | Wed Jan 01 17:32:01 1997    |    1997 |    1 |   3
+     | Fri Feb 28 17:32:01 1997    |    1997 |    9 |   5
+     | Sat Mar 01 17:32:01 1997    |    1997 |    9 |   6
+     | Tue Dec 30 17:32:01 1997    |    1998 |    1 |   2
+     | Wed Dec 31 17:32:01 1997    |    1998 |    1 |   3
+     | Fri Dec 31 17:32:01 1999    |    1999 |   52 |   5
+     | Sat Jan 01 17:32:01 2000    |    1999 |   52 |   6
+     | Sun Dec 31 17:32:01 2000    |    2000 |   52 |   0
+     | Mon Jan 01 17:32:01 2001    |    2001 |    1 |   1
+ (55 rows)
+ 
  -- TO_CHAR()
  SELECT '' AS to_char_1, to_char(d1, 'DAY Day day DY Dy dy MONTH Month month RM MON Mon mon') 
     FROM TIMESTAMPTZ_TBL;
***************
*** 1374,1450 ****
             | 2001 A.D. 2001 a.d. 2001 ad 05:32:01 P.M. 05:32:01 p.m. 05:32:01 pm
  (66 rows)
  
! SELECT '' AS to_char_10, to_char(d1, 'YYYY WW IYYY IYY IY I IW') 
!    FROM TIMESTAMPTZ_TBL;
!  to_char_10 |         to_char          
! ------------+--------------------------
              | 
              | 
!             | 1969 53 1970 970 70 0 01
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 01 1997 997 97 7 01
!             | 1997 01 1997 997 97 7 01
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 23 1997 997 97 7 24
!             | 2001 38 2001 001 01 1 38
!             | 2000 11 2000 000 00 0 11
!             | 2000 11 2000 000 00 0 11
!             | 2000 11 2000 000 00 0 11
!             | 2000 11 2000 000 00 0 11
!             | 2000 11 2000 000 00 0 11
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 28 1997 997 97 7 28
!             | 1997 23 1997 997 97 7 24
!             | 1997 06 1997 997 97 7 07
!             | 1997 06 1997 997 97 7 07
!             | 1997 07 1997 997 97 7 07
!             | 1997 07 1997 997 97 7 07
!             | 1997 07 1997 997 97 7 07
!             | 1997 07 1997 997 97 7 07
!             | 1997 07 1997 997 97 7 07
!             | 0097 07 0097 097 97 7 07
!             | 0097 07 0097 097 97 7 07
!             | 0597 07 0597 597 97 7 07
!             | 1097 07 1097 097 97 7 07
!             | 1697 07 1697 697 97 7 07
!             | 1797 07 1797 797 97 7 07
!             | 1897 07 1897 897 97 7 07
!             | 1997 07 1997 997 97 7 07
!             | 2097 07 2097 097 97 7 07
!             | 1996 09 1996 996 96 6 09
!             | 1996 09 1996 996 96 6 09
!             | 1996 09 1996 996 96 6 09
!             | 1996 53 1997 997 97 7 01
!             | 1996 53 1997 997 97 7 01
!             | 1997 01 1997 997 97 7 01
!             | 1997 09 1997 997 97 7 09
!             | 1997 09 1997 997 97 7 09
!             | 1997 52 1998 998 98 8 01
!             | 1997 53 1998 998 98 8 01
!             | 1999 53 1999 999 99 9 52
!             | 2000 01 1999 999 99 9 52
!             | 2000 53 2000 000 00 0 52
!             | 2001 01 2001 001 01 1 01
! (66 rows)
  
  -- TO_TIMESTAMP()
  SELECT '' AS to_timestamp_1, to_timestamp('0097/Feb/16 --> 08:14:30', 'YYYY/Mon/DD --> HH:MI:SS');
--- 1437,1583 ----
             | 2001 A.D. 2001 a.d. 2001 ad 05:32:01 P.M. 05:32:01 p.m. 05:32:01 pm
  (66 rows)
  
! SELECT '' AS to_char_10, to_char(d1, 'IYYY IYY IY I IW IDDD ID')
!    FROM TIMESTAMP_TBL;
!  to_char_10 |        to_char         
! ------------+------------------------
              | 
              | 
!             | 1970 970 70 0 01 004 4
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 01 004 4
!             | 1997 997 97 7 01 004 4
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 24 163 2
!             | 2001 001 01 1 38 265 6
!             | 2000 000 00 0 11 073 3
!             | 2000 000 00 0 11 073 3
!             | 2000 000 00 0 11 073 3
!             | 2000 000 00 0 11 073 3
!             | 2000 000 00 0 11 073 3
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 24 163 2
!             | 1997 997 97 7 07 043 1
!             | 1997 997 97 7 07 044 2
!             | 1997 997 97 7 07 045 3
!             | 1997 997 97 7 07 046 4
!             | 1997 997 97 7 07 047 5
!             | 1997 997 97 7 07 048 6
!             | 1997 997 97 7 07 049 7
!             | 0097 097 97 7 07 044 2
!             | 0097 097 97 7 07 048 6
!             | 0597 597 97 7 07 046 4
!             | 1097 097 97 7 07 044 2
!             | 1697 697 97 7 07 048 6
!             | 1797 797 97 7 07 046 4
!             | 1897 897 97 7 07 044 2
!             | 1997 997 97 7 07 049 7
!             | 2097 097 97 7 07 048 6
!             | 1996 996 96 6 09 059 3
!             | 1996 996 96 6 09 060 4
!             | 1996 996 96 6 09 061 5
!             | 1997 997 97 7 01 001 1
!             | 1997 997 97 7 01 002 2
!             | 1997 997 97 7 01 003 3
!             | 1997 997 97 7 09 061 5
!             | 1997 997 97 7 09 062 6
!             | 1998 998 98 8 01 002 2
!             | 1998 998 98 8 01 003 3
!             | 1999 999 99 9 52 362 5
!             | 1999 999 99 9 52 363 6
!             | 2000 000 00 0 52 364 7
!             | 2001 001 01 1 01 001 1
! (65 rows)
! 
! SELECT '' AS to_char_11, to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID')
!    FROM TIMESTAMP_TBL;
!  to_char_11 |        to_char         
! ------------+------------------------
!             | 
!             | 
!             | 1970 970 70 0 1 4 4
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 1 4 4
!             | 1997 997 97 7 1 4 4
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 24 163 2
!             | 2001 001 01 1 38 265 6
!             | 2000 000 00 0 11 73 3
!             | 2000 000 00 0 11 73 3
!             | 2000 000 00 0 11 73 3
!             | 2000 000 00 0 11 73 3
!             | 2000 000 00 0 11 73 3
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 24 163 2
!             | 1997 997 97 7 7 43 1
!             | 1997 997 97 7 7 44 2
!             | 1997 997 97 7 7 45 3
!             | 1997 997 97 7 7 46 4
!             | 1997 997 97 7 7 47 5
!             | 1997 997 97 7 7 48 6
!             | 1997 997 97 7 7 49 7
!             | 97 097 97 7 7 44 2
!             | 97 097 97 7 7 48 6
!             | 597 597 97 7 7 46 4
!             | 1097 097 97 7 7 44 2
!             | 1697 697 97 7 7 48 6
!             | 1797 797 97 7 7 46 4
!             | 1897 897 97 7 7 44 2
!             | 1997 997 97 7 7 49 7
!             | 2097 097 97 7 7 48 6
!             | 1996 996 96 6 9 59 3
!             | 1996 996 96 6 9 60 4
!             | 1996 996 96 6 9 61 5
!             | 1997 997 97 7 1 1 1
!             | 1997 997 97 7 1 2 2
!             | 1997 997 97 7 1 3 3
!             | 1997 997 97 7 9 61 5
!             | 1997 997 97 7 9 62 6
!             | 1998 998 98 8 1 2 2
!             | 1998 998 98 8 1 3 3
!             | 1999 999 99 9 52 362 5
!             | 1999 999 99 9 52 363 6
!             | 2000 000 00 0 52 364 7
!             | 2001 001 01 1 1 1 1
! (65 rows)
  
  -- TO_TIMESTAMP()
  SELECT '' AS to_timestamp_1, to_timestamp('0097/Feb/16 --> 08:14:30', 'YYYY/Mon/DD --> HH:MI:SS');
***************
*** 1531,1546 ****
                   | Thu Nov 16 00:00:00 1995 PST
  (1 row)
  
! SELECT '' AS to_timestamp_15, to_timestamp('200401', 'IYYYIW');
   to_timestamp_15 |         to_timestamp         
  -----------------+------------------------------
!                  | Mon Dec 29 00:00:00 2003 PST
  (1 row)
  
! SELECT '' AS to_timestamp_16, to_timestamp('200401', 'YYYYWW');
   to_timestamp_16 |         to_timestamp         
  -----------------+------------------------------
!                  | Thu Jan 01 00:00:00 2004 PST
  (1 row)
  
  SET DateStyle TO DEFAULT;
--- 1664,1709 ----
                   | Thu Nov 16 00:00:00 1995 PST
  (1 row)
  
! SELECT '' AS to_timestamp_15, to_timestamp('2005426', 'YYYYWWD');
   to_timestamp_15 |         to_timestamp         
  -----------------+------------------------------
!                  | Sat Oct 15 00:00:00 2005 PDT
  (1 row)
  
! SELECT '' AS to_timestamp_16, to_timestamp('2005300', 'YYYYDDD');
   to_timestamp_16 |         to_timestamp         
  -----------------+------------------------------
!                  | Thu Oct 27 00:00:00 2005 PDT
! (1 row)
! 
! SELECT '' AS to_timestamp_17, to_timestamp('2005527', 'IYYYIWID');
!  to_timestamp_17 |         to_timestamp         
! -----------------+------------------------------
!                  | Sun Jan 01 00:00:00 2006 PST
! (1 row)
! 
! SELECT '' AS to_timestamp_18, to_timestamp('005527', 'IYYIWID');
!  to_timestamp_18 |         to_timestamp         
! -----------------+------------------------------
!                  | Sun Jan 01 00:00:00 2006 PST
! (1 row)
! 
! SELECT '' AS to_timestamp_19, to_timestamp('05527', 'IYIWID');
!  to_timestamp_19 |         to_timestamp         
! -----------------+------------------------------
!                  | Sun Jan 01 00:00:00 2006 PST
! (1 row)
! 
! SELECT '' AS to_timestamp_20, to_timestamp('5527', 'IIWID');
!  to_timestamp_20 |         to_timestamp         
! -----------------+------------------------------
!                  | Sun Jan 01 00:00:00 2006 PST
! (1 row)
! 
! SELECT '' AS to_timestamp_21, to_timestamp('2005364', 'IYYYIDDD');
!  to_timestamp_21 |         to_timestamp         
! -----------------+------------------------------
!                  | Sun Jan 01 00:00:00 2006 PST
  (1 row)
  
  SET DateStyle TO DEFAULT;
Index: doc/src/sgml/func.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/func.sgml,v
retrieving revision 1.345
diff -c -r1.345 func.sgml
*** doc/src/sgml/func.sgml	23 Oct 2006 19:57:37 -0000	1.345
--- doc/src/sgml/func.sgml	9 Nov 2006 18:52:58 -0000
***************
*** 4527,4533 ****
         </row>
         <row>
          <entry><literal>I</literal></entry>
!         <entry>last digits of ISO year</entry>
         </row>
         <row>
          <entry><literal>BC</literal> or <literal>B.C.</literal> or
--- 4527,4533 ----
         </row>
         <row>
          <entry><literal>I</literal></entry>
!         <entry>last digit of ISO year</entry>
         </row>
         <row>
          <entry><literal>BC</literal> or <literal>B.C.</literal> or
***************
*** 4596,4601 ****
--- 4596,4605 ----
          <entry>day of year (001-366)</entry>
         </row>
         <row>
+         <entry><literal>IDDD</literal></entry>
+         <entry>ISO day of year (001-371; day 1 of the year is Monday of the first ISO week.)</entry>
+        </row>
+        <row>
          <entry><literal>DD</literal></entry>
          <entry>day of month (01-31)</entry>
         </row>
***************
*** 4604,4609 ****
--- 4608,4617 ----
          <entry>day of week (1-7; Sunday is 1)</entry>
         </row>
         <row>
+         <entry><literal>ID</literal></entry>
+         <entry>ISO day of week (1-7; Monday is 1)</entry>
+        </row>
+        <row>
          <entry><literal>W</literal></entry>
          <entry>week of month (1-5) (The first week starts on the first day of the month.)</entry>
         </row> 
***************
*** 4613,4619 ****
         </row>
         <row>
          <entry><literal>IW</literal></entry>
!         <entry>ISO week number of year (The first Thursday of the new year is in week 1.)</entry>
         </row>
         <row>
          <entry><literal>CC</literal></entry>
--- 4621,4627 ----
         </row>
         <row>
          <entry><literal>IW</literal></entry>
!         <entry>ISO week number of year (1 - 53; the first Thursday of the new year is in week 1.)</entry>
         </row>
         <row>
          <entry><literal>CC</literal></entry>
***************
*** 4781,4786 ****
--- 4789,4815 ----
  
       <listitem>
        <para>
+        An ISO week date (as distinct from a Gregorian date) can be specified to <function>to_timestamp</function> and <function>to_date</function> in one of two ways:
+        <itemizedlist>
+         <listitem>
+ 	 <para>
+ 	  Year, week and weekday, for example <literal>to_date('2006-42-4', 'IYYY-IW-ID')</literal> returns the date <literal>2006-10-19</literal>.  If you omit the weekday it is assumed to be 1 (Monday).
+ 	 </para>
+ 	</listitem>
+ 	<listitem>
+ 	 <para>
+ 	  Year and day of year, for example <literal>to_date('2006-291', 'IYYY-IDDD')</literal> also returns <literal>2006-10-19</literal>.
+ 	 </para>
+ 	</listitem>
+        </itemizedlist>
+       </para>
+       <para>
+        Attempting to construct a date using a mixture of ISO week and Gregorian date fields is nonsensical, and could yield unexpected results.  In the context of an ISO year, the concept of a 'month' or 'day of month' has no meaning.  In the context of a Gregorian year, the ISO week has no meaning.  Users should take care to keep Gregorian and ISO date specifications separate.
+       </para>
+      </listitem>
+ 
+      <listitem>
+       <para>
         Millisecond (<literal>MS</literal>) and microsecond (<literal>US</literal>)
         values in a conversion from string to <type>timestamp</type> are used as part of the
         seconds after the decimal point. For example 
***************
*** 5765,5770 ****
--- 5794,5822 ----
       </varlistentry>
  
       <varlistentry>
+       <term><literal>isoyear</literal></term>
+       <listitem>
+        <para>
+         The <acronym>ISO</acronym> 8601 year that the date falls in (not applicable to intervals).
+        </para>
+ 
+ <screen>
+ SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-01');
+ <lineannotation>Result: </lineannotation><computeroutput>2005</computeroutput>
+ SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02');
+ <lineannotation>Result: </lineannotation><computeroutput>2006</computeroutput>
+ </screen>
+ 
+        <para>
+         Each <acronym>ISO</acronym> year begins with the Monday of the week containing the 4th of January, so in early January or late December the <acronym>ISO</acronym> year may be different from the Gregorian year.  See the <literal>week</literal> field for more information.
+        </para>
+        <para>
+         This field is not available in PostgreSQL releases prior to 8.3.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
+      <varlistentry>
        <term><literal>microseconds</literal></term>
        <listitem>
         <para>
