Я просто не совсем понимаю, какой из этих двух я должен использовать для следующего примера:
У нас есть 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
займет что-нибудь, если в нем установлен часовой пояс, но зачем нам это?
Итак, какой из этих двух вариантов лучше, и почему я выбрал один из них?