Return-Path: X-Original-To: apmail-commons-commits-archive@minotaur.apache.org Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id A965C10BC3 for ; Mon, 12 Aug 2013 19:40:20 +0000 (UTC) Received: (qmail 75346 invoked by uid 500); 12 Aug 2013 19:40:18 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 75015 invoked by uid 500); 12 Aug 2013 19:40:18 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 75002 invoked by uid 99); 12 Aug 2013 19:40:17 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 12 Aug 2013 19:40:17 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 12 Aug 2013 19:40:15 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 4EFD823888E7; Mon, 12 Aug 2013 19:39:55 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1513232 - in /commons/sandbox/convert/trunk/src: main/java/org/apache/commons/convert/DateTimeConverters.java test/java/org/apache/commons/convert/TestDateTimeConverters.java Date: Mon, 12 Aug 2013 19:39:55 -0000 To: commits@commons.apache.org From: adrianc@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20130812193955.4EFD823888E7@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: adrianc Date: Mon Aug 12 19:39:54 2013 New Revision: 1513232 URL: http://svn.apache.org/r1513232 Log: Improved code for String->Timestamp->String conversions. Modified: commons/sandbox/convert/trunk/src/main/java/org/apache/commons/convert/DateTimeConverters.java commons/sandbox/convert/trunk/src/test/java/org/apache/commons/convert/TestDateTimeConverters.java Modified: commons/sandbox/convert/trunk/src/main/java/org/apache/commons/convert/DateTimeConverters.java URL: http://svn.apache.org/viewvc/commons/sandbox/convert/trunk/src/main/java/org/apache/commons/convert/DateTimeConverters.java?rev=1513232&r1=1513231&r2=1513232&view=diff ============================================================================== --- commons/sandbox/convert/trunk/src/main/java/org/apache/commons/convert/DateTimeConverters.java (original) +++ commons/sandbox/convert/trunk/src/main/java/org/apache/commons/convert/DateTimeConverters.java Mon Aug 12 19:39:54 2013 @@ -43,10 +43,6 @@ public class DateTimeConverters implemen * JDBC TIME format string: HH:mm:ss. */ public static final String JDBC_TIME_FORMAT = "HH:mm:ss"; - /** - * JDBC TIMESTAMP format string: yyyy-MM-dd HH:mm:ss.SSS. - */ - public static final String JDBC_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS"; /** * Returns an initialized DateFormat object. @@ -746,15 +742,26 @@ public class DateTimeConverters implemen } /** - * Converts obj to a java.sql.Timestamp. If - * formatString is null, the string must be - * formatted as {@link DateTimeConverters#JDBC_TIMESTAMP_FORMAT}. + * Converts obj to a java.sql.Timestamp. + *

Note that the string representation is referenced to the timeZone + * argument, not UTC. The Timestamp that is returned is adjusted to UTC. + * This behavior is intended to accommodate user-entered timestamps, where users are + * accustomed to using their own time zone.

+ *

*/ public java.sql.Timestamp convert(String obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException { - DateFormat df = toDateTimeFormat(formatString == null ? JDBC_TIMESTAMP_FORMAT : formatString, timeZone, locale); try { - return new java.sql.Timestamp(df.parse(obj).getTime()); - } catch (ParseException e) { + // The String is referenced to the time zone represented by the timeZone + // argument, but the parsing code assumes a reference to UTC. So, we need + // to "adjust" the parsed Timestamp's value. + Timestamp parsedStamp = Timestamp.valueOf(obj); + Calendar cal = Calendar.getInstance(timeZone, locale); + cal.setTime(parsedStamp); + cal.add(Calendar.MILLISECOND, 0 - timeZone.getOffset(parsedStamp.getTime())); + Timestamp result = new Timestamp(cal.getTimeInMillis()); + result.setNanos(parsedStamp.getNanos()); + return result; + } catch (Exception e) { throw new ConversionException(e); } } @@ -851,13 +858,27 @@ public class DateTimeConverters implemen /** * Converts obj to a String using the supplied - * locale, time zone, and format string. If formatString is - * null, the string is formatted as - * {@link DateTimeConverters#JDBC_TIMESTAMP_FORMAT}. + * time zone. + *

Note that the string representation is referenced to the timeZone + * argument, not UTC. The Timestamp is adjusted to the specified + * time zone before conversion. This behavior is intended to accommodate user interfaces, + * where users are accustomed to viewing timestamps in their own time zone.

+ *

*/ - public String convert(java.sql.Timestamp obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException { - DateFormat df = toDateTimeFormat(formatString == null ? JDBC_TIMESTAMP_FORMAT : formatString, timeZone, locale); - return df.format(obj); + public String convert(Timestamp obj, Locale locale, TimeZone timeZone, String formatString) throws ConversionException { + try { + // The Timestamp is referenced to UTC, but the String result needs to be + // referenced to the time zone represented by the timeZone argument. + // So, we need to "adjust" the Timestamp's value before conversion. + Calendar cal = Calendar.getInstance(timeZone, locale); + cal.setTime(obj); + cal.add(Calendar.MILLISECOND, timeZone.getOffset(obj.getTime())); + Timestamp result = new Timestamp(cal.getTimeInMillis()); + result.setNanos(obj.getNanos()); + return result.toString(); + } catch (Exception e) { + throw new ConversionException(e); + } } } Modified: commons/sandbox/convert/trunk/src/test/java/org/apache/commons/convert/TestDateTimeConverters.java URL: http://svn.apache.org/viewvc/commons/sandbox/convert/trunk/src/test/java/org/apache/commons/convert/TestDateTimeConverters.java?rev=1513232&r1=1513231&r2=1513232&view=diff ============================================================================== --- commons/sandbox/convert/trunk/src/test/java/org/apache/commons/convert/TestDateTimeConverters.java (original) +++ commons/sandbox/convert/trunk/src/test/java/org/apache/commons/convert/TestDateTimeConverters.java Mon Aug 12 19:39:54 2013 @@ -87,6 +87,8 @@ public class TestDateTimeConverters exte java.sql.Date sqlDate = new java.sql.Date(70, 0, 1); java.sql.Time sqlTime = new java.sql.Time(0, 0, 0); java.sql.Timestamp timestamp = new java.sql.Timestamp(currentTime); + java.sql.Timestamp stampWithNanos = new java.sql.Timestamp(currentTime); + stampWithNanos.setNanos(10); // Source class = java.util.Calendar DateFormat df = new SimpleDateFormat(DateTimeConverters.CALENDAR_FORMAT); df.setCalendar(cal); @@ -118,7 +120,7 @@ public class TestDateTimeConverters exte assertConversion("TimestampToLong", new DateTimeConverters.GenericDateToLong(java.sql.Timestamp.class), timestamp, currentTime); assertConversion("TimestampToSqlDate", new DateTimeConverters.TimestampToSqlDate(), new java.sql.Timestamp(sqlDate.getTime()), sqlDate); assertConversion("TimestampToSqlTime", new DateTimeConverters.TimestampToSqlTime(), new java.sql.Timestamp(sqlDate.getTime()), sqlTime); - assertConversion("TimestampToString", new DateTimeConverters.TimestampToString(), timestamp, timestamp.toString()); + assertConversion("TimestampToString", new DateTimeConverters.TimestampToString(), stampWithNanos, stampWithNanos.toString()); assertToCollection("TimestampToCollection", timestamp); // TimeZone tests TimeZone tz = TimeZone.getDefault();