influxdb-java icon indicating copy to clipboard operation
influxdb-java copied to clipboard

fromInfluxDBTimeFormat does not parse milliseconds correct

Open Prebzs opened this issue 8 years ago • 2 comments

If a timestamp has a 10-millisecond time (last digit 0), the returned milliseconds time is not correct.

.time(1497600000030L, TimeUnit.MILLISECONDS)

after reading from database: fromInfluxDBTimeFormat(raw.get(0).toString()) returns "1497600000003"

the database contains "2017-06-16T08:00:00.03Z"

Prebzs avatar Jun 16 '17 10:06 Prebzs

TLDR: When you execute a query using the InfluxDB Java client, always specify the TimeUnit parameter and never parse the RFC3339 date format returned by InfluxDB.

This seems to be related with how InfluxDB (in fact, Go lang) uses the RFC3339 for date formatting and how java.text.SimpleDateFormat (used by this library) differs from the first.

<short-version>

  • InfluxDB format "1497600000030L" as "2017-06-16T08:00:00.03Z" (.030 ms was trimmed to .03 ms)
  • SimpleDateFormat using the pattern "yyyy-MM-dd'T'HH:mm:ss.SS'Z'" format "1497600000030L" as "2017-06-16T10:00:00.30Z" (.030 ms was "interpreted" as .30 ms)
  • If you try to parse the "2017-06-16T08:00:00.03Z" using SimpleDateFormat, you will have the wrong value with .03ms.

</short-version>

You can test it by yourself:

root@3e65d276839c:/# influx                   
Connected to http://localhost:8086 version 1.3.0
InfluxDB shell version: 1.3.0
>
> create database mydatabase
>
> use mydatabase
Using database mydatabase
>
> insert bar value=1 1497600000030000000
>
> select * from bar
name: bar
time                value
----                -----
1497600000030000000 1

The time 1497600000030000000 is in nanoseconds and it is the same one provided in the previous comment.

Now let's see how InfluxDB is formatting a date using RFC3339. Accordingly with the InfluxDB documentation:

The -precision argument specifies the format/precision of any returned timestamps. In the example above, rfc3339 tells InfluxDB to return timestamps in RFC3339 format (YYYY-MM-DDTHH:MM:SS.nnnnnnnnnZ). Source: https://docs.influxdata.com/influxdb/v1.2/introduction/getting_started/#creating-a-database

root@3e65d276839c:/# influx -precision rfc3339
Connected to http://localhost:8086 version 1.3.0
InfluxDB shell version: 1.3.0
>
> use mydatabase
Using database mydatabase
>
> select * from bar
name: bar
time                    value
----                    -----
2017-06-16T08:00:00.03Z 1
> 

Remember, the issue here is with the milliseconds representation (trimmed to .03).

Now try to execute the following code (output added as comment):

public class Main {

  public static void main(String[] args) {
    long time = TimeUnit.NANOSECONDS.toMillis(1497600000030000000L);

    // 2017-06-16T10:00:00.30Z
    System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.S'Z'").format(time));

    // 2017-06-16T10:00:00.30Z
    System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SS'Z'").format(time));

    // 2017-06-16T10:00:00.030Z
    System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(time));

    // 2017-06-16T10:00:00.0030Z
    System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSS'Z'").format(time));

    // 2017-06-16T10:00:00.00030Z
    System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSS'Z'").format(time));

    // 2017-06-16T10:00:00.000030Z
    System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'Z'").format(time));

    // SAME REPRESENTATION AS INFLUXDB: 2017-06-16T08:00:00.03Z
    DateTimeFormatter rfc3339Format = new DateTimeFormatterBuilder()
      .appendPattern("yyyy-MM-dd'T'HH:mm:ss")
      .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 6, true)
      .appendPattern("X")
      .toFormatter();
    System.out.println(rfc3339Format.withZone(ZoneOffset.UTC).format(Instant.ofEpochMilli(time)));
  }
}

fmachado avatar Jun 26 '17 22:06 fmachado

@majst01 IMO, org.influxdb.impl.TimeUtil should be deprecated and removed later. The developer should be responsible for dealing with date/time conversion. What do you think?

Meanwhile, a patch could be applied by replacing SimpleDateFormat with DateTimeFormatterBuilder and fractions of millisecs.

fmachado avatar Jun 26 '17 22:06 fmachado