Мгновенный против ZonedDateTime - PullRequest
0 голосов
/ 07 октября 2018

Я просто не совсем понимаю, какой из этих двух я должен использовать для следующего примера:

У нас есть OfferEntity, в котором есть член availableDay, который является датой, на которую предложениеимеется в наличии.

Теперь таблица будет выглядеть примерно так:

CREATE TABLE IF NOT EXISTS offer (
  created   timestamp with time zone NOT NULL DEFAULT NOW(),
  id        BIGSERIAL PRIMARY KEY,
  available timestamp with time zone
);

Из Документов PostgreSQL мы знаем, что:

Для timestamp with time zone, внутренне сохраненное значение всегда в UTC (универсальное координированное время, традиционно известное как среднее время по Гринвичу, GMT).Входное значение с указанным явным часовым поясом преобразуется в UTC с использованием соответствующего смещения для этого часового пояса.Если во входной строке не указан часовой пояс, предполагается, что он находится в часовом поясе, указанном системным параметром TimeZone, и преобразуется в UTC с использованием смещения для часового пояса.

Что означает, что я должен быть в порядке, когда дело доходит до сохранения любой информации о дате / времени.

Но что это значит для моих OfferEntity и конечных точек REST, которые я определяю в OfferController?

@Entity
@Table(name = "offer")
public class OfferEntity {    
    @Column(name = "available", nullable = false)
    private ZonedDateTime availableDay;
}

против

@Entity
@Table(name = "offer")
public class OfferEntity {    
    @Column(name = "available", nullable = false)
    private Instant availableDay;
}

Из того, что я понял - это не должно иметь значения.В любом случае PostgreSQL хранит все как UTC, поэтому я должен иметь возможность принимать Instant или ZonedDateTime, верно?Напишите что-нибудь -> UTC.Прочтите еще раз -> все еще UTC.

Даже клиент не сможет заметить разницу:

@RequestMapping(value = "/hello", method = RequestMethod.GET)
public Object hello() {

    class Hello {
        public Instant instant = Instant.now();
        public ZonedDateTime zonedDateTime = ZonedDateTime.now();
        public ZonedDateTime viennaTime = ZonedDateTime.now(ZoneId.of("GMT+2"));
        public LocalDateTime localDateTime = LocalDateTime.now();
    }

    return new Hello();
}

Вернется:

{
  "instant":       "2018-10-07T15:30:08.579Z",
  "zonedDateTime": "2018-10-07T15:30:08.579Z",
  "viennaTime":    "2018-10-07T17:30:08.579+02:00",
  "localDateTime": "2018-10-07T15:30:08.579",
}

Но тамдолжно быть, решающее отличие, которое я, видимо, не вижу.


Есть два различия, которые я могу разглядеть.Кажется, что Spring не имеет проблемы с преобразованием "2018-10-07T15:30:08.579Z" в Instant объект, но не может этого сделать, если я изменяю тип на ZonedDateTime.По крайней мере, из коробки.

@RequestMapping("/places/{placeId}/offers", method = RequestMethod.GET)
public List<OfferDto> getOffers(
        @PathVariable(name = "placeId") Long placeId,
        @RequestParam(name = "date") ZonedDateTime date) {
    return this.offerService.getOffers(placeId, date);
}

Другое отличие состоит в том, что, если я использую Instant, я заставляю своих клиентов сначала конвертировать все свои строки даты / времени в UTC.Поэтому любому клиенту сначала нужно будет myDate.toUTCString().ZonedDateTime займет что-нибудь, если в нем установлен часовой пояс, но зачем нам это?


Итак, какой из этих двух вариантов лучше, и почему я выбрал один из них?

...