Come memorizzare DateTime in formato UTC con Java 8?

Oct 01 2020

Versione Spring Boot 2.3.1.

Ho la seguente classe:

@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;

Dopo aver archiviato l'evento in locale devo inviarlo al backend. Per ora, l'invio di dati è simile a:

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

Tuttavia, il backend prevede il seguente formato di dati:

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

L'idea principale dell'applicazione è inviare eventi al backend .
Quindi devo inviare i dati esatti che si aspettano.

Dopo aver esaminato le seguenti risposte:

  • Qual è questo formato di data? 2011-08-12T20: 17: 46.384Z
  • Come convertire LocalDateTime in “yyyy-MM-dd'T'HH:mm:ss'Z'”formato

Non riesci a capire esattamente come devo memorizzare questo campo localmente?

Devo passare a OffsetDateTimeo ZonedDateTime?

Inoltre, desidero utilizzare Java 8 Date Time API .

Per controllare l'impostazione della data e dell'ora, utilizzare la seguente classe di utilità:

@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();
    }
}

Lo uso ovunque sia necessario creare la nuova data e ora.

Qual è la strategia migliore per archiviare il formato data time ISO 8601 con Java 8 e Spring Boot?

Risposte

deHaar Oct 01 2020 at 22:08

Il problema con LocalDateTimequi è che semplicemente non memorizza un offset o un fuso orario, il che significa che non puoi formattarlo in un Stringche contiene un Zper UTC rispettivamente un offset di +00:00.

Vorrei usare un ZonedDateTimeche avrà un offset e un id di zona e il formato sta usando uno specifico DateTimeFormatter(non so esattamente come la tua annotazione gestirà questo).

Ecco un piccolo esempio Java semplice:

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")));
}

L'output di questo piccolo esempio è stato (alcuni secondi fa):

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

Penso che tu possa usare un tale schema nell'annotazione @JSONFormat. Non del tutto sicuro, ma non posso cercarlo ora.