PostgreSQL/JDBC和时间戳与时间戳

我最近在JPA经历了很多处理时间戳的痛苦。我发现,我的很多问题都通过在字段中使用TIMESTAMP而不是TIMESTAMP得到了解决。我的服务器是UTC,而JVM是PST。如果使用没有时区的时间戳,JPA几乎不可能在数据库中对UTC值进行规范化

对我来说,我使用这些字段来表示诸如“用户是什么时候创建的”、“他们上次使用设备是什么时候”、“他们最后一次收到警报是什么时候”等内容。这些通常是事件,因此它们是时间类值的实例。因为他们现在会在timestamtz之前查询,所以如果我不需要他们,我可以随时查询他们的特定区域

所以我的问题是,对于Java/JPA/PostgreSQL服务器,我什么时候希望在TIMESTAMP上使用TIMESTAMP?它的用例是什么?现在我很难理解为什么我要使用时间戳,正因为如此,我担心我没有把握它的价值

一般使用时间戳

博士后专家大卫·E·惠勒(David E.Wheeler)在一篇博文中给出了以下建议,该博文的标题说明了一切:
始终将时间戳与时区(timestampz)结合使用

如果要跟踪实际时刻、时间轴上的特定点,请使用带时区的时间戳

一个例外:分区

由于技术限制,Wheeler唯一的例外是在时间戳上进行分区。对我们大多数人来说,这是一个罕见的例外

有关分区的信息,请参阅doc和Wiki

用词不当

数据类型名称带时区的时间戳不带时区的时间戳是误称。在两种情况下,日期时间值都存储在UTC(无时区偏移)。把前一句再读一遍UTC,始终。带有时区的短语表示“注意时区”,而不是“将时区存储在此值旁边”。两种类型之间的区别在于,在存储(插入或更新)或检索(选择查询)期间是否应应用任何时区。(这种行为是为Postgres描述的——其他数据库在这方面差异很大。)

更准确地说,应该说没有时区的时间戳存储没有时区的日期时间值。但如果没有任何时间框架参考,任何查看该数据的人都必须假设(希望、祈祷?)这些值是UTC。但同样,你几乎不应该使用这种类型

仔细阅读文档,并做一些实验来阐明你的理解

未分区

如果要存储可能时间而不是特定时刻的一般概念,请使用另一种类型,不带时区的时间戳

例如,今年的圣诞节从2017年12月25日的第一刻开始。这将是2017-12-25T
00:00:00
没有时区指示器,也没有与UTC的偏移。这个值只是一个关于可能时刻的模糊概念。在我们应用时区(或偏移量)之前,它没有任何意义。因此,我们使用不带时区的时间戳来存储它

圣诞老人的特别活动后勤部门将时区作为其计划过程的一部分。目前最早的时区是太平洋/基里巴斯,比UTC早14小时。精灵们安排圣诞老人第一次到达那里。精灵们制定了一个飞行计划,把驯鹿带到其他时区,在那里午夜很快就会到来,比如太平洋/奥克兰。随着每个区域午夜的到来,他们继续向西行进。在亚洲/加尔各答晚了几个小时,在欧洲/巴黎晚了几个小时,在美洲/蒙特利尔晚了几个小时,依此类推

每一个特定的传递时刻都会被精灵们记录下来,使用带有时区的,而圣诞节的一般概念会被存储为不带时区的

在没有时区的商业应用程序中,的另一个用途是将约会安排在几周之外。世界各地的政客都有一种莫名其妙的偏好,那就是打乱时间,重新定义时区规则。他们加入夏令时(DST),离开DST,在不同的日期开始DST,或在不同的日期结束DST,或将时钟移动15分钟或半小时。所有这些都是土耳其、美国、俄罗斯、委内瑞拉和其他国家在过去几年中所做的

政客们经常在没有事先警告的情况下做出这些改变。因此,如果您计划在13:00进行为期六个月的牙科预约,则可能应将其存储为不带时区的时间戳,否则政客可能会有效地将您的预约更改为中午、下午2点或13:30

发表评论