0

I've below code in java

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.joda.JodaModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.time.Instant;

public class Main {
    public static void main(String[] args) throws JsonProcessingException {
        Instant instant = Instant.now();
        System.out.println("java version " + System.getProperty("java.version"));
        System.out.println("java vendor " + System.getProperty("java.vendor"));
//        System.out.println(instant.truncatedTo(ChronoUnit.MILLIS));
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JodaModule());
        mapper.registerModule(new JavaTimeModule());
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        mapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, true);
        System.out.println(mapper.writeValueAsString(instant));
    }

}

when I run with java 8 I get below output -

java version 1.8.0_352
java vendor Azul Systems, Inc.
2023-07-15T07:27:49.588Z

when I run with java 11 I get below output -

java version 11.0.17
java vendor Azul Systems, Inc.
2023-07-15T07:08:15.457153Z

It is clearly java 11 has more precision than java 8 and it is causing schema change in the middleware downstream.

Is there any way to make this api call backward compatible?

user51
  • 8,843
  • 21
  • 79
  • 158

1 Answers1

0

If you just want a String with 3 digits of fractional seconds, you can make your own DateTimeFormatter and format the Instant with that:

// note that there are only 3 "S"
var formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSS'Z'")
    .withZone(ZoneOffset.UTC);
System.out.println(formatter.format(Instant.now()));

This will always produce 3 digits after the decimal dot, even if they are all 0.

If you actually want an Instant that is rounded to the nearest millisecond, use truncatedTo:

System.out.println(Instant.now().truncatedTo(ChronoUnit.MILLIS));

Instant.toString will use at most 3 decimal places for such Instants. Instant.toString uses the ISO_INSTANT formatter.

Sweeper
  • 213,210
  • 22
  • 193
  • 313