8058429: JCK test api/java_sql/Timestamp/descriptions.html start failing after 8058230
Reviewed-by: lancea
--- a/jdk/src/java.sql/share/classes/java/sql/Timestamp.java Mon Sep 15 13:05:04 2014 -0700
+++ b/jdk/src/java.sql/share/classes/java/sql/Timestamp.java Mon Sep 15 21:20:46 2014 +0200
@@ -284,20 +284,32 @@
}
}
- char[] buf = new char[29 - trailingZeros];
- Date.formatDecimalInt(year, buf, 0, 4);
- buf[4] = '-';
- Date.formatDecimalInt(month, buf, 5, 2);
- buf[7] = '-';
- Date.formatDecimalInt(day, buf, 8, 2);
- buf[10] = ' ';
- Date.formatDecimalInt(hour, buf, 11, 2);
- buf[13] = ':';
- Date.formatDecimalInt(minute, buf, 14, 2);
- buf[16] = ':';
- Date.formatDecimalInt(second, buf, 17, 2);
- buf[19] = '.';
- Date.formatDecimalInt(tmpNanos, buf, 20, 9 - trailingZeros);
+ // 8058429: To comply with current JCK tests, we need to deal with year
+ // being any number between 0 and 292278995
+ int count = 10000;
+ int yearSize = 4;
+ do {
+ if (year < count) {
+ break;
+ }
+ yearSize++;
+ count *= 10;
+ } while (count < 1000000000);
+
+ char[] buf = new char[25 + yearSize - trailingZeros];
+ Date.formatDecimalInt(year, buf, 0, yearSize);
+ buf[yearSize] = '-';
+ Date.formatDecimalInt(month, buf, yearSize + 1, 2);
+ buf[yearSize + 3] = '-';
+ Date.formatDecimalInt(day, buf, yearSize + 4, 2);
+ buf[yearSize + 6] = ' ';
+ Date.formatDecimalInt(hour, buf, yearSize + 7, 2);
+ buf[yearSize + 9] = ':';
+ Date.formatDecimalInt(minute, buf, yearSize + 10, 2);
+ buf[yearSize + 12] = ':';
+ Date.formatDecimalInt(second, buf, yearSize + 13, 2);
+ buf[yearSize + 15] = '.';
+ Date.formatDecimalInt(tmpNanos, buf, yearSize + 16, 9 - trailingZeros);
return jla.newStringUnsafe(buf);
}
--- a/jdk/test/java/sql/test/sql/TimestampTests.java Mon Sep 15 13:05:04 2014 -0700
+++ b/jdk/test/java/sql/test/sql/TimestampTests.java Mon Sep 15 21:20:46 2014 +0200
@@ -27,6 +27,7 @@
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDateTime;
+import java.time.ZoneId;
import java.util.Calendar;
import static org.testng.Assert.*;
import org.testng.annotations.DataProvider;
@@ -610,6 +611,12 @@
"Error with Nanos");
}
+ @Test(dataProvider = "validTimestampLongValues")
+ public void test52(long value, String ts) {
+ Timestamp ts1 = new Timestamp(value);
+ assertEquals(ts1.toString(), ts, "ts1.toString() != ts");
+ }
+
/*
* DataProvider used to provide Timestamps which are not valid and are used
* to validate that an IllegalArgumentException will be thrown from the
@@ -678,6 +685,40 @@
};
}
+ @DataProvider(name = "validTimestampLongValues")
+ private Object[][] validTimestampLongValues() {
+ return new Object[][]{
+ {1L, "1970-01-01 01:00:00.001"},
+ {-3600*1000L - 1, "1969-12-31 23:59:59.999"},
+ {-(20000L*365*24*60*60*1000), "18018-08-28 01:00:00.0"},
+ {Timestamp.valueOf("1961-08-30 11:22:33").getTime(), "1961-08-30 11:22:33.0"},
+ {Timestamp.valueOf("1961-08-30 11:22:33.54321000").getTime(), "1961-08-30 11:22:33.543"}, // nanoprecision lost
+ {new Timestamp(114, 10, 10, 10, 10, 10, 100000000).getTime(), "2014-11-10 10:10:10.1"},
+ {new Timestamp(0, 10, 10, 10, 10, 10, 100000).getTime(), "1900-11-10 10:10:10.0"}, // nanoprecision lost
+ {new Date(114, 10, 10).getTime(), "2014-11-10 00:00:00.0"},
+ {new Date(0, 10, 10).getTime(), "1900-11-10 00:00:00.0"},
+ {LocalDateTime.of(1960, 10, 10, 10, 10, 10, 50000).atZone(ZoneId.of("America/Los_Angeles"))
+ .toInstant().toEpochMilli(), "1960-10-10 19:10:10.0"},
+
+ // millisecond timestamps wraps around at year 1, so Long.MIN_VALUE looks similar
+ // Long.MAX_VALUE, while actually representing 292278994 BCE
+ {Long.MIN_VALUE, "292278994-08-17 08:12:55.192"},
+ {Long.MAX_VALUE + 1, "292278994-08-17 08:12:55.192"},
+ {Long.MAX_VALUE, "292278994-08-17 08:12:55.807"},
+ {Long.MIN_VALUE - 1, "292278994-08-17 08:12:55.807"},
+
+ // wrap around point near 0001-01-01, test that we never get a negative year:
+ {-(1970L*365*24*60*60*1000), "0001-04-25 01:00:00.0"},
+ {-(1970L*365*24*60*60*1000 + 115*24*60*60*1000L), "0001-12-31 01:00:00.0"},
+ {-(1970L*365*24*60*60*1000 + 115*24*60*60*1000L - 23*60*60*1000L), "0001-01-01 00:00:00.0"},
+
+ {LocalDateTime.of(0, 1, 1, 10, 10, 10, 50000).atZone(ZoneId.of("America/Los_Angeles"))
+ .toInstant().toEpochMilli() - 2*24*60*60*1000L, "0001-01-01 19:03:08.0"}, // 1 BCE
+ {LocalDateTime.of(0, 1, 1, 10, 10, 10, 50000).atZone(ZoneId.of("America/Los_Angeles"))
+ .toInstant().toEpochMilli() - 3*24*60*60*1000L, "0002-12-31 19:03:08.0"} // 2 BCE
+ };
+ }
+
/*
* DataProvider used to provide Timestamp and Nanos values in order to
* validate that the correct Nanos value is generated from the specified