데이터 유형 timestamp
은의 짧은 이름입니다 timestamp without time zone
.
다른 옵션 timestamptz
은 짧습니다 timestamp with time zone
.
timestamptz
는 IS 원하는 날짜 / 시간 가족 유형은 그대로. 그것은 한 typispreferred
설정 pg_type
관련 수있는 :
내부 저장 및 시대
내부적으로 타임 스탬프는 디스크와 RAM에서 8 바이트 의 스토리지를 차지 합니다. Postgres epoch (2000-01-01 00:00:00 UTC)의 마이크로 초 수를 나타내는 정수 값입니다.
Postgres는 또한 UNIX 시대 (1970-01-01 00:00:00 UTC)에서 일반적으로 사용되는 UNIX 시간 계산 초 에 대한 기본 지식 을 갖추고 있으며이를 함수 to_timestamp(double precision)
또는 에서 사용합니다 EXTRACT(EPOCH FROM timestamptz)
.
소스 코드 :
* 타임 스탬프와 간격의 h / m / s 필드는 다음과 같이 저장됩니다
* 마이크로 초 단위의 int64 값 (한때 그들은
* 초 단위의 이중 값)
과:
/ * Unix 및 Postgres 계산에서 0 일의 율리우스 력 날짜 * /
#define UNIX_EPOCH_JDATE 2440588 / * == date2j (1970, 1, 1) * /
#define POSTGRES_EPOCH_JDATE 2451545 / * == date2j (2000, 1, 1) * /
마이크로 초 해상도는 초 동안 최대 6 개의 소수 자릿수로 변환됩니다.
timestamp
Postgres에 표준 시간대가 명시 적으로 제공되지 않았 음 을 알리는 값으로 입력 합니다. 현재 시간대가 가정됩니다. Postgres 는 실수로 추가 한 시간대 수정자를 무시 합니다!timestamp
[without time zone]
표시 시간이 변경되지 않습니다. 동일한 시간대 설정으로 모든 것이 정상입니다. 다른 시간대 설정의 경우 의미가 변경되지만 값 과 표시 는 동일하게 유지됩니다.
timestamptz
의 취급은 timestamp with time zone
미묘하게 다르다. 나는 여기에 매뉴얼을 인용한다 :
의 경우 timestamp with time zone
내부 저장된 값은 항상 UTC (Universal Coordinated Time ...)입니다.
대담한 강조 광산. 시간대 자체는 저장되지 않습니다 . UTC 타임 스탬프를 계산하는 데 사용되는 입력 수정 자이며, 추가 된 표준 시간대 오프셋과 함께 저장 될 로컬 시간을 계산하는 데 사용되는 출력 수정 자입니다. timestamptz
입력시 오프셋을 추가하지 않으면 세션의 현재 시간대 설정이 가정됩니다. 모든 계산은 UTC 타임 스탬프 값으로 수행됩니다. 둘 이상의 시간대를 처리해야하거나해야 할 경우을 사용하십시오 timestamptz
.
psql 또는 pgAdmin과 같은 클라이언트 또는 libpq 를 통해 통신하는 모든 응용 프로그램 (예 : pg gem이있는 Ruby)에는 현재 시간대에 대한 타임 스탬프와 오프셋이 표시 되거나 요청 된 시간대 에 따라 표시됩니다 (아래 참조). 항상 같은 시점이며 표시 형식 만 다릅니다. 또는 매뉴얼에 따르면 :
모든 시간대 인식 날짜 및 시간은 내부적으로 UTC로 저장됩니다.
클라이언트에 표시되기 전에 TimeZone 구성 매개 변수로 지정된 영역에서 현지 시간으로 변환 됩니다.
이 간단한 예제 (psql)를 고려하십시오.
db = # SELECT 타임 스탬프 '2012-03-05 20:00 +03 ';
타임 스탬프
------------------------
2012-03-05 18:00:00 +01
대담한 강조 광산. 여기 뭔 일 있었 니? 입력 리터럴에 대해
임의의 시간대 오프셋 +3
을 선택했습니다 . Postgres에게 이것은 UTC 타임 스탬프를 입력하는 많은 방법 중 하나 일뿐 2012-03-05 17:00:00
입니다. 내 테스트에서 현재 시간대 설정 비엔나 / 오스트리아 에 대해 쿼리 결과가 표시 되는데, 이는 겨울철과 여름철에 상쇄 됩니다. 겨울철 에 빠지기 때문입니다.+1
+2
2012-03-05 18:00:00+01
Postgres는 이미이 값을 입력 한 방법을 잊었습니다. 기억하는 것은 가치와 데이터 유형뿐입니다. 십진수와 마찬가지로. numeric '003.4'
, numeric '3.40'
또는 numeric '+3.4'
- 동일한 내부 값의 모든 결과.
AT TIME ZONE
이 논리를 이해하자마자 원하는 모든 것을 할 수 있습니다. 현재 누락 된 것은 특정 시간대에 따라 타임 스탬프 리터럴을 해석하거나 나타내는 도구입니다. 그 곳에서 AT TIME ZONE
구문이 시작됩니다. 두 가지 사용 사례가 있습니다. timestamptz
로 변환 timestamp
되고 그 반대도 마찬가지입니다.
UTC로를 입력합니다 timestamptz
2012-03-05 17:00:00+0
:
SELECT timestamp '2012-03-05 17:00:00' AT TIME ZONE 'UTC'
... 이는 다음과 같습니다.
SELECT timestamptz '2012-03-05 17:00:00 UTC'
EST timestamp
(동부 표준시) 와 동일한 시점을 표시하려면 다음을 수행하십시오.
SELECT timestamp '2012-03-05 17:00:00' AT TIME ZONE 'UTC' AT TIME ZONE 'EST'
AT TIME ZONE 'UTC'
두 번 맞습니다 . 첫 번째는 timestamp
값을 형식을 반환하는 (주어진) UTC 타임 스탬프로 해석합니다 timestamptz
. 두 번째는 변환 timestamptz
받는 사람을 timestamp
지정된 타임 존 'EST'에서 - 어떤 시간에 독특한 시점에서 시간대 EST 표시에 시계.
예
SELECT ts AT TIME ZONE 'UTC'
FROM (
VALUES
(1, timestamptz '2012-03-05 17:00:00+0')
, (2, timestamptz '2012-03-05 18:00:00+1')
, (3, timestamptz '2012-03-05 17:00:00 UTC')
, (4, timestamp '2012-03-05 11:00:00' AT TIME ZONE '+6')
, (5, timestamp '2012-03-05 17:00:00' AT TIME ZONE 'UTC')
, (6, timestamp '2012-03-05 07:00:00' AT TIME ZONE 'US/Hawaii') -- ①
, (7, timestamptz '2012-03-05 07:00:00 US/Hawaii') -- ①
, (8, timestamp '2012-03-05 07:00:00' AT TIME ZONE 'HST') -- ①
, (9, timestamp '2012-03-05 18:00:00+1') -- ② loaded footgun!
) t(id, ts);
동일한 UTC 타임 스탬프를 보유한 타임 스탬프 열이있는 8 개 또는 9 개의 동일한 행을 반환 2012-03-05 17:00:00
합니다. 9 번째 줄은 내 시간대에서 작동하지만 사악한 함정입니다. 아래를 참조하십시오.
① 표준 시간대 이름 과 표준 시간대 약어 하와이 행 6-8 은 DST (일광 절약 시간제)에 따라 달라 지지만 현재는 다를 수 있습니다. 같은 표준 시간대 이름 'US/Hawaii'
은 DST 규칙과 모든 기록 변화를 자동으로 인식하는 반면, 약어 HST
는 고정 오프셋을위한 벙어리 코드 일뿐입니다. 여름 / 표준 시간에 다른 약어를 추가해야 할 수도 있습니다. 이름은 올바르게 해석 어떤 주어진 시간대에 타임 스탬프를. 약어는 저렴하지만, 주어진 타임 스탬프에 대한 올바른 하나가 될 필요가있다 :
일광 절약 시간제는 인류가 생각 해낸 가장 밝은 아이디어 중 하나가 아닙니다.
로 표시 ② 행 9, 로드 footgun는 작동 나를 위해 ,하지만 우연의 일치에 의해. 명시 적으로 문자 캐스팅 경우 timestamp [without time zone]
, 오프셋 어떤 시간대는 무시됩니다 ! 베어 타임 스탬프 만 사용됩니다. 그런 다음 timestamptz
예제에서 값이 열 유형과 일치 하도록 자동으로 강제됩니다 . 이 단계에서는 timezone
현재 세션 의 설정이 가정됩니다.이 경우 +1
내 시간대 (유럽 / 비엔나) 와 동일한 시간대 입니다. 그러나 아마도 귀하의 경우에는 그렇지 않을 것입니다-다른 가치를 초래할 것입니다. 한마디로 : timestamptz
리터럴을 캐스트하지 않거나 timestamp
시간대 오프셋을 잃습니다.
당신의 질문
사용자는 시간을 저장합니다 (예 : 2012 년 3 월 17 일 오후 7시). 시간대 변환이나 시간대를 저장하고 싶지 않습니다.
시간대 자체는 저장되지 않습니다. 위의 방법 중 하나를 사용하여 UTC 타임 스탬프를 입력하십시오.
사용자가 지정한 시간대 만 사용하여 사용자 현지 시간대의 현재 시간을 '이전'또는 '이후'로 가져옵니다.
다른 시간대의 모든 클라이언트에 대해 하나의 쿼리를 사용할 수 있습니다.
절대 세계 시간 :
SELECT * FROM tbl WHERE time_col > (now() AT TIME ZONE 'UTC')::time
현지 시계에 따른 시간 :
SELECT * FROM tbl WHERE time_col > now()::time
아직 배경 정보에 질리지 않습니까? 매뉴얼에 더 있습니다.