Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,12 @@ public static Time boxTime(String val, ZoneId zoneId) {
* the Calendar timezone is explicitly ignored per JDBC 4.2 spec.
*/
public static Timestamp boxTimestamp(String val) {
// Check if the value is a numeric float string (e.g. "1680174859.8202269" from JSON API)
try {
if (val.indexOf('-') < 0
|| (val.startsWith("-")
&& val.indexOf('-', 1) < 0)) { // Quick check to ensure it's not a date string
// Epoch decimals never contain ':' but may contain '-' (e.g. "1.0E-6"), so key on ':'.
if (val.indexOf(':') < 0) {
try {
return Timestamp.from(parseEpochDecimalToInstant(val));
} catch (NumberFormatException ignored) {
}
} catch (NumberFormatException ignored) {
}
Comment thread
keshavdandeva marked this conversation as resolved.

String iso = val;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,16 @@ public void testBoxTimestamp() {
Timestamp picosIsoTs =
BigQueryTemporalUtility.boxTimestamp("2026-08-24T15:30:45.123456789012Z");
assertThat(picosIsoTs.getNanos()).isEqualTo(123456789);

// JSON API uses scientific notation for |t| < 1 ms
assertThat(BigQueryTemporalUtility.boxTimestamp("1.0E-6").toInstant())
.isEqualTo(Instant.parse("1970-01-01T00:00:00.000001Z"));
assertThat(BigQueryTemporalUtility.boxTimestamp("9.99E-4").toInstant())
.isEqualTo(Instant.parse("1970-01-01T00:00:00.000999Z"));
assertThat(BigQueryTemporalUtility.boxTimestamp("-1.0E-6").toInstant())
.isEqualTo(Instant.parse("1969-12-31T23:59:59.999999Z"));
assertThat(BigQueryTemporalUtility.boxTimestamp("-1.0E-4").toInstant())
.isEqualTo(Instant.parse("1969-12-31T23:59:59.999900Z"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ public class ITTimestampTimeZoneTest extends ITBase {
+ " DATE '2025-01-01' AS d,"
+ " TIME '12:34:56' AS t,"
+ " [TIMESTAMP '2025-01-01 12:34:56.123 UTC'] AS ts_array,"
+ " STRUCT(TIMESTAMP '2025-01-01 12:34:56.123 UTC' AS ts) AS ts_struct";
+ " STRUCT(TIMESTAMP '2025-01-01 12:34:56.123 UTC' AS ts) AS ts_struct,"
// REST API sends these as scientific notation ("1.0E-6", "-1.0E-6").
+ " TIMESTAMP '1970-01-01 00:00:00.000001 UTC' AS ts_post_epoch,"
+ " TIMESTAMP '1969-12-31 23:59:59.999999 UTC' AS ts_pre_epoch";

// Same coercion as an INSERT into a TIMESTAMP column, for TIMESTAMP and STRING parameters.
private static final String PROBE_TIMESTAMP = "SELECT UNIX_MILLIS(CAST(? AS TIMESTAMP))";
Expand Down Expand Up @@ -321,7 +324,17 @@ public void testGetTimestampAndGetObject_returnMoment(String zone) throws SQLExc
assertEquals(
Timestamp.from(REF),
rs.getObject("ts"),
label(zone, "getObject must return a Timestamp of the stored moment")));
label(zone, "getObject must return a Timestamp of the stored moment")),
() ->
assertEquals(
Instant.parse("1970-01-01T00:00:00.000001Z"),
rs.getTimestamp("ts_post_epoch").toInstant(),
label(zone, "getTimestamp just after the epoch")),
() ->
assertEquals(
Instant.parse("1969-12-31T23:59:59.999999Z"),
rs.getTimestamp("ts_pre_epoch").toInstant(),
label(zone, "getTimestamp just before the epoch")));
}
}

Expand Down Expand Up @@ -500,7 +513,17 @@ public void testGetString_returnsUtcDigits(String zone) throws SQLException {
assertEquals(
"{\"ts\":\"2025-01-01 12:34:56.123\"}",
rs.getString("ts_struct"),
label(zone, "getString on STRUCT<TIMESTAMP> must return UTC digits")));
label(zone, "getString on STRUCT<TIMESTAMP> must return UTC digits")),
() ->
assertEquals(
"1970-01-01 00:00:00.000001",
rs.getString("ts_post_epoch"),
label(zone, "getString just after the epoch")),
() ->
assertEquals(
"1969-12-31 23:59:59.999999",
rs.getString("ts_pre_epoch"),
label(zone, "getString just before the epoch")));
}
}

Expand Down
Loading