PostgreSQL에서 UTC로 현재 시간을 기본값으로 사용


172

TIMESTAMP WITHOUT TIME ZONE유형 의 열이 있으며 기본값을 UTC로 현재 시간으로 설정하고 싶습니다. UTC로 현재 시간을 얻는 것은 쉽습니다.

postgres=# select now() at time zone 'utc';
          timezone          
----------------------------
 2013-05-17 12:52:51.337466
(1 row)

열에 현재 타임 스탬프를 사용하는 경우

postgres=# create temporary table test(id int, ts timestamp without time zone default current_timestamp);
CREATE TABLE
postgres=# insert into test values (1) returning ts;
             ts             
----------------------------
 2013-05-17 14:54:33.072725
(1 row)

그러나 그것은 현지 시간을 사용합니다. UTC로 강제로 시도하면 구문 오류가 발생합니다.

postgres=# create temporary table test(id int, ts timestamp without time zone default now() at time zone 'utc');
ERROR:  syntax error at or near "at"
LINE 1: ...int, ts timestamp without time zone default now() at time zo...

답변:


297

기능도 필요하지 않습니다. 기본 표현식 주위에 괄호를 넣으십시오.

create temporary table test(
    id int, 
    ts timestamp without time zone default (now() at time zone 'utc')
);

2
쿼리를 작성할 때 now_utc ()와 같은 기능이 실제로 빛납니다
misaxi

시간이 한 시간 뒤로 돌아갈 때도 작동합니다. now ()는 UTC의 오프셋을 알고있는 타임 스탬프를 반환합니다.
Clay Lenhart

1
FWIW, PostgreSQL 11.5에서이 쿼리를 실행 ALTER TABLE testcase_result ADD COLUMN date_created TIMESTAMP WITHOUT TIME ZONE DEFAULT (NOW() AT TIME ZONE "UTC") NOT NULL;하면 실패합니다 : ERROR: column "UTC" does not exist. 모두 소문자 인지 확인하십시오 'utc'.
code_dredd

2
수정 : 'utc'문자열도 큰 따옴표가 아닌 작은 따옴표로 묶어야합니다.
code_dredd 1


26

함수로 감싸십시오.

create function now_utc() returns timestamp as $$
  select now() at time zone 'utc';
$$ language sql;

create temporary table test(
  id int,
  ts timestamp without time zone default now_utc()
);

16

이건 어떤가요

now()::timestamp

다른 타임 스탬프에 시간대가없는 경우이 캐스트는 현재 시간에 대해 "타임 스탬프가없는 타임 스탬프"와 일치하는 유형을 생성합니다.

그래도 다른 사람들이 그 옵션에 대해 어떻게 생각하는지 읽고 싶습니다. 나는 여전히 "있는 /없는"시간대에 대한 나의 이해를 신뢰하지 않습니다.

편집 : 중요한 점을 분명히하기 때문에 Michael Ekoka의 의견을 여기에 추가하십시오.

경고. 문제는 시간대를 저장하지 않는 타임 스탬프 열에 대해 UTC로 기본 타임 스탬프를 생성하는 것입니다 (아마도 모든 타임 스탬프가 동일한 것을 공유하는 경우 시간대를 저장할 필요가 없기 때문에). 솔루션은 로컬 타임 스탬프 (대부분의 사람들은 반드시 UTC로 설정하지 않아도 됨)를 생성하고 순진 타임 스탬프 (표준 시간대를 지정하지 않은 타임 스탬프)로 저장하는 것입니다.


흥미로운 속임수이지만이 동작을 알지 못하면 혼동 될 수 있습니다. 승인 된 답변은 원하는 조치와 결과에 대해 명확합니다. 함수와 동일하지만 DB의 함수에서 멀리 떨어져 있습니다.
Frank V

내 선택에 따라 로컬 날짜 시간을 db로 생성합니다
VelikiiNehochuha

경고. 문제는 시간대를 저장하지 않는 타임 스탬프 열에 대해 UTC기본 타임 스탬프를 생성 하는 것입니다 (아마도 모든 타임 스탬프가 동일한 것을 공유하는 경우 시간대를 저장할 필요가 없기 때문에). 솔루션은 로컬 타임 스탬프 (대부분의 사람들은 UTC로 설정하지 않아도 됨)를 생성하고 순진 타임 스탬프 (시간대를 지정하지 않은 타임 스탬프)로 저장하는 것입니다.
Michael Ekoka

@MichaelEkoka 답변에 의견을 추가했습니다. 원하는 경우 계속 수정하십시오. 매우 명확하게 설명하고 있습니다. 감사!
Risadinha

경고 : 시간대가있는 타임 스탬프 필드는 합리적인 가정과 달리 시간대를 저장하지 않습니다. 아래 링크를 참조하여 UTC 페이지를 검색하십시오. 입력시, 시간대가있는 시간 소인은 수신 값을 utc로 변환하고 해당 값을 시간 영역 또는 오프셋 정보없이 저장합니다 . 출력시, 저장된 utc 값은 사용 가능한 경우 클라이언트의 시간대를 사용하여 현지 시간으로 변환됩니다. 이 유형은 쿼리시 값 변환에 관한 것입니다. 한 시간대에서 저장하고 다른 시간대에서 선택하여이를 테스트해야합니다. postgresql.org/docs/11/datatype-datetime.html
Tom

7

다음과 같은 두 가지 솔루션이 있습니다.

(다음 코드에서, 당신은 대체해야 'UTC'에 대한 구역now()대한 타임 스탬프 )

  1. timestamp AT TIME ZONE zone -SQL 표준 준수
  2. timezone(zone, timestamp) -더 읽기 쉽다

timezone (zone, timestamp) 함수는 TIME ZONE 존의 SQL 준수 구문 타임 스탬프와 같습니다.


설명:

  • zone 은 텍스트 문자열 (예 :) 'UTC'또는 간격 (예 :)으로 지정할 수 있습니다. INTERVAL '-08:00'여기에 사용 가능한 모든 시간대 목록이 있습니다.
  • 타임 스탬프 형식의 모든 값이 될 수있는 타임 스탬프
  • now()데이터베이스의 기본 시간대 (예 :)가 첨부 된 타임 스탬프 유형 (필요한 것) 의 값을 반환합니다 2018-11-11T12:07:22.3+05:00.
  • timezone('UTC', now())현재 시간대 ( 타임 스탬프가있는 타임 스탬프 유형 )를에있는 시간대없는 시간 으로 바꿉니다 UTC.
    예를 들어을 SELECT timestamp with time zone '2020-03-16 15:00:00-05' AT TIME ZONE 'UTC'반환 2020-03-16T20:00:00Z합니다.

문서 : timezone ()


1
이것들을 요약 해 주셔서 감사합니다. 소문자 버전을 사용 at timezone 'utc'했는데 PostgreSQL 설정에서 작동하지 않습니다. 문자를 대문자로 사용하는 것은 문제 해결
Geradlus_RU

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.