Skip to content

BigQuery: QueryParameterValue.timestamp(long) conversion causes loss of microsecond precision #6495

@slilichenko

Description

@slilichenko

Environment details

  1. Specify the API at the beginning of the title (for example, "BigQuery: ...")
    General, Core, and Other are also allowed as types
  2. OS type and version:
  3. Java version:
  4. google-cloud-java version(s):

Steps to reproduce

Use QueryParameterValue.timestamp(long) with microsecond precision; the precision will be lost.

Code example

Unit test (can't attached; .java is not accepted extension):
package com.google.demo;

import static org.threeten.bp.temporal.ChronoField.HOUR_OF_DAY;
import static org.threeten.bp.temporal.ChronoField.MINUTE_OF_HOUR;
import static org.threeten.bp.temporal.ChronoField.NANO_OF_SECOND;
import static org.threeten.bp.temporal.ChronoField.SECOND_OF_MINUTE;

import com.google.cloud.bigquery.QueryParameterValue;
import org.junit.Assert;
import org.junit.Test;
import org.threeten.bp.Instant;
import org.threeten.bp.ZoneOffset;
import org.threeten.bp.format.DateTimeFormatter;
import org.threeten.bp.format.DateTimeFormatterBuilder;

public class QueryParameterValueTest {

// Taken as-is from QueryParameterValue class
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseLenient()
.append(org.threeten.bp.format.DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral(' ')
.appendValue(HOUR_OF_DAY, 2)
.appendLiteral(':')
.appendValue(MINUTE_OF_HOUR, 2)
.optionalStart()
.appendLiteral(':')
.appendValue(SECOND_OF_MINUTE, 2)
.optionalStart()
.appendFraction(NANO_OF_SECOND, 6, 9, true)
.optionalStart()
.appendOffset("+HHMM", "+00:00")
.optionalEnd()
.toFormatter()
.withZone(ZoneOffset.UTC);

@test
public void testTimestamp() {
//--- Added microseconds
long tsInMicroseconds = 1571068536842L * 1000 + 123;
long MICROSECONDS = 1_000_000;

long secs = Math.floorDiv(tsInMicroseconds, MICROSECONDS);
int nano = (int) Math.floorMod(tsInMicroseconds, MICROSECONDS) * 1000;
Instant instant = Instant.ofEpochSecond(secs, nano);

String expected = formatter.format(instant);

Assert.assertEquals(expected, QueryParameterValue.timestamp(tsInMicroseconds).getValue());

}
}
output:
org.junit.ComparisonFailure:
Expected :2019-10-14 15:55:36.842123+00:00
Actual :2019-10-14 15:55:36.842000+00:00

Metadata

Metadata

Assignees

Labels

api: bigqueryIssues related to the BigQuery API.priority: p2Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions