import java.sql.Timestamp; import java.util.Date; import java.text.SimpleDateFormat; import java.text.FieldPosition; import java.util.Calendar; import java.util.GregorianCalendar; public class tsperf { private static GregorianCalendar cal = new GregorianCalendar(); private static StringBuffer sbuf = new StringBuffer(35); private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS000Z"); private static FieldPosition fieldPos = new FieldPosition(0); private static final int COUNT = 100000; public static void main(String[] args) { Timestamp timestamp = new Timestamp((new Date()).getTime()); long startTime = System.currentTimeMillis(); for (int i = 0; i < COUNT; i++) { setTimestamp74(0, timestamp); } long endTime = System.currentTimeMillis(); String string74 = sbuf.toString(); System.err.println("setTimestamp74 took: " + (endTime - startTime)); startTime = System.currentTimeMillis(); for (int i = 0; i < COUNT; i++) { setTimestamp80(0, timestamp); } endTime = System.currentTimeMillis(); String string80 = sbuf.toString(); System.err.println("setTimestamp80 took: " + (endTime - startTime)); startTime = System.currentTimeMillis(); for (int i = 0; i < COUNT; i++) { setTimestampDF(0, timestamp); } endTime = System.currentTimeMillis(); String stringDF = sbuf.toString(); System.err.println("format took: " + (endTime - startTime)); System.err.println("string74: " + string74); System.err.println("string80: " + string80); System.err.println("stringDF: " + stringDF); } private static void setTimestampDF(int parameterIndex, Timestamp timestamp) { synchronized (sbuf) { sbuf.setLength(0); format.format(timestamp, sbuf, fieldPos); } } private static void setTimestamp80(int parameterIndex, Timestamp x) { cal.setTime(x); synchronized(sbuf) { sbuf.setLength(0); appendDate(sbuf, cal); sbuf.append(' '); appendTime(sbuf, cal, x.getNanos()); appendTimeZone(sbuf, x); appendEra(sbuf, cal); } } private static void appendDate(StringBuffer sbuf, Calendar cal) { int l_year = cal.get(Calendar.YEAR); // always use at least four digits for the year so very // early years, like 2, don't get misinterpreted // int l_yearlen = String.valueOf(l_year).length(); for (int i = 4; i > l_yearlen; i--) { sbuf.append("0"); } sbuf.append(l_year); sbuf.append('-'); int l_month = cal.get(Calendar.MONTH) + 1; if (l_month < 10) sbuf.append('0'); sbuf.append(l_month); sbuf.append('-'); int l_day = cal.get(Calendar.DAY_OF_MONTH); if (l_day < 10) sbuf.append('0'); sbuf.append(l_day); } private static void appendTime(StringBuffer sbuf, Calendar cal, int nanos) { int hours = cal.get(Calendar.HOUR_OF_DAY); if (hours < 10) sbuf.append('0'); sbuf.append(hours); sbuf.append(':'); int minutes = cal.get(Calendar.MINUTE); if (minutes < 10) sbuf.append('0'); sbuf.append(minutes); sbuf.append(':'); int seconds = cal.get(Calendar.SECOND); if (seconds < 10) sbuf.append('0'); sbuf.append(seconds); // Add nanoseconds. // This won't work for server versions < 7.2 which only want // a two digit fractional second, but we don't need to support 7.1 // anymore and getting the version number here is difficult. // char[] decimalStr = {'0', '0', '0', '0', '0', '0', '0', '0', '0'}; char[] nanoStr = Integer.toString(nanos).toCharArray(); System.arraycopy(nanoStr, 0, decimalStr, decimalStr.length - nanoStr.length, nanoStr.length); sbuf.append('.'); sbuf.append(decimalStr, 0, 6); } private static void appendTimeZone(StringBuffer sbuf, java.util.Date x) { //add timezone offset int offset = -(x.getTimezoneOffset()); int absoff = Math.abs(offset); int hours = absoff / 60; int mins = absoff - hours * 60; sbuf.append((offset >= 0) ? "+" : "-"); if (hours < 10) sbuf.append('0'); sbuf.append(hours); if (mins < 10) sbuf.append('0'); sbuf.append(mins); } private static void appendEra(StringBuffer sbuf, Calendar cal) { if (cal.get(Calendar.ERA) == GregorianCalendar.BC) { sbuf.append(" BC"); } } private static void setTimestamp74(int parameterIndex, Timestamp x) { // Use the shared StringBuffer synchronized (sbuf) { sbuf.setLength(0); //format the timestamp //we do our own formating so that we can get a format //that works with both timestamp with time zone and //timestamp without time zone datatypes. //The format is '2002-01-01 23:59:59.123456-0130' //we need to include the local time and timezone offset //so that timestamp without time zone works correctly int l_year = x.getYear() + 1900; // always use four digits for the year so very // early years, like 2, don't get misinterpreted int l_yearlen = String.valueOf(l_year).length(); for (int i = 4; i > l_yearlen; i--) { sbuf.append("0"); } sbuf.append(l_year); sbuf.append('-'); int l_month = x.getMonth() + 1; if (l_month < 10) sbuf.append('0'); sbuf.append(l_month); sbuf.append('-'); int l_day = x.getDate(); if (l_day < 10) sbuf.append('0'); sbuf.append(l_day); sbuf.append(' '); int l_hours = x.getHours(); if (l_hours < 10) sbuf.append('0'); sbuf.append(l_hours); sbuf.append(':'); int l_minutes = x.getMinutes(); if (l_minutes < 10) sbuf.append('0'); sbuf.append(l_minutes); sbuf.append(':'); int l_seconds = x.getSeconds(); if (l_seconds < 10) sbuf.append('0'); sbuf.append(l_seconds); // Make decimal from nanos. char[] l_decimal = {'0', '0', '0', '0', '0', '0', '0', '0', '0'}; char[] l_nanos = Integer.toString(x.getNanos()).toCharArray(); System.arraycopy(l_nanos, 0, l_decimal, l_decimal.length - l_nanos.length, l_nanos.length); sbuf.append('.'); sbuf.append(l_decimal, 0, 6); //add timezone offset int l_offset = -(x.getTimezoneOffset()); int l_houros = l_offset / 60; if (l_houros >= 0) { sbuf.append('+'); } else { sbuf.append('-'); } if (l_houros > -10 && l_houros < 10) sbuf.append('0'); if (l_houros >= 0) { sbuf.append(l_houros); } else { sbuf.append( -l_houros); } int l_minos = l_offset - (l_houros * 60); if (l_minos != 0) { if (l_minos > -10 && l_minos < 10) sbuf.append('0'); if (l_minos >= 0) { sbuf.append(l_minos); } else { sbuf.append( -l_minos); } } } } }