*** org/postgresql/jdbc2/ResultSet.java_7.2b4	Tue Dec 11 13:48:05 2001
--- org/postgresql/jdbc2/ResultSet.java	Thu Jan 17 19:42:19 2002
***************
*** 1597,1606 ****
  	* The driver is set to return ISO date formated strings. We modify this 
  	* string from the ISO format to a format that Java can understand. Java
  	* expects timezone info as 'GMT+09:00' where as ISO gives '+09'.
! 	* Java also expects fractional seconds to 3 places where postgres
  	* will give, none, 2 or 6 depending on the time and postgres version.
  	* From version 7.2 postgres returns fractional seconds to 6 places.
- 	* If available, we drop the last 3 digits.
  	*
  	* @param s         The ISO formated date string to parse.
  	* @param resultSet The ResultSet this date is part of.
--- 1597,1605 ----
  	* The driver is set to return ISO date formated strings. We modify this 
  	* string from the ISO format to a format that Java can understand. Java
  	* expects timezone info as 'GMT+09:00' where as ISO gives '+09'.
! 	* Java also expects fractional seconds to 9 places where postgres
  	* will give, none, 2 or 6 depending on the time and postgres version.
  	* From version 7.2 postgres returns fractional seconds to 6 places.
  	*
  	* @param s         The ISO formated date string to parse.
  	* @param resultSet The ResultSet this date is part of.
***************
*** 1613,1704 ****
  	throws SQLException
  	{
  		if (s == null)
! 			return null;
  
  		// We must be synchronized here incase more theads access the ResultSet
! 		// bad practice but possible. Anyhow this is to protect sbuf and
! 		// SimpleDateFormat objects
  		synchronized (resultSet)
  		{
  			SimpleDateFormat df = null;
  
! 			// If first time, create the buffer, otherwise clear it.
  			if (resultSet.sbuf == null)
  				resultSet.sbuf = new StringBuffer();
! 			else
  				resultSet.sbuf.setLength(0);
  
! 			// Copy s into sbuf for parsing.
! 			resultSet.sbuf.append(s);
  
! 			if (s.length() > 19)
! 			{
! 				// The len of the ISO string to the second value is 19 chars. If
! 				// greater then 19, there should be tz info and perhaps fractional
! 				// second info which we need to change to java to read it.
! 
! 				// cut the copy to second value "2001-12-07 16:29:22"
! 				int i = 19;
! 				resultSet.sbuf.setLength(i);
! 
! 				char c = s.charAt(i++);
! 				if (c == '.')
! 				{
! 					// Found a fractional value. Append up to 3 digits including
! 					// the leading '.'
! 					do
! 					{
! 						if (i < 24)
! 							resultSet.sbuf.append(c);
! 						c = s.charAt(i++);
! 					} while (Character.isDigit(c));
! 
! 					// If there wasn't at least 3 digits we should add some zeros
! 					// to make up the 3 digits we tell java to expect.
! 					for (int j = i; j < 24; j++)
  						resultSet.sbuf.append('0');
  				}
- 				else
- 				{
- 					// No fractional seconds, lets add some.
- 					resultSet.sbuf.append(".000");
- 				}
- 
- 				// prepend the GMT part and then add the remaining bit of
- 				// the string.
- 				resultSet.sbuf.append(" GMT");
- 				resultSet.sbuf.append(c);
- 				resultSet.sbuf.append(s.substring(i, s.length()));
- 
- 				// Lastly, if the tz part doesn't specify the :MM part then
- 				// we add ":00" for java.
- 				if (s.length() - i < 5)
- 					resultSet.sbuf.append(":00");
  
! 				// we'll use this dateformat string to parse the result.
! 				df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
! 			}
! 			else if (s.length() == 19)
! 			{
! 				// No tz or fractional second info. 
! 				// I'm not sure if it is
! 				// possible to have a string in this format, as pg
! 				// should give us tz qualified timestamps back, but it was
! 				// in the old code, so I'm handling it for now.
! 				df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
! 			}
! 			else
! 			{
! 				// We must just have a date. This case is 
! 				// needed if this method is called on a date
! 				// column
! 				df = new SimpleDateFormat("yyyy-MM-dd");
  			}
  
  			try
  			{
  				// All that's left is to parse the string and return the ts.
! 				return new Timestamp(df.parse(resultSet.sbuf.toString()).getTime());
  			}
  			catch (ParseException e)
  			{
--- 1612,1695 ----
  	throws SQLException
  	{
  		if (s == null)
! 			return null; // SQL NULL
! 
! 		// 2002-01-15 17:22:41.863506+09  timestamp with time zone
! 		// 2002-01-15 17:25:11.451415     timestamp without time zone
! 		// 2002-01-15 17:22:41+09         timestamp(0) with time zone
! 		// 2002-01-15 17:25:11            timestamp(0) without time zone
! 		// 2002-01-15                     date
  
  		// We must be synchronized here incase more theads access the ResultSet
! 		// bad practice but possible. Anyhow this is to protect sbuf.
  		synchronized (resultSet)
  		{
+ 			final int TIMESTAMP_LENGTH = 19; // "2002-01-15 17:22:41".length()
+ 			final int MAX_NANOS_LENGTH = 9; // 0 <= Timastamp.nanos <= 999999999
  			SimpleDateFormat df = null;
+ 			int nanos = 0;
  
! 			// If first time, create the buffer
  			if (resultSet.sbuf == null)
  				resultSet.sbuf = new StringBuffer();
! 
! 			if (s.length() < TIMESTAMP_LENGTH) {
! 				// In case of SQL Date.
  				resultSet.sbuf.setLength(0);
+ 				resultSet.sbuf.append(s);
+ 				df = new SimpleDateFormat("yyyy-MM-dd");
+ 			} else {
+ 				// In case of SQL Timestamp.
  
! 				// Search position of decimal point and time zone.
! 				int decimalPointIndex = s.length();
! 				int timezoneIndex = s.length();
! 				for (int i = TIMESTAMP_LENGTH; i < s.length(); i++) {
! 					switch (s.charAt(i)) {
! 						case '.':
! 							decimalPointIndex = i;
! 							break;
! 						case '+':
! 						case '-':
! 							timezoneIndex = i;
! 							break;
! 						default:
! 							break; // digit
! 					}
! 				}
  
! 				if (decimalPointIndex < s.length()) {
! 					// Parse fractional seconds
! 					resultSet.sbuf.setLength(0);
! 					resultSet.sbuf.append(s.substring(decimalPointIndex + 1, timezoneIndex));
! 					for (int i = resultSet.sbuf.length(); i < MAX_NANOS_LENGTH; i++) {
  						resultSet.sbuf.append('0');
+ 					}
+ 					resultSet.sbuf.setLength(MAX_NANOS_LENGTH);
+ 					nanos = Integer.parseInt(resultSet.sbuf.toString());
  				}
  
! 				resultSet.sbuf.setLength(0);
! 				resultSet.sbuf.append(s.substring(0, TIMESTAMP_LENGTH));
! 				if (timezoneIndex < s.length()) {
! 					// Parse time zone.
! 					String tz = s.substring(timezoneIndex, s.length());
! 					resultSet.sbuf.append(" GMT");
! 					resultSet.sbuf.append(tz);
! 					if (tz.length() <= 3) // "+09".length()
! 						resultSet.sbuf.append(":00");
! 					df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
! 				} else {
! 					df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
! 				}
  			}
  
  			try
  			{
  				// All that's left is to parse the string and return the ts.
! 				Timestamp ts = new Timestamp(df.parse(resultSet.sbuf.toString()).getTime());
! 				ts.setNanos(nanos);
! 				return ts;
  			}
  			catch (ParseException e)
  			{
