我只是不太明白在下面的例子中应该使用哪一种:
我们有一个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 (通用协调时间,传统上称为格林威治标准时间(格林尼治标准时间))。指定了显式时区的输入值将使用该时区的适当偏移量转换为UTC。如果输入字符串中没有指定时区,则假定它位于由系统的TimeZone参数指示的时区,并使用时区的偏移量将其转换为UTC。
这意味着我在保存任何日期/时间信息时应该很好。
但是这对我的OfferEntity和我在OfferController中定义的其他端点意味着什么?
@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就会采取任何措施,但为什么我们会在意呢?
那么这两种选择中哪一种更好,为什么我会选择一种而另一种?
发布于 2019-10-23 09:17:22
以下链接中的答案比我以往任何时候都能更好地解释它。答案涉及Java中所有不同的日期/时间类,以及它们与sql类型的关系。
一个简短的总结:类Instant和ZonedDateTime (以及OffsetDateTime)代表着相同的东西:瞬间。区别在于ZonedDateTime和OffsetDateTime提供了关于时区或时差的额外上下文和功能,而Instant没有指定时区或偏移量。这可能导致差异,特别是当涉及到夏令时。例如,以以下代码片段为例:
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日有一个额外的小时。当我们转换为即时的时区信息丢失,所以添加一天将只增加24小时。
LocalDateTime是一个完全不同的野兽。它表示没有时区信息的日期和时间。它并不代表时间上的某个时刻。它对于写诸如“圣诞节早晨从12月25日00:00:00开始”之类的东西很有用。无论时区如何,这都是正确的,因此ZonedDateTime或Instant是不合适的。
https://stackoverflow.com/questions/52690684
复制相似问题