Answers:
这在很多地方说,但我认为这值得一提的总是当我们比较timestamp with time zone
与timestamp without time zone
类型:在timestamp WITH time zone
不将存储时区与时间戳一起信息。它所做的是将所有数据存储在UTC时区中,如docs中所述:
对于带时区的时间戳,内部存储的值始终以UTC(通用协调时间,通常称为格林威治标准时间,GMT)表示。使用该时区的适当偏移量,将指定了明确时区的输入值转换为UTC。如果在输入字符串中未指定时区,则假定该时区位于系统的TimeZone参数指示的时区中,并使用时区时区的偏移量转换为UTC。
在某些timestamp WITHOUT time zone
情况下(1)一切都在同一时区或(2)应用程序层处理时区并仅将所有内容存储在某个时区(通常是UTC)中,这种方法被认为对某些人有效。但这也被认为是一种反模式,因为(1)的正确解决方案是将TimeZone设置配置为系统的给定时区,并且(2)已解决,因为PostgreSQL已将所有内容存储在同一时区(世界标准时间)。
现在,有了这两个功能,我只有一个很好的理由来使用timestamp WITHOUT time zone
。那是您将来要存储事件的时间,到那时我们必须触发某种警报。timestamp WITH time zone
如果且仅当该地区的有关时区的法律所定义的规则从未改变时,这可能是有益的。更改的最常见规则是关于是否采用日光节约时间(DST)。
例如,假设您正在2013-06-15
(尚未在DST中)安排某个事件发生的时间2013-01-15 10:00
(该事件已经在DST中发生),并且2013-06-15
指定您所在的地区采用DST;但是在那之后的一段时间,政府更改了规则,并说您所在的地区将不再使用DST,如果您使用,并保持TZ配置最新,则您的计划时间突然变成2013-01-15 11:00
(而不是10:00
)timestamp WITH time zone
。当然,如果您跟踪自己感兴趣的地区/时区中的规则更改并更新受影响的记录,那么您可能还会注意到也可以使用时区来处理此类情况。
值得一提的是,某些地区的确会经常更改这些规则(例如在巴西,某些州-而不是整个国家-经常会更改),但在大多数情况下,更改的时间很早,因此您的用户只会受到距离很远的活动的影响当前时间。
话虽如此,我只有一个建议。如果您确实在不同时区有用户,日志或其他任何内容,请存储他们来自某个地方的时区,然后选择并使用timestamp with time zone
。这样,您可以(1)针对不同来源(与时区无关)相互交叉发生事件,并且(2)显示事件发生的原始时间(时钟时间)。
是。有一些用例TIMESTAMP WITHOUT TIME ZONE
。
TIMESTAMP WITH TIME ZONE
而不是WITHOUT
。 TIMESTAMP WITHOUT TIME ZONE
值不是时间轴上的一点,不是实际时刻。它们代表了有关潜在时刻的粗略想法,可能涉及时间轴上大约26-27小时(全球时区范围)内的时间点。在您应用时区或UTC偏移之前,它们没有真正的意义。
例如,假设您需要记录假期/圣日的开始。
Table: holiday_
Column: year_ Type: SMALLINT
Column: description_ Type: VARCHAR
Column: start_ Type: TIMESTAMP WITHOUT TIME ZONE
要记录圣诞节在今年12月25日午夜之后开始的事实,我们需要说不2016-12-25 00:00:00
带任何时区。圣诞老人那天凌晨,他在午夜之后访问NZ奥克兰,因为这是全球最早的午夜之一。然后,随着下一个午夜的到来,他向西行驶,不久便到达了菲律宾。然后,驯鹿向西方向移动,在午夜到达印度,恰好发生在奥克兰午夜后的几个小时。更晚之后仍是巴黎FR的午夜,再晚仍是加利福尼亚州蒙特利尔的午夜。圣诞老人的所有这些拜访都是在不同的时间发生的,但是每个地点都在午夜后不久发生,具体时间取决于每个地方的午夜。
因此2016-12-25 00:00:00
,在圣诞节开始时没有任何时区的录音内容丰富,合法,但模糊不清。在您说“奥克兰的圣诞节”或“蒙特利尔的圣诞节”之前,我们没有特定的时间。如果您每次记录雪橇降落时都在记录实际时刻,则应使用TIMESTAMP WITH TIME ZONE
而不是WITHOUT
类型。
与圣诞节相似的是除夕。当纽约的时代广场舞会落下时,西雅图的人们仍在冷藏香槟,准备派对喇叭。然而,我们将记录的想法新年的时刻,作为2017-01-01 00:00:00
一个TIMESTAMP WITHOUT TIME ZONE
。相反,如果我们想记录何时纽约落下球,或者西雅图人何时鸣喇叭,我们将使用TIMESTAMP WITH TIME ZONE
(而不是WITHOUT
)记录这些实际时刻,彼此间隔三个小时。
另一个示例可能是记录涉及不同位置的挂钟时间的策略。假设我们在底特律,杜塞尔多夫和德里都有工厂。如果我们说在所有三个工厂中,第一个班次从上午6点开始,在上午11:30午餐休息,则可以记录为TIMESTAMP WITHOUT TIME ZONE
。同样,此信息以模糊的方式很有用,但在我们应用时区之前不会指示特定的时刻。东方较新的一天到来了。因此,德里工厂将是第一个早上6点开放的工厂。几个小时后,杜塞尔多夫工厂在早上6点开始工作。但是底特律工厂要等到六个小时后才早上6点才真正开业。
将这个想法(关于通常何时开始工厂倒班)与每个工厂工人何时开始在特定一天开始倒班的历史事实进行对比。计时是一个真实的时刻,是时间轴上的实际点。因此,我们会将其记录在type列中,TIMESTAMP WITH TIME ZONE
而不是WITHOUT
type中。
因此,是的,存在合法的用例TIMESTAMP WITHOUT TIME ZONE
。但是根据我在商务应用程序方面的经验,它们相对很少见。在业务中,我们倾向于关心实际时刻:发票何时真正到达,合同何时确切生效,银行交易何时执行。因此,在这种常见情况下,我们需要TIMESTAMP WITH TIME ZONE
类型。
有关更多讨论,请参见我对类似问题的答案,我应该存储UTC时间戳还是本地时间以进行轮班
请注意,Postgres特别是从不保存插入时间戳时指定的时区信息。
TIMESTAMP WITH TIME ZONE
TIMESTAMP WITH TIME ZONE
是TIMESTAMP WITH RESPECT FOR TIME ZONE
。TIMESTAMP WITHOUT TIME ZONE
SQL标准几乎没有涉及日期时间数据类型和行为的问题。因此,数据库在处理日期时间方面差异很大。
21:00
)
我想为此添加另一种观点,这与其他答案中的大部分内容背道而驰。我认为timestamp with time zone
几乎没有有效的用例,timestamp without time zone
因此通常应优先使用。
首先,您必须了解“无处不在的UTC”模式,通常建议对没有特殊要求的所有应用程序使用该模式。这仅表示您的应用程序应始终无时无刻地以UTC表示其所有时间戳。当然,您将向用户显示本地日期/时间,但是其想法是在渲染视图时在程序的最边缘转换它们。这是将UTC时间戳(您可能已从数据库加载)和用户时区(可能来自浏览器)组合到本地时间戳的正确位置。
如果您遵循此模式,timestamp with time zone
则为反模式。这种类型的作用是使PostgreSQL在读取和写入时间戳时根据您的PostgreSQL TimeZone
会话变量执行时区转换。您没有在应用程序的最边缘处理时区,而是将它们引入了它的核心,并与数据库进行了通信。您必须注意始终始终TimeZone
正确配置PostgreSQL ,这会增加另一个不必要的失败和混乱点。
为了什么 如果您遵循UTC无处不在模式,则您的应用程序无论如何都只有UTC时间戳。那么,为什么要让您的数据库对它们进行时区转换呢?您可以简单地将它们存储在timestamp without time zone
列中,并像对待UTC一样对待它。没有转换,没有时区,没有并发症。
Instance
NodaTime / JodaTime中的时间戳)的客户端类型。您基本上是在描述几乎要遵循“无处不在的UTC”的情况,或者有点遵循的情况
timestamptz
。这种类型的重点是执行时区转换,作为对PostgreSQL进行读写的值(在数据库内部,时间戳始终保存为UTC)。始终将会话时区设置为UTC会有效地禁用这些转换,那么为什么要使用它timestamptz
呢?换句话说,如果数据库中的值是UTC,而进出数据库的值始终是UTC,那么为什么数据库中根本没有时区意识?
该date
时间戳也没有包括时区信息,但有很多人使用它。
当然,这本身并不是答案。
它的有效使用timestamp
和date
任何时间戳和日期,它总是在同一个时区,或在相对于一些已知的时区存储。
如果时区始终相同或隐式,则存储时区要比不存储时区更重要(冗余信息)。
时间戳还可用于存储技术信息,例如在应用程序日志中使用的信息或用于性能测量的信息。在这种情况下,时区也可能不重要。
相反,如果您正在设计或在分布式系统上或在其中系统的各个部分分布在不同时区的任何系统中工作,则可以将其视为不使用的反模式timestamp with timezone
,尽管某些系统可能被设计为可以运行在一个时区,例如UTC。在这种情况下,时区逻辑可能会被推到应用程序层中-但我认为这是一种反模式,是的。
timestamp without timezone
,但是它能为我买任何东西吗?否则,如果timestamp with timezone data
类型总是相等或更合适,为什么还要打扰呢?
timestamp without timezone
也会更快,但这仅在您要处理数十亿行时才重要……
如果您的应用程序限于一个时区,则似乎很想在本地时间存储和处理日期/时间,但是我认为这是一个错误。
当从夏令时切换回标准时间时,将重复本地时间的一小时(假设时差为一小时)。我住的地方通常发生在凌晨2点左右,因此本地时间运行在01:58、01:59、01:00,并且在重复的小时结束时才前进到02:00。
如果您尝试使用本地时间按时间排序事件,则意味着两个小时内的事件混合在一起,并且不会按照实际发生的顺序显示。
相比之下,UTC则没有此问题,订单整齐。因此,即使仅使用一个时区,您也希望数据库以UTC存储和处理时间,并转换为本地时间或从本地时间转换为输入/显示。这是TIMESTAMP WITH TIME ZONE的行为。