타임스탬프

타임스탬프 (시간대 포함) 함수

이 섹션은 TIMESTAMP WITH TIME ZONE(TIMESTAMPTZ) 값을 검사하고 조작하기 위한 함수와 연산자를 설명해요. 관련된 TIMESTAMP 함수도 함께 참고하면 좋아요. 시간대 지원은 내장된 ICU 확장이 제공합니다. 아래 예시들에서 현재 시간대는 그레고리안 달력을 사용하는 America/Los_Angeles라고 가정해요.

출처: 문서

본문

내장 타임스탬프 (시간대 포함) 함수

아래 표는 TIMESTAMPTZ 값에 사용할 수 있는 스칼라 함수를 보여줘요. 이 함수들은 빈닝이나 표시를 포함하지 않으므로 항상 사용 가능해요.

이름 설명
current_timestamp 현재 날짜와 시간 (현재 트랜잭션 시작).
get_current_timestamp() 현재 날짜와 시간 (현재 트랜잭션 시작).
greatest(timestamptz, timestamptz) 두 타임스탬프 중 더 늦은 것.
isfinite(timestamptz) 시간대 포함 타임스탬프가 유한하면 true, 그렇지 않으면 false 반환.
isinf(timestamptz) 시간대 포함 타임스탬프가 무한하면 true, 그렇지 않으면 false 반환.
least(timestamptz, timestamptz) 두 타임스탬프 중 더 이른 것.
now() 현재 날짜와 시간 (현재 트랜잭션 시작).
timetz_byte_comparable(timetz) TIME WITH TIME ZONEUBIGINT 정렬 키로 변환.
to_timestamp(double) epoch 이후의 초를 시간대 포함 타임스탬프로 변환.
transaction_timestamp() 현재 날짜와 시간 (현재 트랜잭션 시작).

current_timestamp

| 설명 | 현재 날짜와 시간 (현재 트랜잭션 시작) | | 예시 | current_timestamp | | 결과 | 2022-10-08 12:44:46.122-07 |

get_current_timestamp()

| 설명 | 현재 날짜와 시간 (현재 트랜잭션 시작) | | 예시 | get_current_timestamp() | | 결과 | 2022-10-08 12:44:46.122-07 |

greatest(timestamptz, timestamptz)

| 설명 | 두 타임스탬프 중 더 늦은 것 | | 예시 | greatest(TIMESTAMPTZ '1992-09-20 20:38:48', TIMESTAMPTZ '1992-03-22 01:02:03.1234') | | 결과 | 1992-09-20 20:38:48-07 |

isfinite(timestamptz)

| 설명 | 시간대 포함 타임스탬프가 유한하면 true, 그렇지 않으면 false 반환 | | 예시 | isfinite(TIMESTAMPTZ '1992-03-07') | | 결과 | true |

isinf(timestamptz)

| 설명 | 시간대 포함 타임스탬프가 무한하면 true, 그렇지 않으면 false 반환 | | 예시 | isinf(TIMESTAMPTZ '-infinity') | | 결과 | true |

least(timestamptz, timestamptz)

| 설명 | 두 타임스탬프 중 더 이른 것 | | 예시 | least(TIMESTAMPTZ '1992-09-20 20:38:48', TIMESTAMPTZ '1992-03-22 01:02:03.1234') | | 결과 | 1992-03-22 01:02:03.1234-08 |

now()

| 설명 | 현재 날짜와 시간 (현재 트랜잭션 시작) | | 예시 | now() | | 결과 | 2022-10-08 12:44:46.122-07 |

timetz_byte_comparable(timetz)

| 설명 | TIME WITH TIME ZONEUBIGINT 정렬 키로 변환 | | 예시 | timetz_byte_comparable('18:18:16.21-07:00'::TIMETZ) | | 결과 | 2494691656335442799 |

to_timestamp(double)

| 설명 | epoch 이후의 초를 시간대 포함 타임스탬프로 변환 | | 예시 | to_timestamp(1284352323.5) | | 결과 | 2010-09-13 04:32:03.5+00 |

transaction_timestamp()

| 설명 | 현재 날짜와 시간 (현재 트랜잭션 시작) | | 예시 | transaction_timestamp() | | 결과 | 2022-10-08 12:44:46.122-07 |

타임스탬프 (시간대 포함) 문자열

시간대 확장이 로드되지 않으면 TIMESTAMPTZ 값은 오프셋 표기를 사용해 문자열로/에서 캐스팅돼요. 이를 통해 시간대 정보에 접근하지 않고도 instant를 정확히 지정할 수 있어요. 이식성을 위해 TIMESTAMPTZ 값은 항상 GMT 오프셋으로 표시됩니다.

SELECT '2022-10-08 13:13:34-07'::TIMESTAMPTZ;
2022-10-08 20:13:34+00

ICU 같은 시간대 확장이 로드되면 문자열에서 시간대를 파싱해 로컬 시간대로 표현할 수 있어요.

SELECT '2022-10-08 13:13:34 Europe/Amsterdam'::TIMESTAMPTZ::VARCHAR;
2022-10-08 04:13:34-07 -- 오프셋은 여러분의 로컬 시간대에 따라 달라짐

ICU 타임스탬프 (시간대 포함) 연산자

아래 표는 ICU 확장이 제공하는 TIMESTAMP WITH TIME ZONE 값용 수학 연산자를 보여줘요.

연산자 설명 예시 결과
+ INTERVAL 더하기 TIMESTAMPTZ '1992-03-22 01:02:03' + INTERVAL 5 DAY 1992-03-27 01:02:03
- TIMESTAMPTZ 빼기 TIMESTAMPTZ '1992-03-27' - TIMESTAMPTZ '1992-03-22' 5 days
- INTERVAL 빼기 TIMESTAMPTZ '1992-03-27 01:02:03' - INTERVAL 5 DAY 1992-03-22 01:02:03

무한 값에 더하거나 빼면 같은 무한 값이 생성돼요.

인터벌의 덧셈과 뺄셈은 ICU Calendar add 함수를 사용해요. 양의 인터벌(시간 앞으로)에는 필드가 가장 덜 중요한 것부터 가장 중요한 것 순으로 증가해요. 음의 인터벌(시간 뒤로)에는 필드가 가장 중요한 것부터 가장 덜 중요한 것 순으로 감소해요. 이는 Postgres와 같은 결과를 내지만, 일부 더 최근의 달력 RFC와는 일치하지 않아요.

ICU 타임스탬프 (시간대 포함) 함수

아래 표는 ICU가 제공하는 TIMESTAMP WITH TIME ZONE 값용 스칼라 함수를 보여줘요.

이름 설명
age(timestamptz, timestamptz) 인자들을 빼서 두 타임스탬프 사이의 시간 차이를 구함.
age(timestamptz) current_date에서 뺌.
date_diff(part, starttimestamptz, endtimestamptz) starttimestamptzendtimestamptz 사이의 part 경계 수. 더 큰 타임스탬프는 포함하고 더 작은 것은 제외.
date_part([part, ...], timestamp) 나열된 subfield들을 struct로 가져오기. 목록은 상수여야 함.
date_part(part, timestamp) subfield 가져오기 (extract와 동등).
date_sub(part, starttimestamptz, endtimestamptz) starttimestamptzendtimestamptz 사이 간격의 부호 있는 길이. part의 정수 배수로 잘림.
date_trunc(part, timestamptz) 지정된 정밀도로 잘라내기.
epoch_ns(timestamptz) timestamptz를 epoch 이후의 나노초로 변환.
epoch_us(timestamptz) timestamptz를 epoch 이후의 마이크로초로 변환.
extract(field FROM timestamptz) TIMESTAMP WITH TIME ZONE에서 subfield 가져오기.
last_day(timestamptz) 한 달의 마지막 날.
make_timestamptz(bigint, bigint, bigint, bigint, bigint, double, string) 주어진 부분들과 시간대에 대한 TIMESTAMP WITH TIME ZONE.
make_timestamptz(bigint, bigint, bigint, bigint, bigint, double) 현재 시간대에서 주어진 부분들에 대한 TIMESTAMP WITH TIME ZONE.
make_timestamptz(microseconds) epoch 이후의 µs에 대한 TIMESTAMP WITH TIME ZONE.
strftime(timestamptz, format) 포맷 문자열에 따라 TIMESTAMP WITH TIME ZONE 값을 문자열로 변환.
strptime(text, format) %Z가 지정되면 포맷 문자열에 따라 문자열을 TIMESTAMP WITH TIME ZONE으로 변환.
time_bucket(bucket_width, timestamptz[, offset]) timestamptz를 폭 bucket_width의 격자로 잘라냄. 격자는 bucket_width가 개월 수 또는 그보다 거친 단위일 때 2000-01-01 00:00:00+00:00[ + offset], 그 외에는 2000-01-03 00:00:00+00:00[ + offset]에 고정. 2000-01-03이 월요일이라는 점 유의.
time_bucket(bucket_width, timestamptz[, origin]) timestamptz를 폭 bucket_width의 격자로 잘라냄. 격자는 origin 타임스탬프에 고정되며, 기본값은 bucket_width가 개월 수 또는 그보다 거친 단위일 때 2000-01-01 00:00:00+00:00, 그 외에는 2000-01-03 00:00:00+00:00. 2000-01-03이 월요일이라는 점 유의.
time_bucket(bucket_width, timestamptz[, timezone]) timestamptz를 폭 bucket_width의 격자로 잘라냄. 격자는 origin 타임스탬프에 고정되며, 기본값은 bucket_width가 개월 수 또는 그보다 거친 단위일 때 제공된 timezone2000-01-01 00:00:00, 그 외에는 제공된 timezone2000-01-03 00:00:00. 기본 시간대는 'UTC'. 2000-01-03이 월요일이라는 점 유의.

age(timestamptz, timestamptz)

| 설명 | 인자들을 빼서 두 타임스탬프 사이의 시간 차이를 구함 | | 예시 | age(TIMESTAMPTZ '2001-04-10', TIMESTAMPTZ '1992-09-20') | | 결과 | 8 years 6 months 20 days |

age(timestamptz)

| 설명 | current_date에서 뺌 | | 예시 | age(TIMESTAMP '1992-09-20') | | 결과 | 29 years 1 month 27 days 12:39:00.844 |

date_diff(part, starttimestamptz, endtimestamptz)

| 설명 | starttimestamptzendtimestamptz 사이의 부호 있는 part 경계 수. 더 큰 타임스탬프는 포함하고 더 작은 것은 제외 | | 예시 | date_diff('hour', TIMESTAMPTZ '1992-09-30 23:59:59', TIMESTAMPTZ '1992-10-01 01:58:00') | | 결과 | 2 |

date_part([part, ...], timestamptz)

| 설명 | 나열된 subfield들을 struct로 가져오기. 목록은 상수여야 함 | | 예시 | date_part(['year', 'month', 'day'], TIMESTAMPTZ '1992-09-20 20:38:40-07') | | 결과 | {year: 1992, month: 9, day: 20} |

date_part(part, timestamptz)

| 설명 | subfield 가져오기 (extract와 동등) | | 예시 | date_part('minute', TIMESTAMPTZ '1992-09-20 20:38:40') | | 결과 | 38 |

date_sub(part, starttimestamptz, endtimestamptz)

| 설명 | starttimestamptzendtimestamptz 사이 간격의 부호 있는 길이. part의 정수 배수로 잘림 | | 예시 | date_sub('hour', TIMESTAMPTZ '1992-09-30 23:59:59', TIMESTAMPTZ '1992-10-01 01:58:00') | | 결과 | 1 |

date_trunc(part, timestamptz)

| 설명 | 지정된 정밀도로 잘라내기 | | 예시 | date_trunc('hour', TIMESTAMPTZ '1992-09-20 20:38:40') | | 결과 | 1992-09-20 20:00:00 |

epoch_ns(timestamptz)

| 설명 | timestamptz를 epoch 이후의 나노초로 변환 | | 예시 | epoch_ns('2022-11-07 08:43:04.123456+00'::TIMESTAMPTZ); | | 결과 | 1667810584123456000 |

epoch_us(timestamptz)

| 설명 | timestamptz를 epoch 이후의 마이크로초로 변환 | | 예시 | epoch_us('2022-11-07 08:43:04.123456+00'::TIMESTAMPTZ); | | 결과 | 1667810584123456 |

extract(field FROM timestamptz)

| 설명 | TIMESTAMP WITH TIME ZONE에서 subfield 가져오기 | | 예시 | extract('hour' FROM TIMESTAMPTZ '1992-09-20 20:38:48') | | 결과 | 20 |

last_day(timestamptz)

| 설명 | 한 달의 마지막 날 | | 예시 | last_day(TIMESTAMPTZ '1992-03-22 01:02:03.1234') | | 결과 | 1992-03-31 |

make_timestamptz(bigint, bigint, bigint, bigint, bigint, double, string)

| 설명 | 주어진 부분들과 시간대에 대한 TIMESTAMP WITH TIME ZONE | | 예시 | make_timestamptz(1992, 9, 20, 15, 34, 27.123456, 'CET') | | 결과 | 1992-09-20 06:34:27.123456-07 |

make_timestamptz(bigint, bigint, bigint, bigint, bigint, double)

| 설명 | 현재 시간대에서 주어진 부분들에 대한 TIMESTAMP WITH TIME ZONE | | 예시 | make_timestamptz(1992, 9, 20, 13, 34, 27.123456) | | 결과 | 1992-09-20 13:34:27.123456-07 |

make_timestamptz(microseconds)

| 설명 | epoch 이후의 µs에 대한 TIMESTAMP WITH TIME ZONE | | 예시 | make_timestamptz(1667810584123456) | | 결과 | 2022-11-07 16:43:04.123456-08 |

strftime(timestamptz, format)

| 설명 | 포맷 문자열에 따라 TIMESTAMP WITH TIME ZONE 값을 문자열로 변환 | | 예시 | strftime(timestamptz '1992-01-01 20:38:40', '%a, %-d %B %Y - %I:%M:%S %p') | | 결과 | Wed, 1 January 1992 - 08:38:40 PM |

strptime(text, format)

| 설명 | %Z가 지정되면 포맷 문자열에 따라 문자열을 TIMESTAMP WITH TIME ZONE으로 변환 | | 예시 | strptime('Wed, 1 January 1992 - 08:38:40 PST', '%a, %-d %B %Y - %H:%M:%S %Z') | | 결과 | 1992-01-01 08:38:40-08 |

time_bucket(bucket_width, timestamptz[, offset])

| 설명 | timestamptz를 폭 bucket_width의 격자로 잘라냄. 격자는 bucket_width가 개월 수 또는 그보다 거친 단위일 때 2000-01-01 00:00:00+00:00[ + offset], 그 외에는 2000-01-03 00:00:00+00:00[ + offset]에 고정. 2000-01-03이 월요일이라는 점 유의 | | 예시 | time_bucket(INTERVAL '10 minutes', TIMESTAMPTZ '1992-04-20 15:26:00-07', INTERVAL '5 minutes') | | 결과 | 1992-04-20 15:25:00-07 |

time_bucket(bucket_width, timestamptz[, origin])

| 설명 | timestamptz를 폭 bucket_width의 격자로 잘라냄. 격자는 origin 타임스탬프에 고정되며, 기본값은 bucket_width가 개월 수 또는 그보다 거친 단위일 때 2000-01-01 00:00:00+00:00, 그 외에는 2000-01-03 00:00:00+00:00. 2000-01-03이 월요일이라는 점 유의 | | 예시 | time_bucket(INTERVAL '2 weeks', TIMESTAMPTZ '1992-04-20 15:26:00-07', TIMESTAMPTZ '1992-04-01 00:00:00-07') | | 결과 | 1992-04-15 00:00:00-07 |

time_bucket(bucket_width, timestamptz[, timezone])

| 설명 | timestamptz를 폭 bucket_width의 격자로 잘라냄. 격자는 origin 타임스탬프에 고정되며, 기본값은 bucket_width가 개월 수 또는 그보다 거친 단위일 때 제공된 timezone2000-01-01 00:00:00, 그 외에는 제공된 timezone2000-01-03 00:00:00. 기본 시간대는 'UTC'. 2000-01-03이 월요일이라는 점 유의 | | 예시 | time_bucket(INTERVAL '2 days', TIMESTAMPTZ '1992-04-20 15:26:00-07', 'Europe/Berlin') | | 결과 | 1992-04-19 15:00:00-07 (=1992-04-20 00:00:00 Europe/Berlin) |

subfield를 얻기 위한 전용 추출 함수도 있어요.

ICU 타임스탬프 테이블 함수

아래 표는 TIMESTAMP WITH TIME ZONE 타입에 사용할 수 있는 테이블 함수를 보여줘요.

이름 설명
generate_series(timestamptz, timestamptz, interval) 닫힌 범위(시작 타임스탬프와 끝 타임스탬프 모두 포함)에서 인터벌만큼씩 증가하는 타임스탬프 테이블 생성.
range(timestamptz, timestamptz, interval) 반 개방 범위(시작 타임스탬프는 포함하지만 끝 타임스탬프 전에 멈춤)에서 인터벌만큼씩 증가하는 타임스탬프 테이블 생성.

무한 값은 테이블 함수 경계로 허용되지 않아요.

generate_series(timestamptz, timestamptz, interval)

| 설명 | 닫힌 범위(시작 타임스탬프와 끝 타임스탬프 모두 포함)에서 인터벌만큼씩 증가하는 타임스탬프 테이블 생성 | | 예시 | generate_series(TIMESTAMPTZ '2001-04-10', TIMESTAMPTZ '2001-04-11', INTERVAL 30 MINUTE) |

range(timestamptz, timestamptz, interval)

| 설명 | 반 개방 범위(시작 타임스탬프는 포함하지만 끝 타임스탬프 전에 멈춤)에서 인터벌만큼씩 증가하는 타임스탬프 테이블 생성 | | 예시 | range(TIMESTAMPTZ '2001-04-10', TIMESTAMPTZ '2001-04-11', INTERVAL 30 MINUTE) |

ICU 타임스탬프 (시간대 미포함) 함수

아래 표는 일반 TIMESTAMP 값에 동작하는 ICU 제공 스칼라 함수를 보여줘요. 이 함수들은 TIMESTAMP가 "로컬 타임스탬프"라고 가정해요.

로컬 타임스탬프는 실질적으로 시간대의 부분 값을 단일 값으로 인코딩하는 방식이에요. 일광 절약 시간제 덕분에 생성된 값이 공백과 모호함을 포함할 수 있으므로 주의해서 사용해야 해요. 종종 date_part 함수의 struct 변형으로 더 안정적으로 같은 기능을 구현할 수 있어요.

이름 설명
current_localtime() GMT 빈 값이 현재 시간대의 로컬 시간에 해당하는 TIME 반환.
current_localtimestamp() GMT 빈 값이 현재 시간대의 로컬 날짜와 시간에 해당하는 TIMESTAMP 반환.
localtime current_localtime() 함수 호출의 동의어.
localtimestamp current_localtimestamp() 함수 호출의 동의어.
timezone(text, timestamp) GMT의 타임스탬프 date parts를 사용해 주어진 시간대의 타임스탬프를 구성. 실질적으로 인자는 "로컬" 시간.
timezone(text, timestamptz) 주어진 시간대의 타임스탬프 date parts를 사용해 타임스탬프를 구성. 실질적으로 결과는 "로컬" 시간.

current_localtime()

| 설명 | GMT 빈 값이 현재 시간대의 로컬 시간에 해당하는 TIME 반환 | | 예시 | current_localtime() | | 결과 | 08:47:56.497 |

current_localtimestamp()

| 설명 | GMT 빈 값이 현재 시간대의 로컬 날짜와 시간에 해당하는 TIMESTAMP 반환 | | 예시 | current_localtimestamp() | | 결과 | 2022-12-17 08:47:56.497 |

localtime

| 설명 | current_localtime() 함수 호출의 동의어 | | 예시 | localtime | | 결과 | 08:47:56.497 |

localtimestamp

| 설명 | current_localtimestamp() 함수 호출의 동의어 | | 예시 | localtimestamp | | 결과 | 2022-12-17 08:47:56.497 |

timezone(text, timestamp)

| 설명 | GMT의 타임스탬프 date parts를 사용해 주어진 시간대의 타임스탬프를 구성. 실질적으로 인자는 "로컬" 시간 | | 예시 | timezone('America/Denver', TIMESTAMP '2001-02-16 20:38:40') | | 결과 | 2001-02-16 19:38:40-08 |

timezone(text, timestamptz)

| 설명 | 주어진 시간대의 타임스탬프 date parts를 사용해 타임스탬프를 구성. 실질적으로 결과는 "로컬" 시간 | | 예시 | timezone('America/Denver', TIMESTAMPTZ '2001-02-16 20:38:40-05') | | 결과 | 2001-02-16 18:38:40 |

At Time Zone

AT TIME ZONE 문법은 위에서 나열한 (두 인자) timezone 함수의 구문 설탕이에요.

SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'America/Denver' AS ts;
2001-02-16 19:38:40-08
SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/Denver' AS ts;
2001-02-16 18:38:40

숫자 시간대는 허용되지 않는다는 점에 유의하세요.

SELECT TIMESTAMP '2001-02-16 20:38:40-05' AT TIME ZONE '0200' AS ts;
Not implemented Error: Unknown TimeZone '0200'

무한 값

무한 날짜에 적용된 함수는 "말이 되는" 것에 따라 같은 무한 날짜(예: greatest)를 반환하거나 NULL(예: date_part)을 반환해요. 일반적으로 함수가 무한 시간 값의 부분을 검사해야 하면 결과는 NULL이에요.

달력

ICU 확장은 비-그레고리안 달력도 지원해요. 그런 달력이 현재라면 표시와 빈닝 연산이 그 달력을 사용합니다.

일광 절약 시간제(DST) 전환

TIMESTAMPTZINTERVAL '1 day' 같은 달력 인터벌을 더하면, 결과 로컬 타임스탬프가 일광 절약 시간제 전환 중에 존재하지 않는 시간에 떨어질 수 있어요.

DuckDB는 PostgreSQL의 동작을 따라 결과를 다음 유효 타임스탬프로 앞으로 조정해요.

예시:

SET timezone = 'Europe/Amsterdam';

SELECT TIMESTAMPTZ '2025-03-29 02:30:00+01' + INTERVAL '1 day';
2025-03-30 03:30:00+02

더 알아보기 (Learn more)

  • TIMESTAMP 함수는 sql/functions/timestamp, date parts는 sql/functions/datepart 문서를 참고해 주세요.