aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java130
-rw-r--r--src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java154
2 files changed, 133 insertions, 151 deletions
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java
index 7fea1dab6be..b20d2f8a880 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java
@@ -492,6 +492,14 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
* Get the value of a column in the current row as a
* java.sql.Timestamp object
*
+ * 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 columnIndex the first column is 1, the second is 2...
* @return the column value; null if SQL NULL
* @exception SQLException if a database access error occurs
@@ -499,102 +507,80 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
public Timestamp getTimestamp(int columnIndex) throws SQLException
{
String s = getString(columnIndex);
+
if (s == null)
return null;
- boolean subsecond;
- //if string contains a '.' we have fractional seconds
- if (s.indexOf('.') == -1)
- {
- subsecond = false;
- }
- else
- {
- subsecond = true;
- }
+ StringBuffer sbuf = new StringBuffer(s);
+ SimpleDateFormat df = null;
- //here we are modifying the string from ISO format to a format java can understand
- //java expects timezone info as 'GMT-08:00' instead of '-08' in postgres ISO format
- //and java expects three digits if fractional seconds are present instead of two for postgres
- //so this code strips off timezone info and adds on the GMT+/-...
- //as well as adds a third digit for partial seconds if necessary
- StringBuffer strBuf = new StringBuffer(s);
-
- //we are looking to see if the backend has appended on a timezone.
- //currently postgresql will return +/-HH:MM or +/-HH for timezone offset
- //(i.e. -06, or +06:30, note the expectation of the leading zero for the
- //hours, and the use of the : for delimiter between hours and minutes)
- //if the backend ISO format changes in the future this code will
- //need to be changed as well
- char sub = strBuf.charAt(strBuf.length() - 3);
- if (sub == '+' || sub == '-')
+ if (s.length() > 19)
{
- strBuf.setLength(strBuf.length() - 3);
- if (subsecond)
- {
- strBuf.append('0').append("GMT").append(s.substring(s.length() - 3, s.length())).append(":00");
- }
- else
- {
- strBuf.append("GMT").append(s.substring(s.length() - 3, s.length())).append(":00");
- }
- }
- else if (sub == ':')
- {
- //we may have found timezone info of format +/-HH:MM, or there is no
- //timezone info at all and this is the : preceding the seconds
- char sub2 = strBuf.charAt(strBuf.length() - 5);
- if (sub2 == '+' || sub2 == '-')
+ // 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;
+ sbuf.setLength(i);
+
+ char c = s.charAt(i++);
+ if (c == '.')
{
- //we have found timezone info of format +/-HH:MM
- strBuf.setLength(strBuf.length() - 5);
- if (subsecond)
- {
- strBuf.append('0').append("GMT").append(s.substring(s.length() - 5));
- }
- else
+ // Found a fractional value. Append up to 3 digits including
+ // the leading '.'
+ do
{
- strBuf.append("GMT").append(s.substring(s.length() - 5));
- }
+ if (i < 24)
+ 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++)
+ sbuf.append('0');
}
- else if (subsecond)
+ else
{
- strBuf.append('0');
+ // No fractional seconds, lets add some.
+ sbuf.append(".000");
}
- }
- else if (subsecond)
- {
- strBuf = strBuf.append('0');
- }
- s = strBuf.toString();
+ // prepend the GMT part and then add the remaining bit of
+ // the string.
+ sbuf.append(" GMT");
+ sbuf.append(c);
+ sbuf.append(s.substring(i, s.length()));
- SimpleDateFormat df = null;
+ // Lastly, if the tz part doesn't specify the :MM part then
+ // we add ":00" for java.
+ if (s.length() - i < 5)
+ sbuf.append(":00");
- if (s.length() > 23 && subsecond)
- {
- df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSzzzzzzzzz");
- }
- else if (s.length() > 23 && !subsecond)
- {
- df = new SimpleDateFormat("yyyy-MM-dd HH:mm:sszzzzzzzzz");
- }
- else if (s.length() > 10 && subsecond)
- {
- df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ // 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() > 10 && !subsecond)
+ 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
{
- return new Timestamp(df.parse(s).getTime());
+ // All that's left is to parse the string and return the ts.
+ return new Timestamp(df.parse(sbuf.toString()).getTime());
}
catch (ParseException e)
{
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java
index 66e7b4d3fac..565847db9f1 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java
@@ -1591,115 +1591,113 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
}
}
- public static Timestamp toTimestamp(String s, ResultSet resultSet) throws SQLException
+ /**
+ * Parse a string and return a timestamp representing its value.
+ *
+ * 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.
+ *
+ * @return null if s is null or a timestamp of the parsed string s.
+ *
+ * @throws SQLException if there is a problem parsing s.
+ **/
+ public static Timestamp toTimestamp(String s, ResultSet resultSet)
+ throws SQLException
{
if (s == null)
return null;
- boolean subsecond;
- //if string contains a '.' we have fractional seconds
- if (s.indexOf('.') == -1)
- {
- subsecond = false;
- }
- else
- {
- subsecond = true;
- }
-
- //here we are modifying the string from ISO format to a format java can understand
- //java expects timezone info as 'GMT-08:00' instead of '-08' in postgres ISO format
- //and java expects three digits if fractional seconds are present instead of two for postgres
- //so this code strips off timezone info and adds on the GMT+/-...
- //as well as adds a third digit for partial seconds if necessary
+ // 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)
{
- // We must be synchronized here incase more theads access the ResultSet
- // bad practice but possible. Anyhow this is to protect sbuf and
- // SimpleDateFormat objects
+ SimpleDateFormat df = null;
- // First time?
+ // If first time, create the buffer, otherwise clear it.
if (resultSet.sbuf == null)
resultSet.sbuf = new StringBuffer();
+ else
+ resultSet.sbuf.setLength(0);
- resultSet.sbuf.setLength(0);
+ // Copy s into sbuf for parsing.
resultSet.sbuf.append(s);
- //we are looking to see if the backend has appended on a timezone.
- //currently postgresql will return +/-HH:MM or +/-HH for timezone offset
- //(i.e. -06, or +06:30, note the expectation of the leading zero for the
- //hours, and the use of the : for delimiter between hours and minutes)
- //if the backend ISO format changes in the future this code will
- //need to be changed as well
- char sub = resultSet.sbuf.charAt(resultSet.sbuf.length() - 3);
- if (sub == '+' || sub == '-')
+ if (s.length() > 19)
{
- //we have found timezone info of format +/-HH
+ // 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.
- resultSet.sbuf.setLength(resultSet.sbuf.length() - 3);
- if (subsecond)
- {
- resultSet.sbuf.append('0').append("GMT").append(s.substring(s.length() - 3)).append(":00");
- }
- else
- {
- resultSet.sbuf.append("GMT").append(s.substring(s.length() - 3)).append(":00");
- }
- }
- else if (sub == ':')
- {
- //we may have found timezone info of format +/-HH:MM, or there is no
- //timezone info at all and this is the : preceding the seconds
- char sub2 = resultSet.sbuf.charAt(resultSet.sbuf.length() - 5);
- if (sub2 == '+' || sub2 == '-')
+ // 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 == '.')
{
- //we have found timezone info of format +/-HH:MM
- resultSet.sbuf.setLength(resultSet.sbuf.length() - 5);
- if (subsecond)
- {
- resultSet.sbuf.append('0').append("GMT").append(s.substring(s.length() - 5));
- }
- else
+ // Found a fractional value. Append up to 3 digits including
+ // the leading '.'
+ do
{
- resultSet.sbuf.append("GMT").append(s.substring(s.length() - 5));
- }
+ 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 if (subsecond)
+ else
{
- resultSet.sbuf.append('0');
+ // No fractional seconds, lets add some.
+ resultSet.sbuf.append(".000");
}
- }
- else if (subsecond)
- {
- resultSet.sbuf.append('0');
- }
- // could optimize this a tad to remove too many object creations...
- SimpleDateFormat df = null;
+ // 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()));
- if (resultSet.sbuf.length() > 23 && subsecond)
- {
- df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSzzzzzzzzz");
- }
- else if (resultSet.sbuf.length() > 23 && !subsecond)
- {
- df = new SimpleDateFormat("yyyy-MM-dd HH:mm:sszzzzzzzzz");
- }
- else if (resultSet.sbuf.length() > 10 && subsecond)
- {
- df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ // 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 (resultSet.sbuf.length() > 10 && !subsecond)
+ 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)
@@ -1708,7 +1706,5 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
}
}
}
-
-
}