Как сохранить DateTime в формате UTC с Java 8?

Oct 01 2020

Версия Spring Boot 2.3.1.

У меня следующий класс:

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

После локального сохранения события я должен отправить его на бэкэнд. На данный момент отправка данных выглядит так:

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

Однако серверная часть ожидает следующего формата данных:

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

Основная идея приложения - отправлять события на бэкэнд .
Поэтому мне нужно отправить точные данные, которых они ожидают.

Посмотрев на следующие ответы:

  • Что это за формат даты? 2011-08-12T20: 17: 46.384Z
  • Как преобразовать LocalDateTime в “yyyy-MM-dd'T'HH:mm:ss'Z'”формат

Не могу понять, как именно я должен хранить это поле локально?

Мне нужно перейти на OffsetDateTimeили ZonedDateTime?

Кроме того, я хочу использовать Java 8 Date Time API .

Для управления настройкой даты и времени используйте следующий служебный класс:

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

Я использую его везде, где нужно создать новую дату и время.

Какова лучшая стратегия для хранения формата времени данных ISO 8601 с Java 8 и Spring Boot?

Ответы

deHaar Oct 01 2020 at 22:08

Проблема LocalDateTimeздесь в том, что он просто не хранит смещение или часовой пояс, что означает, что вы не можете отформатировать его до String, содержащего Zдля UTC, соответственно смещение +00:00.

Я бы использовал a, ZonedDateTimeкоторый будет иметь смещение, а идентификатор зоны и формат используют определенный DateTimeFormatter(точно не знаю, как ваша аннотация справится с этим).

Вот небольшой простой пример 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")));
}

Результат этого небольшого примера был (несколько секунд назад):

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

Думаю, вы можете использовать такой узор в @JSONFormatаннотации. Не совсем уверен, но сейчас не могу посмотреть.