0

I have a rest API with an input value which is an epoch. However, storing as an Instant ignores the nanos, thus storing it as some date in the future (I think). I could be storing them in the wrong type also as had thought about storing them as a long either.

Example: From the input of 683124845000 I am expecting a date and time in 1991. It is converted to +23617-05-13T13:23:20Z.

public class Booking {
    private Instant epoch;
    private String email;
}

The JSON input is:

{
  "epoch": "683124845000", 
  "email": "email@email.com"
}

Currently, I just have a controller that returns OK regardless of input as I am modeling the input.

@PostMapping("/booking")
    public ResponseEntity createBooking(@RequestBody Booking booking) {
        return ResponseEntity.ok().build();
    }
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Droid_Interceptor
  • 613
  • 3
  • 14
  • 37
  • 1
    What is the expected result from 683124845000? Asking because the number looks funny if it was supposed to denote a point in time this year or last year. If milliseconds since the epoch it would denote 1991-08-25T12:54:05Z. Is that it? – Ole V.V. Jan 29 '23 at 12:33
  • That 1991 time is the expected time. It's from a randomly generate epoch with milliseconds – Droid_Interceptor Jan 29 '23 at 15:35

2 Answers2

1

The default Instant serializer is expecting the epoch to be in seconds. Here are the following solutions:

  1. Use long or Long to store the epoch.
  2. Change your API to expect seconds.
  3. Create custom serializer / deserializer.

Custom serializer / deserializer implementation:
(Assuming you want to use milliseconds for your API since the epoch in the question seemed to be in milliseconds)

Serializer

public class CustomInstantSerializer extends JsonSerializer<Instant> {

    @Override
    public void serialize(Instant value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        long epoch = value.toEpochMilli();
        gen.writeNumber(epoch);
    }

}

Deserializer

public class CustomInstantDeserializer extends JsonDeserializer<Instant> {

    @Override
    public Instant deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
        long epoch = jp.getLongValue();
        return Instant.ofEpochMilli(epoch);
    }

}

Then wiring the serializer / deserializer to the field:

public class Booking {

    @JsonSerialize(using = CustomInstantSerializer.class)
    @JsonDeserialize(using = CustomInstantDeserializer.class)
    private Instant epoch;

    private String email;

}
origeva
  • 185
  • 9
0

To store the epoch value correctly, you can change the data type of the epoch field in the Booking class to long.

Example:

public class Booking {
private long epoch;
private String email;
}

Then in the controller, you can convert the string value from the request body to a long using Long.parseLong() method.

Example:

@PostMapping("/booking")
public ResponseEntity createBooking(@RequestBody Booking booking) {
booking.setEpoch(Long.parseLong(booking.getEpoch()));
return ResponseEntity.ok().build();
}
Razib
  • 10,965
  • 11
  • 53
  • 80