Fix external issue 4048 - make java.sql.Timestamp emulation
more lenient about the formatting of the nanoseconds field.

Review by: jat



git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7352 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/super/com/google/gwt/emul/java/sql/Timestamp.java b/user/super/com/google/gwt/emul/java/sql/Timestamp.java
index 369f0c2..527a404 100644
--- a/user/super/com/google/gwt/emul/java/sql/Timestamp.java
+++ b/user/super/com/google/gwt/emul/java/sql/Timestamp.java
@@ -29,19 +29,36 @@
     }
 
     String[] timeComponents = components[1].split("\\.");
-    if (timeComponents.length != 2) {
-      throw new IllegalArgumentException("Invalid escape format: " + s);
-    } else if (timeComponents[1].length() != 9) {
+    boolean hasNanos = true;
+    int nanos = 0;
+ 
+    if (timeComponents.length == 1) {
+      // Allow timestamps without .fffffffff nanoseconds field
+      hasNanos = false;
+    } else if (timeComponents.length != 2) {
       throw new IllegalArgumentException("Invalid escape format: " + s);
     }
 
     Date d = Date.valueOf(components[0]);
     Time t = Time.valueOf(timeComponents[0]);
-    int nanos;
-    try {
-      nanos = Integer.valueOf(timeComponents[1]);
-    } catch (NumberFormatException e) {
-      throw new IllegalArgumentException("Invalid escape format: " + s);
+    if (hasNanos) {
+      String nanosString = timeComponents[1];
+      int len = nanosString.length();
+      assert(len > 0); // len must be > 0 if hasNanos is true
+      if (len > 9) {
+        throw new IllegalArgumentException("Invalid escape format: " + s);
+      }
+
+      // Pad zeros on the right up to a total of 9 digits
+      if (len < 9) {
+        nanosString += "00000000".substring(len - 1);
+      }
+
+      try {
+        nanos = Integer.valueOf(nanosString);
+      } catch (NumberFormatException e) {
+        throw new IllegalArgumentException("Invalid escape format: " + s);
+      }
     }
 
     return new Timestamp(d.getYear(), d.getMonth(), d.getDate(), t.getHours(),
diff --git a/user/test/com/google/gwt/emultest/java/sql/SqlTimestampTest.java b/user/test/com/google/gwt/emultest/java/sql/SqlTimestampTest.java
index cb77943..b211971 100644
--- a/user/test/com/google/gwt/emultest/java/sql/SqlTimestampTest.java
+++ b/user/test/com/google/gwt/emultest/java/sql/SqlTimestampTest.java
@@ -174,5 +174,40 @@
     Timestamp expected = new Timestamp(2000 - 1900, 1 - 1, 1, 12, 34, 56, 123456789);
     Timestamp actual = Timestamp.valueOf("2000-01-01 12:34:56.123456789");
     assertEquals(expected, actual);
+    
+    expected = new Timestamp(2000 - 1900, 1 - 1, 1, 12, 34, 56, 0);
+    actual = Timestamp.valueOf("2000-01-01 12:34:56");
+    assertEquals(expected, actual);
+    
+    expected = new Timestamp(2000 - 1900, 1 - 1, 1, 12, 34, 56, 100000000);
+    actual = Timestamp.valueOf("2000-01-01 12:34:56.1");
+    assertEquals(expected, actual);
+    
+    expected = new Timestamp(2000 - 1900, 1 - 1, 1, 12, 34, 56, 120000000);
+    actual = Timestamp.valueOf("2000-01-01 12:34:56.12");
+    assertEquals(expected, actual);
+    
+    expected = new Timestamp(2000 - 1900, 1 - 1, 1, 12, 34, 56, 123000000);
+    actual = Timestamp.valueOf("2000-01-01 12:34:56.123");
+    assertEquals(expected, actual);
+    
+    expected = new Timestamp(2000 - 1900, 1 - 1, 1, 12, 34, 56, 123400000);
+    actual = Timestamp.valueOf("2000-01-01 12:34:56.1234");
+    assertEquals(expected, actual);
+    
+    expected = new Timestamp(2000 - 1900, 1 - 1, 1, 12, 34, 56, 123450000);
+    actual = Timestamp.valueOf("2000-01-01 12:34:56.12345");
+    assertEquals(expected, actual);
+    
+    expected = new Timestamp(2000 - 1900, 1 - 1, 1, 12, 34, 56, 123456000);
+    actual = Timestamp.valueOf("2000-01-01 12:34:56.123456");
+    assertEquals(expected, actual);
+    
+    expected = new Timestamp(2000 - 1900, 1 - 1, 1, 12, 34, 56, 123456700);
+    actual = Timestamp.valueOf("2000-01-01 12:34:56.1234567");
+    assertEquals(expected, actual);
+    
+    expected = new Timestamp(2000 - 1900, 1 - 1, 1, 12, 34, 56, 123456780);
+    actual = Timestamp.valueOf("2000-01-01 12:34:56.12345678");
   }
 }