2

Spring Boot version 2.3.1.

I have the following class:

@Data
@Entity
@NoArgsConstructor
public class CarParkEvent implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Enumerated(EnumType.STRING)
    private EventType eventType;

    @Column(columnDefinition = "TIMESTAMP")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createdAt;

After storing the event locally I have to send it to the backend. For now, sending data looks like:

"createdAt" : "2020-10-01T17:15:23.481"

However, backend expects the following data format:

"createdAt" : "2020-10-01T17:15:23Z"

The main idea of the application is to send events to the backend.
So I need to send exact data which they are expecting.

After looking at the following answers:

Could not understand how exactly I have to store this field locally?

Do I need to shift to OffsetDateTime or ZonedDateTime?

Also, I want to use Java 8 Date Time API.

For controlling date time setting use following utility class:

@Slf4j
@UtilityClass
public class TimeClock {

    private LocalDateTime dateTime;

    public LocalDateTime getCurrentDateTime() {
        return (dateTime == null ? LocalDateTime.now() : dateTime);
    }

    public void setDateTime(LocalDateTime date) {
        log.info("Set current date for application to: {}", date);
        TimeClock.dateTime = date;
    }

    public void resetDateTime() {
        log.info("Reset date for the application");
        TimeClock.dateTime = LocalDateTime.now();
    }

    /**
     * Different formats for current dateTime.
     */
    public LocalDate getCurrentDate() {
        return getCurrentDateTime().toLocalDate();
    }

    public LocalTime getCurrentTime() {
        return getCurrentDateTime().toLocalTime();
    }
}

I use it anywhere where the new date-time should be created.

What is the best strategy for storing ISO 8601 data time format with Java 8 and Spring Boot?

catch23
  • 17,519
  • 42
  • 144
  • 217

1 Answers1

0

The problem with LocalDateTime here is that it simply doesn't store an offset or a time zone, which means you cannot format it to a String that contains a Z for UTC respectively an offset of +00:00.

I would use a ZonedDateTime which will have an offset and a zone id and format is using a specific DateTimeFormatter (don't exactly know how your annotation will handle this).

Here's a small plain Java example:

public static void main(String[] args) {
    // get an example time (the current moment) in UTC
    ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
    // print its toString (implicitly)
    System.out.println(now);
    // format it using a built-in formatter
    System.out.println(now.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
    // or define a formatter yourself and print the ZonedDateTime using that
    System.out.println(now.format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssz")));
}

The output of this small example was (some seconds ago):

2020-10-01T15:06:16.705916600Z
2020-10-01T15:06:16.7059166Z
2020-10-01T15:06:16Z

I think you can use such a pattern in the @JSONFormat annotation. Not entirely sure, but cannot look it up now.

catch23
  • 17,519
  • 42
  • 144
  • 217
deHaar
  • 17,687
  • 10
  • 38
  • 51
  • what will be prefered way of storing `ZonedDateTime` with JPA at this case? – catch23 Oct 01 '20 at 15:11
  • @nazar_art some answer to [this question](https://stackoverflow.com/questions/54840769/how-to-persist-localdate-with-jpa) mentions JPA 2.2 added support for some classes of `java.time` and it has some links. Unfortunately, `ZonedDateTime` seems unsupported. – deHaar Oct 01 '20 at 15:24
  • 1
    looks like it should be supported for this case. – catch23 Oct 02 '20 at 09:55