Skip to content

Commit cdebcad

Browse files
author
Barry Lind
committed
fixed bug in support for timestamp without time zone reported by Yuva Chandolu (ychandolu@ebates.com)
1 parent 846ea08 commit cdebcad

File tree

3 files changed

+135
-73
lines changed

3 files changed

+135
-73
lines changed

src/interfaces/jdbc/org/postgresql/Driver.java.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,6 @@ public class Driver implements java.sql.Driver
442442
}
443443

444444
//The build number should be incremented for every new build
445-
private static int m_buildNumber = 101;
445+
private static int m_buildNumber = 102;
446446

447447
}

src/interfaces/jdbc/org/postgresql/jdbc1/PreparedStatement.java

Lines changed: 71 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
3636
String[] inStrings;
3737
Connection connection;
3838

39+
// Some performance caches
40+
private StringBuffer sbuf = new StringBuffer();
41+
3942
/*
4043
* Constructor for the PreparedStatement class.
4144
* Split the SQL statement into segments - separated by the arguments.
@@ -340,19 +343,8 @@ public void setDate(int parameterIndex, java.sql.Date x) throws SQLException
340343
}
341344
else
342345
{
343-
SimpleDateFormat df = new SimpleDateFormat("''yyyy-MM-dd''");
344-
set(parameterIndex, df.format(x));
346+
set(parameterIndex, "'" + x.toString() + "'");
345347
}
346-
// The above is how the date should be handled.
347-
//
348-
// However, in JDK's prior to 1.1.6 (confirmed with the
349-
// Linux jdk1.1.3 and the Win95 JRE1.1.5), SimpleDateFormat seems
350-
// to format a date to the previous day. So the fix is to add a day
351-
// before formatting.
352-
//
353-
// PS: 86400000 is one day
354-
//
355-
//set(parameterIndex, df.format(new java.util.Date(x.getTime()+86400000)));
356348
}
357349

358350
/*
@@ -390,23 +382,75 @@ public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException
390382
setNull(parameterIndex, Types.OTHER);
391383
}
392384
else
393-
{
394-
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
395-
df.setTimeZone(TimeZone.getTimeZone("GMT"));
396-
397-
// Make decimal from nanos.
398-
StringBuffer decimal = new StringBuffer("000000000"); // max nanos length
399-
String nanos = String.valueOf(x.getNanos());
400-
decimal.setLength(decimal.length() - nanos.length());
401-
decimal.append(nanos);
402-
if (! connection.haveMinimumServerVersion("7.2")) {
403-
// Because 7.1 include bug that "hh:mm:59.999" becomes "hh:mm:60.00".
404-
decimal.setLength(2);
385+
{
386+
// Use the shared StringBuffer
387+
synchronized (sbuf)
388+
{
389+
sbuf.setLength(0);
390+
sbuf.append("'");
391+
//format the timestamp
392+
//we do our own formating so that we can get a format
393+
//that works with both timestamp with time zone and
394+
//timestamp without time zone datatypes.
395+
//The format is '2002-01-01 23:59:59.123456-0130'
396+
//we need to include the local time and timezone offset
397+
//so that timestamp without time zone works correctly
398+
int l_year = x.getYear() + 1900;
399+
sbuf.append(l_year);
400+
sbuf.append('-');
401+
int l_month = x.getMonth() + 1;
402+
if (l_month < 10) sbuf.append('0');
403+
sbuf.append(l_month);
404+
sbuf.append('-');
405+
int l_day = x.getDate();
406+
if (l_day < 10) sbuf.append('0');
407+
sbuf.append(l_day);
408+
sbuf.append(' ');
409+
int l_hours = x.getHours();
410+
if (l_hours < 10) sbuf.append('0');
411+
sbuf.append(l_hours);
412+
sbuf.append(':');
413+
int l_minutes = x.getMinutes();
414+
if (l_minutes < 10) sbuf.append('0');
415+
sbuf.append(l_minutes);
416+
sbuf.append(':');
417+
int l_seconds = x.getSeconds();
418+
if (l_seconds < 10) sbuf.append('0');
419+
sbuf.append(l_seconds);
420+
// Make decimal from nanos.
421+
char[] l_decimal = {'0','0','0','0','0','0','0','0','0'};
422+
char[] l_nanos = Integer.toString(x.getNanos()).toCharArray();
423+
System.arraycopy(l_nanos, 0, l_decimal, l_decimal.length - l_nanos.length, l_nanos.length);
424+
sbuf.append('.');
425+
if (connection.haveMinimumServerVersion("7.2")) {
426+
sbuf.append(l_decimal,0,6);
427+
} else {
428+
// Because 7.1 include bug that "hh:mm:59.999" becomes "hh:mm:60.00".
429+
sbuf.append(l_decimal,0,2);
430+
}
431+
//add timezone offset
432+
int l_offset = -(x.getTimezoneOffset());
433+
int l_houros = l_offset/60;
434+
if (l_houros >= 0) {
435+
sbuf.append('+');
436+
} else {
437+
sbuf.append('-');
438+
}
439+
if (l_houros > -10 && l_houros < 10) sbuf.append('0');
440+
if (l_houros >= 0) {
441+
sbuf.append(l_houros);
442+
} else {
443+
sbuf.append(-l_houros);
444+
}
445+
int l_minos = l_offset - (l_houros *60);
446+
if (l_minos != 0) {
447+
if (l_minos < 10) sbuf.append('0');
448+
sbuf.append(l_minos);
449+
}
450+
sbuf.append("'");
451+
set(parameterIndex, sbuf.toString());
405452
}
406453

407-
StringBuffer strBuf = new StringBuffer("'");
408-
strBuf.append(df.format(x)).append('.').append(decimal).append("+00'");
409-
set(parameterIndex, strBuf.toString());
410454
}
411455
}
412456

src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java

Lines changed: 63 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,6 @@ public class PreparedStatement extends Statement implements java.sql.PreparedSta
3939
// Some performance caches
4040
private StringBuffer sbuf = new StringBuffer();
4141

42-
// We use ThreadLocal for SimpleDateFormat's because they are not that
43-
// thread safe, so each calling thread has its own object.
44-
private static ThreadLocal tl_df = new ThreadLocal(); // setDate() SimpleDateFormat
45-
private static ThreadLocal tl_tsdf = new ThreadLocal(); // setTimestamp() SimpleDateFormat
46-
4742
/*
4843
* Constructor for the PreparedStatement class.
4944
* Split the SQL statement into segments - separated by the arguments.
@@ -355,24 +350,8 @@ public void setDate(int parameterIndex, java.sql.Date x) throws SQLException
355350
}
356351
else
357352
{
358-
SimpleDateFormat df = (SimpleDateFormat) tl_df.get();
359-
if (df == null)
360-
{
361-
df = new SimpleDateFormat("''yyyy-MM-dd''");
362-
tl_df.set(df);
363-
}
364-
set(parameterIndex, df.format(x));
353+
set(parameterIndex, "'" + x.toString() + "'");
365354
}
366-
// The above is how the date should be handled.
367-
//
368-
// However, in JDK's prior to 1.1.6 (confirmed with the
369-
// Linux jdk1.1.3 and the Win95 JRE1.1.5), SimpleDateFormat seems
370-
// to format a date to the previous day. So the fix is to add a day
371-
// before formatting.
372-
//
373-
// PS: 86400000 is one day
374-
//
375-
//set(parameterIndex, df.format(new java.util.Date(x.getTime()+86400000)));
376355
}
377356

378357
/*
@@ -410,36 +389,75 @@ public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException
410389
setNull(parameterIndex, Types.OTHER);
411390
}
412391
else
413-
{
414-
SimpleDateFormat df = (SimpleDateFormat) tl_tsdf.get();
415-
if (df == null)
416-
{
417-
df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
418-
df.setTimeZone(TimeZone.getTimeZone("GMT"));
419-
tl_tsdf.set(df);
420-
}
421-
422-
// Make decimal from nanos.
423-
StringBuffer decimal = new StringBuffer("000000000"); // max nanos length
424-
String nanos = String.valueOf(x.getNanos());
425-
decimal.setLength(decimal.length() - nanos.length());
426-
decimal.append(nanos);
427-
if (! connection.haveMinimumServerVersion("7.2")) {
428-
// Because 7.1 include bug that "hh:mm:59.999" becomes "hh:mm:60.00".
429-
decimal.setLength(2);
430-
}
431-
392+
{
432393
// Use the shared StringBuffer
433394
synchronized (sbuf)
434395
{
435396
sbuf.setLength(0);
436-
sbuf.append("'").append(df.format(x)).append('.').append(decimal).append("+00'");
397+
sbuf.append("'");
398+
//format the timestamp
399+
//we do our own formating so that we can get a format
400+
//that works with both timestamp with time zone and
401+
//timestamp without time zone datatypes.
402+
//The format is '2002-01-01 23:59:59.123456-0130'
403+
//we need to include the local time and timezone offset
404+
//so that timestamp without time zone works correctly
405+
int l_year = x.getYear() + 1900;
406+
sbuf.append(l_year);
407+
sbuf.append('-');
408+
int l_month = x.getMonth() + 1;
409+
if (l_month < 10) sbuf.append('0');
410+
sbuf.append(l_month);
411+
sbuf.append('-');
412+
int l_day = x.getDate();
413+
if (l_day < 10) sbuf.append('0');
414+
sbuf.append(l_day);
415+
sbuf.append(' ');
416+
int l_hours = x.getHours();
417+
if (l_hours < 10) sbuf.append('0');
418+
sbuf.append(l_hours);
419+
sbuf.append(':');
420+
int l_minutes = x.getMinutes();
421+
if (l_minutes < 10) sbuf.append('0');
422+
sbuf.append(l_minutes);
423+
sbuf.append(':');
424+
int l_seconds = x.getSeconds();
425+
if (l_seconds < 10) sbuf.append('0');
426+
sbuf.append(l_seconds);
427+
// Make decimal from nanos.
428+
char[] l_decimal = {'0','0','0','0','0','0','0','0','0'};
429+
char[] l_nanos = Integer.toString(x.getNanos()).toCharArray();
430+
System.arraycopy(l_nanos, 0, l_decimal, l_decimal.length - l_nanos.length, l_nanos.length);
431+
sbuf.append('.');
432+
if (connection.haveMinimumServerVersion("7.2")) {
433+
sbuf.append(l_decimal,0,6);
434+
} else {
435+
// Because 7.1 include bug that "hh:mm:59.999" becomes "hh:mm:60.00".
436+
sbuf.append(l_decimal,0,2);
437+
}
438+
//add timezone offset
439+
int l_offset = -(x.getTimezoneOffset());
440+
int l_houros = l_offset/60;
441+
if (l_houros >= 0) {
442+
sbuf.append('+');
443+
} else {
444+
sbuf.append('-');
445+
}
446+
if (l_houros > -10 && l_houros < 10) sbuf.append('0');
447+
if (l_houros >= 0) {
448+
sbuf.append(l_houros);
449+
} else {
450+
sbuf.append(-l_houros);
451+
}
452+
int l_minos = l_offset - (l_houros *60);
453+
if (l_minos != 0) {
454+
if (l_minos < 10) sbuf.append('0');
455+
sbuf.append(l_minos);
456+
}
457+
sbuf.append("'");
437458
set(parameterIndex, sbuf.toString());
438459
}
439460

440-
// The above works, but so does the following. I'm leaving the above in, but this seems
441-
// to be identical. Pays to read the docs ;-)
442-
//set(parameterIndex,"'"+x.toString()+"'");
443461
}
444462
}
445463

0 commit comments

Comments
 (0)