CodeGym /행동 /SQL SELF /Unix-시간 다루기: EPOCH

Unix-시간 다루기: EPOCH

SQL SELF
레벨 32, 레슨 1
사용 가능

Unix-시간은 그냥 시간을 숫자로 저장하는 방식이야. 1970년 1월 1일 자정(UTC)부터 몇 초(가끔은 밀리초)가 지났는지 세는 거지. 개발할 때 엄청 많이 쓰는 포맷인데, 저장도 쉽고, 전송이나 비교도 편해서 그냥 숫자 하나만 다루면 되거든.

쉽게 말하면, Unix-시간은 1970년에 시작해서 계속 돌아가는 타이머 같은 거야. 1697222400 같은 이상한 숫자 봤어? 걱정하지 마, 이건 그냥 기준점부터 몇 초가 지났는지 나타내는 거야. 이게 무슨 날짜인지 궁금하지? 곧 계산하는 법 알려줄게!

이런 포맷은 시스템끼리 데이터 동기화할 때, 타임스탬프 저장할 때, 그리고 뭐가 먼저 일어났는지 빠르게 비교할 때 자주 써.

Unix-시간으로 변환하기

PostgreSQL에는 EXTRACT(EPOCH FROM ...)라는 함수가 있어서 날짜나 타임스탬프를 Unix-시간으로 바꿔줄 수 있어.

지금 날짜를 이 포맷으로 바꿔보자:

SELECT EXTRACT(EPOCH FROM NOW());

결과는 이런 식이야:

1697222400

이 결과는 1970년부터 지금까지 지난 초를 나타내는 거야.

고정된 날짜도 이렇게 변환할 수 있어:

SELECT EXTRACT(EPOCH FROM TIMESTAMP '2023-10-01 12:00:00');

결과:

1696152000

이제 2023년 10월 1일 12:00(UTC)이 이 값이랑 매칭된다는 걸 알았지.

Unix-시간에서 다시 변환하기

당연히 반대로 변환하는 함수도 있어. Unix-시간이 있는데 이걸 사람이 읽기 쉬운 포맷으로 바꾸고 싶으면 TO_TIMESTAMP() 함수가 도와줄 거야.

Unix-시간을 날짜와 시간으로 바꿔보자

SELECT TO_TIMESTAMP(1697222400);

결과:

2023-10-13 00:00:00+00

이제 이게 2023년 10월 13일 00:00(UTC)라는 걸 알 수 있어.

Unix-시간의 실전 활용

예를 들어, events라는 테이블에 이벤트 정보를 저장하고, 이벤트 시간도 Unix-시간 포맷으로 저장한다고 해보자.

CREATE TABLE events (
    id SERIAL PRIMARY KEY,
    event_name TEXT,
    event_time BIGINT -- Unix-시간 저장용
);

이 테이블에 데이터를 넣을 때 Unix-시간으로 타임스탬프를 넣을 수 있어:

INSERT INTO events (event_name, event_time)
VALUES
('서버 시작', 1697222400),
('데이터베이스 업데이트', 1697308800);

이 정보를 읽기 쉬운 형태로 바꾸려면 TO_TIMESTAMP만 쓰면 돼:

SELECT event_name, TO_TIMESTAMP(event_time) AS readable_time
FROM events;

결과:

event_name readable_time
서버 시작 2023-10-13 00:00:00+00
데이터베이스 업데이트 2023-10-14 00:00:00+00

꿀팁 & 자주 하는 실수

  1. 정확도(precision) 잘못 선택하기

Unix-시간이 밀리초 단위(예: 1697222400000)라면, 그냥 TO_TIMESTAMP나 EXTRACT에 바로 넣으면 안 돼. 이럴 땐 값을 1000으로 나눠줘야 해:

SELECT TO_TIMESTAMP(1697222400000 / 1000);

결과:

2023-10-13 00:00:00+00
  1. 타임존 무시하기

Unix-시간은 항상 UTC 기준이야. 그래서 결과도 타임존을 따로 바꿔주지 않으면 항상 UTC로 나와. 예를 들어:

SELECT TO_TIMESTAMP(1697222400) AT TIME ZONE 'Europe/Moscow';

결과:

2023-10-13 03:00:00
  1. 너무 큰 숫자 문제

가끔 개발자가 실수로 Unix-시간을 너무 큰 값(예: 밀리초 단위)을 넣는 경우가 있어. 이러면 결과가 엉뚱하게 나와:

SELECT TO_TIMESTAMP(1697222400000); -- 에러남!

이럴 땐 꼭 1000으로 나눠줘야 해.

예제: 작업 소요 시간 계산하기

실생활 예제로, tasks라는 테이블이 있고, 각 작업이 생성된 후 얼마나 시간이 지났는지 계산해보자.

테이블 만들기:

CREATE TABLE tasks (
    id SERIAL PRIMARY KEY,
    task_name TEXT,
    created_at TIMESTAMP DEFAULT NOW()
);

작업 몇 개 추가하기:

INSERT INTO tasks (task_name)
VALUES
('작업 1'),
('작업 2'),
('작업 3');

이제 Unix-시간 컬럼을 추가해서 볼 수 있어:

SELECT id, task_name, EXTRACT(EPOCH FROM created_at) AS created_epoch
FROM tasks;

결과:

id task_name created_epoch
1 작업 1 1697222400
2 작업 2 1697233200

그리고 생성된 후 몇 초가 지났는지 계산해보자:

SELECT id, task_name, EXTRACT(EPOCH FROM NOW()) - EXTRACT(EPOCH FROM created_at) AS elapsed_seconds
FROM tasks;

결과:

id task_name elapsed_seconds
1 작업 1 3600
2 작업 2 7200

언제, 왜 Unix-시간을 써야 할까?

Unix-시간은 시스템끼리 값 주고받을 때, 타임스탬프 비교할 때, 그리고 CPU 부담을 최소화해야 할 때 딱이야. API, 웹 개발, 데이터 분석, 서버-클라이언트 동기화 등에서 엄청 많이 써. 하지만 항상 UTC 기준이라는 점, 초/밀리초 단위 구분, 그리고 저장 포맷을 신경 써야 해.

외부 시스템이 "Unix-시간 언어"로 말할 때 PostgreSQL에서 어떻게 다뤄야 할지 이제 알겠지? TO_TIMESTAMP랑 EXTRACT(EPOCH)만 잘 쓰면 변환은 문제없어. 이제 시간 관련 작업은 걱정 끝!

2
과제
SQL SELF, 레벨 32, 레슨 1
잠금
시간 간격 계산하기
시간 간격 계산하기
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION