¿Cómo almacenar DateTime en formato UTC con Java 8?

Oct 01 2020

Versión Spring Boot 2.3.1.

Tengo la siguiente clase:

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

Después de almacenar el evento localmente, tengo que enviarlo al backend. Por ahora, el envío de datos se ve así:

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

Sin embargo, el backend espera el siguiente formato de datos:

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

La idea principal de la aplicación es enviar eventos al backend .
Entonces necesito enviar los datos exactos que esperan.

Después de mirar las siguientes respuestas:

  • ¿Qué es este formato de fecha? 2011-08-12T20: 17: 46.384Z
  • Cómo convertir LocalDateTime a “yyyy-MM-dd'T'HH:mm:ss'Z'”formato

¿No puedo entender cómo exactamente tengo que almacenar este campo localmente?

¿Necesito cambiar a OffsetDateTimeo ZonedDateTime?

Además, quiero usar Java 8 Date Time API .

Para controlar la configuración de la fecha y la hora, utilice la siguiente clase de utilidad:

@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 en cualquier lugar donde se deba crear la nueva fecha y hora.

¿Cuál es la mejor estrategia para almacenar el formato de hora de datos ISO 8601 con Java 8 y Spring Boot?

Respuestas

deHaar Oct 01 2020 at 22:08

El problema LocalDateTimeaquí es que simplemente no almacena un desplazamiento o una zona horaria, lo que significa que no puede formatearlo en un formato Stringque contenga un Zpara UTC respectivamente un desplazamiento de +00:00.

Usaría un ZonedDateTimeque tendrá un desplazamiento y una identificación de zona y el formato está usando un específico DateTimeFormatter(no sé exactamente cómo manejará esto su anotación).

Aquí hay un pequeño ejemplo simple de Java:

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

El resultado de este pequeño ejemplo fue (hace unos segundos):

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

Creo que puedes usar ese patrón en la @JSONFormatanotación. No estoy del todo seguro, pero no puedo buscarlo ahora.