对于以下示例,我只是不太了解应该使用这两个中的哪一个:
我们有一个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 docs我们知道:
对于
timestamp with time zone
,内部存储的值始终以UTC(世界标准时间,通常称为格林威治标准时间,GMT)表示。使用该时区的适当偏移量,将指定了明确时区的输入值转换为UTC。如果在输入字符串中未指定时区,则假定该时区位于系统的TimeZone
参数所指示的时区中,并使用时区时区的偏移量转换为UTC。
这表示在保留任何日期/时间信息时我应该没事。
但这对我的OfferEntity
和我在OfferController
中定义的REST端点意味着什么?
@Entity
@Table(name = "offer")
public class OfferEntity {
@Column(name = "available", nullable = false)
private ZonedDateTime availableDay;
}
vs
@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
会花费任何时间,只要设置了时区即可,但是为什么我们会关心呢?
那么,哪两个是更好的选择,为什么我要选择一个呢?
答案 0 :(得分:0)
以下链接中的答案比以往任何时候都可以更好地解释它。答案进入Java中所有不同的日期/时间类,以及它们与sql类型的关系。
What's the difference between Instant and LocalDateTime?
简短摘要: 类Instant和ZonedDateTime(以及OffsetDateTime) 代表同一件事:片刻。区别在于 ZonedDateTime和OffsetDateTime提供额外的上下文和功能 关于时区或时区偏移,而“即时”没有时区或 指定的偏移量。这可能会导致差异,尤其是在涉及夏时制的情况下。例如,采用以下代码段:
ZonedDateTime z1 = zonedDateTime.of(LocalDateTime.of(2019,10,26,6,0,0),ZoneId.of("Europe/Amsterdam"));
Instant i1 = z1.plus(1,ChronoUnit.DAYS).toInstant();
Instant i2 = z1.toInstant().plus(1,ChronoUnit.DAYS);
System.out.println(i1);
System.out.println(i2);
结果将是这样:
2019-10-27T05:00:00Z
2019-10-27T04:00:00Z
差异源自以下事实:在阿姆斯特丹时区,10月27日有一个额外的小时。当我们转换为Instant时,时区信息会丢失,因此添加一天只会增加24小时。
LocalDateTime完全是另一种野兽。它代表一个日期 和时间,没有时区信息。它不代表 这一刻。对于写“圣诞节”之类的东西很有用 早上从12月25日00:00:00开始。 时区,因此ZonedDateTime或Instant不适合。