Como armazenar DateTime no formato UTC com Java 8?

Oct 01 2020

Versão do Spring Boot 2.3.1.

Eu tenho a seguinte aula:

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

Depois de armazenar o evento localmente, tenho que enviá-lo para o backend. Por enquanto, o envio de dados se parece com:

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

No entanto, o back-end espera o seguinte formato de dados:

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

A ideia principal do aplicativo é enviar eventos para o backend .
Portanto, preciso enviar os dados exatos que eles estão esperando.

Depois de olhar as seguintes respostas:

  • Qual é este formato de data? 2011-08-12T20: 17: 46.384Z
  • Como converter LocalDateTime para o “yyyy-MM-dd'T'HH:mm:ss'Z'”formato

Não consigo entender como exatamente tenho que armazenar este campo localmente?

Eu preciso mudar para OffsetDateTimeou ZonedDateTime?

Além disso, desejo usar a API Java 8 Date Time .

Para controlar a configuração de data e hora, use a seguinte classe de utilitário:

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

Eu o uso em qualquer lugar onde a nova data e hora deva ser criada.

Qual é a melhor estratégia para armazenar o formato de hora de dados ISO 8601 com Java 8 e Spring Boot?

Respostas

deHaar Oct 01 2020 at 22:08

O problema LocalDateTimeaqui é que ele simplesmente não armazena um deslocamento ou fuso horário, o que significa que você não pode formatá-lo para um Stringque contenha um Zpara UTC respectivamente um deslocamento de +00:00.

Eu usaria um ZonedDateTimeque terá um deslocamento e um id e formato de zona usando um específico DateTimeFormatter(não sei exatamente como sua anotação vai lidar com isso).

Aqui está um pequeno exemplo simples 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")));
}

O resultado deste pequeno exemplo foi (alguns segundos atrás):

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

Acho que você pode usar esse padrão na @JSONFormatanotação. Não tenho certeza absoluta, mas não posso pesquisar agora.