From e03b483a94a3e14c06c203fda816d55489f8ba8f Mon Sep 17 00:00:00 2001 From: Bhavik Shah <115029313+bhvkshah@users.noreply.github.com> Date: Mon, 12 Feb 2024 16:49:28 -0600 Subject: [PATCH] Added support for TIME datatype to display up to 6 digits of fractional second data --- .../amazon/redshift/jdbc/TimestampUtils.java | 6 ++- .../amazon/redshift/util/RedshiftTime.java | 39 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/amazon/redshift/jdbc/TimestampUtils.java b/src/main/java/com/amazon/redshift/jdbc/TimestampUtils.java index 253be1a..1dc6c49 100644 --- a/src/main/java/com/amazon/redshift/jdbc/TimestampUtils.java +++ b/src/main/java/com/amazon/redshift/jdbc/TimestampUtils.java @@ -620,11 +620,13 @@ public synchronized Time toTime(Calendar cal, String s) throws SQLException { long timeMillis = useCal.getTimeInMillis() + ts.nanos / 1000000; if (ts.tz != null || (ts.year == 1970 && ts.era == GregorianCalendar.AD)) { // time with time zone has proper time zone, so the value can be returned as is - return new Time(timeMillis); + Time timeObj = new Time(timeMillis); + return (ts.nanos > 0) ? new RedshiftTime(timeObj, ts.nanos) : timeObj; } // 2) Truncate date part so in given time zone the date would be formatted as 01/01/1970 - return convertToTime(timeMillis, useCal.getTimeZone()); + Time timeObj = convertToTime(timeMillis, useCal.getTimeZone()); + return (ts.nanos > 0) ? new RedshiftTime(timeObj, ts.nanos) : timeObj; } public synchronized Date toDate(Calendar cal, String s) throws SQLException { diff --git a/src/main/java/com/amazon/redshift/util/RedshiftTime.java b/src/main/java/com/amazon/redshift/util/RedshiftTime.java index 5e680bf..a2e134e 100644 --- a/src/main/java/com/amazon/redshift/util/RedshiftTime.java +++ b/src/main/java/com/amazon/redshift/util/RedshiftTime.java @@ -8,6 +8,7 @@ import java.sql.PreparedStatement; import java.sql.Time; import java.util.Calendar; +import java.text.SimpleDateFormat; /** * This class augments the Java built-in Time to allow for explicit setting of the time zone. @@ -139,4 +140,42 @@ public Object clone() { } return clone; } + + /** + * Threadsafe access to ready to use time formatter + */ + public static ThreadLocal TIME_FORMAT = + new ThreadLocal() + { + @Override + protected SimpleDateFormat initialValue() + { + return new SimpleDateFormat("HH:mm:ss"); + } + }; + + + /** + * Override default to string method to handle nanoSeconds + */ + @Override + public String toString() + { + StringBuilder baseResult = new StringBuilder(); + baseResult.append(TIME_FORMAT.get().format(this.getTime())); + + // TIME columns store values with up to a maximum of 6 digits of precision for fractional seconds. + // If TIME has more than 6 digits, trim down to 6 digits from the end of TIME. + if (0 < nanos) + { + while (999999 < nanos) + { + nanos /= 10; + } + baseResult.append("."); + baseResult.append(String.valueOf(nanos)); + } + + return baseResult.toString(); + } }