Home > Software engineering >  SpringBoot deserializing json instant to next day
SpringBoot deserializing json instant to next day

Time:10-27

So I observed how @FutureOrPresent was complaining for present date also. Debugging my code further

public class MyCustomDeserializer extends JsonDeserializer<Instant> {
    private DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd-MM-yyyy").withZone(ZoneOffset.UTC);

    @Override
    public Instant deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        LocalDate date = LocalDate.parse(p.getText(), fmt);
        Instant instant = date.atStartOfDay(ZoneId.of("UTC")).toInstant();
        return instant;
    }
}

Debugging gives me this state:

state

Any idea how this can be worked around? I'm in Asia/Kolkate zone if that helps

If I am passing current date in fromDate in the JSON file I'm getting this error:

fromDate Must Be Of Future Or Present

The POJO has this format

@JsonDeserialize(using = MyCustomDeserializer.class)
    @JsonSerialize(using = MyCustomSerializer.class)
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
    @NotNull(message = "Please provide From Date")
    @FutureOrPresent(message = "From Date Must Be Of Future Or Present")
    private Instant fromDate;

CodePudding user response:

You may get this response because you take the start of the day as the time of day and you do that in UTC.

Either the comparison uses start of day, too, but excludes equality or it uses the current time in UTC while you pass the start of day in UTC, which will never be a future time according to your description, it may be considered equal at best.

Try the following example and check if the result is considered past or passes the validation:

public static Instant deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
            // parse the JSON String (that's the date part)
    return LocalDate.parse(p.getText(), fmt)
                    // use your system's time of day
                    .atTime(LocalTime.now())
                    // shift the time zone afterwards
                    .atZone(ZoneId.of("UTC"))
                    // and return it as an Instant
                    .toInstant();
}

This approach will only make sense (to me, at the moment) if you get the date of today, it seems not appropriate to use the time of day of execution for some future date.

CodePudding user response:

The problem would be that you are using the time of the start of the day

if you use todays date that will always be in the past. If you use today and want an instant that will be in the future you can get an instant at the end of the day instead

LocalDateTime localDateTime= date.atTime(23, 59, 59); 
localDateTime.atZone( ZoneId.of("UTC")); 
localDateTime.toInstant();

This will give you an instant that most likely will be of today but also always in the future or present most likely

You could also use an instant that is a minute in the future instead of at the end of the day.

An instant that is of the current time may fail as it takes time for the request to travel to the destination and its nice to have a little buffer

  • Related