tursodatabase/turso · error · SQLException

Cannot convert value to Timestamp: {type}

Error message

Cannot convert value to Timestamp: {type}

What it means

getTimestamp(int) accepts only the driver's 8-byte epoch-millis blob written by setTimestamp (Long.BYTES buffer, putLong). TEXT timestamps ('2024-01-31 10:00:00') and INTEGER epoch columns arrive as String/Long and throw with the actual class name. Unlike getTime, this message correctly says 'Timestamp'.

Source

Thrown at bindings/java/src/main/java/tech/turso/jdbc4/JDBC4ResultSet.java:230

  @Override
  @SkipNullableCheck
  public Timestamp getTimestamp(int columnIndex) throws SQLException {
    final Object result = resultSet.get(columnIndex);
    wasNull = result == null;
    if (result == null) {
      return null;
    }
    return wrapTypeConversion(
        () -> {
          if (result instanceof byte[]) {
            byte[] bytes = (byte[]) result;
            if (bytes.length == Long.BYTES) {
              long time = ByteBuffer.wrap(bytes).getLong();
              return new Timestamp(time);
            }
          }
          throw new SQLException("Cannot convert value to Timestamp: " + result.getClass());
        });
  }

  @Override
  @SkipNullableCheck
  public InputStream getAsciiStream(int columnIndex) throws SQLException {
    final Object result = resultSet.get(columnIndex);
    wasNull = result == null;
    if (result == null) {
      return null;
    }
    return wrapTypeConversion(
        () -> {
          if (result instanceof String) {
            return new ByteArrayInputStream(((String) result).getBytes("US-ASCII"));
          } else if (result instanceof byte[]) {
            return new ByteArrayInputStream((byte[]) result);
          }

View on GitHub (pinned to bad083fafb)

Solutions

  1. Parse in Java: Timestamp.valueOf(rs.getString(i)) for 'yyyy-mm-dd hh:mm:ss[.fff]', Timestamp.from(Instant.parse(s)) for ISO-8601, or new Timestamp(rs.getLong(i)) for epoch millis.
  2. Write with setTimestamp() so the blob round-trips.
  3. Or transform in SQL (strftime / CAST) so the value arrives in the shape you parse.

Example fix

// before
Timestamp ts = rs.getTimestamp(1); // TEXT column -> throws

// after
Timestamp ts = Timestamp.valueOf(rs.getString(1));
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = rs.getObject(1);
Timestamp ts = (v == null) ? null
    : isDriverDateBlob(v) ? rs.getTimestamp(1)
    : Timestamp.valueOf(rs.getString(1)); // 'yyyy-mm-dd hh:mm:ss[.fff]' fallback

Type guard

static boolean isDriverDateBlob(Object v) {
    return v instanceof byte[] b && b.length == Long.BYTES;
}

Try / catch

try {
    return rs.getTimestamp(i);
} catch (SQLException e) {
    if (e.getMessage() != null && e.getMessage().contains("Cannot convert value to Timestamp")) {
        return Timestamp.valueOf(rs.getString(i));
    }
    throw e;
}

Prevention

When it happens

Trigger: rs.getTimestamp() on TEXT or INTEGER timestamp columns; timestamps written by other tools/drivers as strings; DEFAULT CURRENT_TIMESTAMP columns that SQLite stores as text.

Common situations: Schemas shared with other SQLite writers; migrated datasets keeping text timestamps; assuming other drivers' lenient getTimestamp coercion.

Related errors


AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16). Data as JSON: /api/errors/8e8bf5df87c6b3ea. Report an issue: GitHub.