답변:
차이점은 날짜 / 시간 유형에 대한 PostgreSQL 설명서 에서 다룹니다 . 예, 치료 TIME또는 TIMESTAMP하나를 사이에 다릅니다 WITH TIME ZONE나 WITHOUT TIME ZONE. 값이 저장되는 방식에는 영향을 미치지 않습니다. 해석 방법에 영향을줍니다.
이러한 데이터 형식에 대한 표준 시간대의 영향은 문서에서 구체적 으로 다룹니다 . 차이점은 시스템이 가치에 대해 합리적으로 알 수있는 것과 다릅니다.
시간대를 값의 일부로 사용하면 값을 클라이언트에서 현지 시간으로 렌더링 할 수 있습니다.
값의 일부로 시간대가 없으면 명백한 기본 시간대는 UTC이므로 해당 시간대에 대해 렌더링됩니다.
동작은 최소한 세 가지 요소에 따라 다릅니다.
WITH TIME ZONE또는 WITHOUT TIME ZONE)이러한 요소의 조합을 다루는 예는 다음과 같습니다.
foo=> SET TIMEZONE TO 'Japan';
SET
foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP;
timestamp
---------------------
2011-01-01 00:00:00
(1 row)
foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP WITH TIME ZONE;
timestamptz
------------------------
2011-01-01 00:00:00+09
(1 row)
foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP;
timestamp
---------------------
2011-01-01 00:00:00
(1 row)
foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP WITH TIME ZONE;
timestamptz
------------------------
2011-01-01 06:00:00+09
(1 row)
foo=> SET TIMEZONE TO 'Australia/Melbourne';
SET
foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP;
timestamp
---------------------
2011-01-01 00:00:00
(1 row)
foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP WITH TIME ZONE;
timestamptz
------------------------
2011-01-01 00:00:00+11
(1 row)
foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP;
timestamp
---------------------
2011-01-01 00:00:00
(1 row)
foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP WITH TIME ZONE;
timestamptz
------------------------
2011-01-01 08:00:00+11
(1 row)
timestamp with time zone과 실제로 시간대 정보를 저장 하지 않는다는 것을 이해해야합니다 . 데이터 유형 문서 페이지에서이를 한눈에 확인할 수 있습니다. 두 유형 모두 같은 수의 옥텟을 차지하고 저장 범위의 값을 가지므로 시간대 정보를 저장할 공간이 없습니다. 페이지의 텍스트가이를 확인합니다. 잘못된 의미 : "tz없이"는 "데이터 삽입시 오프셋 무시"를 의미하고 "tz로"는 "UTC로 조정하기 위해 오프셋 사용"을 의미합니다. timestamp without time zone
참조 된 PostgreSQL 설명서보다 이해하기 쉽게 설명하려고합니다.
TIMESTAMP변형은 이름에서 제안하는 내용에도 불구하고 시간대 (또는 오프셋)를 저장 하지 않습니다 . 차이점은 저장 형식 자체가 아니라 저장된 데이터 (및 의도 된 응용 프로그램)의 해석에 있습니다.
TIMESTAMP WITHOUT TIME ZONE저장 현지 날짜 - 시간 (일명. 벽에 달력의 날짜와 벽 시계 시간). 표준 시간대는 PostgreSQL이 알 수있는 한 미지정입니다 (응용 프로그램이 무엇인지 알 수 있음). 따라서 PostgreSQL은 입력 또는 출력에서 표준 시간대 관련 변환을 수행하지 않습니다. 값을로 데이터베이스에 입력 '2011-07-01 06:30:30'한 후 나중에 표시 할 시간대에 상관이없는 경우에도 2011 년, 월 07, 일 01, 06 시간, 30 분 및 30 초 (일부 형식)로 표시됩니다. 또한, 모든 오프셋 또는 입력에 지정한 시간대는 PostgreSQL을 무시하므로 '2011-07-01 06:30:30+00'와 '2011-07-01 06:30:30+05'마찬가지로 동일합니다 '2011-07-01 06:30:30'. Java 개발자의 경우 :와 유사합니다 java.time.LocalDateTime.
TIMESTAMP WITH TIME ZONEUTC 타임 라인에 포인트를 저장합니다. 어떻게 보이는지 (시간, 분 등)는 시간대에 따라 다르지만 항상 실제 "실제 사건의 순간"과 같은 "물리적"순간을 나타냅니다. 입력은 내부적으로 UTC로 변환되어 저장되는 방식입니다. 이를 위해서는 입력의 오프셋을 알고 있어야합니다. 따라서 입력에 명시적인 오프셋이나 시간대 (예 :)가 포함되어 있지 '2011-07-01 06:30:30'않으면 PostgreSQL 세션의 현재 시간대에있는 것으로 간주됩니다. 그렇지 않으면 명시 적으로 지정된 오프셋 또는 시간대가 사용됩니다 (에서와 같이 '2011-07-01 06:30:30+05'). 출력은 PostgreSQL 세션의 현재 시간대로 변환되어 표시됩니다. Java 개발자의 경우 : java.time.Instant해상도는 낮지 만 JDBC 및 JPA 2.2에서는이를 매핑해야합니다 java.time.OffsetDateTime( java.util.Date또는java.sql.Timestamp 물론이야).
어떤 사람들은 두 TIMESTAMP변형이 UTC 날짜-시간을 저장 한다고 말합니다 . 내 생각에는 그렇게하는 것이 혼란 스럽습니다. TIMESTAMP WITHOUT TIME ZONE은 TIMESTAMP WITH TIME ZONEUTC 시간대로 렌더링되어 현지 날짜-시간과 동일한 연도, 월, 일,시, 분, 초 및 마이크로 초를 제공하는으로 저장됩니다. 그러나 UTC 해석에서 말하는 타임 라인의 요점을 나타내는 것은 아니며 현지 날짜-시간 필드가 인코딩되는 방식입니다. (실시간 시간대는 UTC가 아니기 때문에 타임 라인의 일부 점입니다. 우리는 그것이 무엇인지 알 수 없습니다.)
TIMESTAMP WITH TIME ZONE로 검색해도 아무런 문제가 없습니다 Instant. 둘 다 타임 라인의 한 지점을 UTC로 나타냅니다. Instant내 의견 OffsetDateTime으로는 더 많은 자체 문서화 가 선호 됩니다 .A TIMESTAMP WITH TIME ZONE는 항상 데이터베이스에서 UTC로 검색되고 A 는 항상 InstantUTC이므로 자연스럽게 일치하지만 OffsetDateTime다른 오프셋을 가질 수 있습니다.
OffsetDateTime는 매핑 된 Java 유형으로 만 언급 됩니다. Instance어딘가에서 비공식적으로 지원 되는지 확실하지 않습니다 .
'2011-07-01 06:30:30+00'하고 '2011-07-01 06:30:30+05'무시하지만 할 수 insert into test_table (date) values ('2018-03-24T00:00:00-05:00'::timestamptz);있으며 올바르게 utc로 변환합니다. 여기서 날짜는 시간대가없는 타임 스탬프입니다. 시간대가있는 타임 스탬프의 주요 가치가 무엇인지 이해하고 노력하고 있습니다.
::timestamptz. 당신의 문자열을 변환하는 것이로 TIMESTAMP WITH TIME ZONE, 그리고 추가로 변환 될 때 WITHOUT TIME ZONE, 즉 (어쩌면 UTC입니다) 세션 시간대에서 본 그 순간의 "벽에 달력"하루 벽 시계 시간을 저장합니다. 여전히 지정되지 않은 오프셋 (영역 없음)이있는 로컬 타임 스탬프 만됩니다.
여기 도움이 될만한 예가 있습니다. 시간대가있는 타임 스탬프가있는 경우 해당 타임 스탬프를 다른 시간대로 변환 할 수 있습니다. 기본 시간대가 없으면 올바르게 변환되지 않습니다.
SELECT now(),
now()::timestamp,
now() AT TIME ZONE 'CST',
now()::timestamp AT TIME ZONE 'CST'
산출:
-[ RECORD 1 ]---------------------------
now | 2018-09-15 17:01:36.399357+03
now | 2018-09-15 17:01:36.399357
timezone | 2018-09-15 08:01:36.399357
timezone | 2018-09-16 02:01:36.399357+03
timestamp을 timestamptz의미 하는지 이해해야합니다 . timestamptz"절대 시간 (UTC)" timestamp은 시계가 특정 시간대에서 보여준 것을 나타냅니다. 따라서 timestamptz시간대 로 변환 할 때이 절대 시점에서 시계가 뉴욕에서 무엇을 보여 주었습니까? 반면에 "변환" 할 때 뉴욕의 시계가 x를 표시했을 때 절대 시점이 무엇인지timestamp 묻고 있습니까?
AT TIME ZONE이미 이해하더라도 구조는, 자신의 티저 뇌입니다 WITH대의 WITHOUT TIME ZONE유형. 그것들을 설명하는 것은 호기심 많은 선택입니다. (: ( 타임 스탬프를 타임 스탬프 AT TIME ZONE로 변환 하고 그 반대도 마찬가지입니다. 정확히 알 수 없습니다.)WITH TIME ZONEWITHOUT TIME ZONE
now()::timestamp AT TIME ZONE 'CST''CST'구역의 시계가 현지 시계가 현재 표시되는 시간을 어떤 순간에 표시 할 것인지를 제외하고는 의미가 없습니다.