TIMESTAMPTZ vs TIMESTAMP: PostgreSQL ๋์๋ณด๋์ API
PostgreSQL์์ TIMESTAMPTZ์ TIMESTAMP์ ์ฐจ์ด๊ฐ ๋์๋ณด๋, API ์๋ต, ์๊ฐ๋ ๋ณํ ๋ฐ ์๋จธํ์ ๋ฒ๊ทธ์ ์ด๋ค ์ํฅ์ ์ฃผ๋์ง ์ค๋ช ํฉ๋๋ค.

๋ฌธ์ ์ ๋ณธ์ง: ํ ๋ฒ ์ผ์ด๋ ์ฌ๊ฑด, ์ฌ๋ฌ ํด์\n\n์ฌ๊ฑด์ ํ ๋ฒ ๋ฐ์ํ์ง๋ง ์ฌ๋ฌ ๋ฐฉ์์ผ๋ก ๋ณด๊ณ ๋ฉ๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ๊ฐ์ ์ ์ฅํ๊ณ , API๊ฐ ์ง๋ ฌํํ๊ณ , ๋์๋ณด๋๊ฐ ์ง๊ณํ๋ฉฐ, ๊ฐ ์ฌ์ฉ์๋ ์์ ์๊ฐ๋์ ๋ง์ถฐ ๋ด
๋๋ค. ์ด๋ ํ ๊ณ์ธต์ด๋ผ๋ ๋ค๋ฅธ ๊ฐ์ ์ ํ๋ฉด ๊ฐ์ ํ์ด ์๋ก ๋ค๋ฅธ ์๊ฐ์ฒ๋ผ ๋ณด์ผ ์ ์์ต๋๋ค.\n\n๊ทธ๋์ TIMESTAMPTZ์ TIMESTAMP์ ์ ํ์ ๋จ์ํ ํ์
์ ํธ๊ฐ ์๋๋๋ค. ์ ์ฅ๋ ๊ฐ์ด ํน์ ํ ์๊ฐ(instant)์ ๋ํ๋ด๋์ง, ์๋๋ฉด ํน์ ์ง์ญ์์๋ง ์๋ฏธ๊ฐ ์๋ ๋ฒฝ์๊ณ(wall-clock) ์๊ฐ์ธ์ง ๊ฒฐ์ ํฉ๋๋ค.\n\n๋ณดํต ๋จผ์ ๊นจ์ง๋ ๋ถ๋ถ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค: ์ธ์ผ์ฆ ๋์๋ณด๋๊ฐ ๋ด์๊ณผ ๋ฒ ๋ฅผ๋ฆฐ์์ ์๋ก ๋ค๋ฅธ ์ผ๋ณ ํฉ๊ณ๋ฅผ ๋ณด์ฌ์ฃผ๊ฑฐ๋, ์๊ฐ๋ณ ์ฐจํธ๊ฐ DST ๋ณ๊ฒฝ ์ ํ ์๊ฐ์ด ๋น ์ง๊ฑฐ๋ ์ค๋ณต๋๋ ๊ฒฝ์ฐ, ๊ฐ์ฌ ๋ก๊ทธ๊ฐ ๋ ์์คํ
์ด ๋ ์ง์๋ โ๋์โํ์ง๋ง ์ค์ ์๊ฐ์ ๋ํด์๋ ์์๊ฐ ๋ค์์ฌ ๋ณด์ด๋ ๊ฒฝ์ฐ ๋ฑ์
๋๋ค.\n\n๊ฐ๋จํ ๋ชจ๋ธ๋ง ์ง์ผ๋ ๋ฌธ์ ๋ฅผ ํผํ ์ ์์ต๋๋ค:\n\n- ์ ์ฅ(Storage): PostgreSQL์ ๋ฌด์์ ์ ์ฅํ๊ณ ๊ทธ ๊ฐ์ด ๋ฌด์์ ์๋ฏธํ๋๊ฐ.\n- ํ์(Display): UI, ๋ด๋ณด๋ด๊ธฐ, ๋ฆฌํฌํธ์์ ์ด๋ป๊ฒ ํฌ๋งทํ๋๊ฐ.\n- ์ฌ์ฉ์ ๋ก์ผ์ผ(User locale): ๋ทฐ์ด์ ์๊ฐ๋์ ๋ฌ๋ ฅ ๊ท์น(์๋จธํ์ ํฌํจ).\n\n์ด๋ค์ ์์ด ์ฐ๋ฉด ์กฐ์ฉํ ๋ณด๊ณ ๋ฒ๊ทธ๊ฐ ์๊น๋๋ค. ์ง์ํ์ด ๋์๋ณด๋์์ โ์ด์ ์์ฑ๋ ํฐ์ผโ์ ๋ด๋ณด๋ด API ๋ณด๊ณ ์์ ๋น๊ตํ๋ฉด, ๋ ๋ค ๊ทธ๋ด๋ฏํ์ง๋ง ํ ์ชฝ์ ๋ทฐ์ด์ ๋ก์ปฌ ์์ ๊ฒฝ๊ณ๋ฅผ ์ผ๊ณ ๋ค๋ฅธ ์ชฝ์ UTC๋ฅผ ์ผ์ ์ ์์ต๋๋ค.\n\n๋ชฉํ๋ ๊ฐ๋จํฉ๋๋ค: ๊ฐ ์๊ฐ ๊ฐ์ ๋ํด ๋ ๊ฐ์ง๋ฅผ ๋ถ๋ช
ํ ๊ฒฐ์ ํ์ธ์. ๋ฌด์์ ์ ์ฅํ ์ง, ๋ฌด์์ ๋ณด์ฌ์ค์ง ๊ฒฐ์ ํ์ธ์. ์ด ๋ช
ํ์ฑ์ ๋ฐ์ดํฐ ๋ชจ๋ธ, API ์๋ต, ๋์๋ณด๋ ์ ๋ฐ์ ๊ฑธ์ณ ์ ์ง๋์ด์ผ ๋ชจ๋๊ฐ ๊ฐ์ ํ์๋ผ์ธ์ ๋ณด๊ฒ ๋ฉ๋๋ค.\n\n## TIMESTAMP์ TIMESTAMPTZ๊ฐ ์ค์ ๋ก ์๋ฏธํ๋ ๊ฒ\n\nPostgreSQL์์ ์ด๋ฆ์ ์คํด๋ฅผ ๋ถ๋ฌ์ต๋๋ค. ์ด๋ฆ์ ๋ฌด์์ด ์ ์ฅ๋๋์ง๋ฅผ ์ค๋ช
ํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง, ์ฌ์ค์ PostgreSQL์ด ์
๋ ฅ์ ์ด๋ป๊ฒ ํด์ํ๊ณ ์ถ๋ ฅ์ ์ด๋ป๊ฒ ํฌ๋งทํ๋์ง๋ฅผ ์ค๋ช
ํฉ๋๋ค.\n\nTIMESTAMP(์ฆ timestamp without time zone)๋ ๋จ์ง ๋ฌ๋ ฅ ๋ ์ง์ ์๊ฐ์
๋๋ค. ์: 2026-01-29 09:00:00. ์๊ฐ๋๊ฐ ๋ถ์ด ์์ง ์์ต๋๋ค. PostgreSQL์ ์๋์ผ๋ก ๋ณํํด์ฃผ์ง ์์ต๋๋ค. ๋ค๋ฅธ ์๊ฐ๋์ ์๋ ๋ ์ฌ๋์ด ๊ฐ์ TIMESTAMP๋ฅผ ์ฝ๊ณ ์๋ก ๋ค๋ฅธ ์ค์ ์๊ฐ์ผ๋ก ํด์ํ ์ ์์ต๋๋ค.\n\nTIMESTAMPTZ(์ฆ timestamp with time zone)๋ ์ค์ ์์ ์ ๋ํ๋
๋๋ค. ์ธ์คํดํธ๋ก ์๊ฐํ์ธ์. PostgreSQL์ ๋ด๋ถ์ ์ผ๋ก ์ ๊ทํ(์ฌ์ค์ UTC๋ก)ํ ๋ค ์ธ์
์ ์๊ฐ๋์ ๋ง์ถฐ ํ์ํฉ๋๋ค.\n\n๋๋ถ๋ถ์ ๊น์ง ๋๋ ๋ค์๋ ์ด๋ฐ ๋์์ด ์์ต๋๋ค:\n\n- ์
๋ ฅ ์: PostgreSQL์ TIMESTAMPTZ ๊ฐ์ ๋จ์ผ ๋น๊ต ๊ฐ๋ฅํ ์๊ฐ์ผ๋ก ๋ณํํฉ๋๋ค.\n- ์ถ๋ ฅ ์: PostgreSQL์ ํ์ฌ ์ธ์
์๊ฐ๋๋ฅผ ์ฌ์ฉํด ๊ทธ ์๊ฐ์ ํฌ๋งทํฉ๋๋ค.\n- TIMESTAMP์ ๊ฒฝ์ฐ: ์
๋ ฅ์ด๋ ์ถ๋ ฅ์์ ์๋ ๋ณํ์ด ์ผ์ด๋์ง ์์ต๋๋ค.\n\n์์ ์์ ๊ฐ ์ฐจ์ด๋ฅผ ๋ณด์ฌ์ค๋๋ค. ์ฑ์ด ์ฌ์ฉ์๋ก๋ถํฐ 2026-03-08 02:30์ ๋ฐ์๋ค๊ณ ํฉ์๋ค. ์ด๋ฅผ TIMESTAMP ์ด์ ์ฝ์
ํ๋ฉด PostgreSQL์ ์ ํํ ๊ทธ ๋ฒฝ์๊ณ ๊ฐ์ ์ ์ฅํฉ๋๋ค. ๋ง์ฝ ๊ทธ ์ง์ญ์์ DST๋ก ์ธํด ๊ทธ ๋ก์ปฌ ์๊ฐ์ด ์กด์ฌํ์ง ์๋๋ค๋ฉด, ๋ณด๊ณ ๋จ๊ณ์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๋๊น์ง ๋์น์ฑ์ง ๋ชปํ ์ ์์ต๋๋ค.\n\nTIMESTAMPTZ๋ก ์ฝ์
ํ๋ฉด PostgreSQL์ ๊ฐ์ ํด์ํ ์๊ฐ๋๊ฐ ํ์ํฉ๋๋ค. ์๋ฅผ ๋ค์ด 2026-03-08 02:30 America/New_York์ด๋ผ๋ฉด PostgreSQL์ ์ด๋ฅผ ์๊ฐ์ผ๋ก ๋ณํํฉ๋๋ค(๊ท์น๊ณผ ๊ฐ์ ๋ฐ๋ผ ์ค๋ฅ๋ฅผ ๋ผ ์๋ ์์). ๋์ค์ ๋ฐ๋์ ๋์๋ณด๋๋ ๋ค๋ฅธ ๋ก์ปฌ ์๊ฐ์ ๋ณด์ฌ๋ ๋์ผํ ์ค์๊ฐ ์๊ฐ์ ๊ฐ๋ฆฌํต๋๋ค.\n\nํํ ์คํด ํ๋: ์ฌ๋๋ค์ โwith time zoneโ์ ๋ณด๊ณ PostgreSQL์ด ์๋ ์ฌ์ฉ์์ ์๊ฐ๋ ๋ผ๋ฒจ์ ์ ์ฅํ๋ค๊ณ ๊ธฐ๋ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ต๋๋ค. PostgreSQL์ ๋ผ๋ฒจ์ด ์๋๋ผ ๊ทธ ์๊ฐ์ ์ ์ฅํฉ๋๋ค. ๋ง์ฝ ์ฌ์ฉ์์ ์๋ ์๊ฐ๋ ๋ผ๋ฒจ์ ํ์ํด์ผ ํ๋ค๋ฉด(์: โ๊ณ ๊ฐ ๋ก์ปฌ ์๊ฐ์ผ๋ก ๋ณด์ฌ์ฃผ๊ธฐโ), ์๊ฐ๋ ์ ๋ณด๋ฅผ ๋ณ๋์ ํ
์คํธ ํ๋๋ก ์ ์ฅํ์ธ์.\n\n## ์ธ์
์๊ฐ๋: ๋ง์ ๋๋ผ์์ ์จ์ ์ค์ \n\nPostgreSQL์๋ ๋น์ ์ด ๋ณด๋ ๊ฒ์ ์กฐ์ฉํ ๋ฐ๊พธ๋ ์ค์ ์ด ์์ต๋๋ค: ์ธ์
์๊ฐ๋์
๋๋ค. ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ์ฟผ๋ฆฌ๋ก ์กฐํํด๋ ์ธ์
์ ์๊ฐ๋๊ฐ ๋ค๋ฅด๋ฉด ์๋ก ๋ค๋ฅธ ์๊ณ ์๊ฐ์ ๋ณผ ์ ์์ต๋๋ค.\n\n์ด๊ฑด ์ฃผ๋ก TIMESTAMPTZ์ ์ํฅ์ ์ค๋๋ค. PostgreSQL์ ์ ๋์ ์๊ฐ์ ์ ์ฅํ ๋ค ์ธ์
์๊ฐ๋์ ๋ง์ถฐ ํ์ํฉ๋๋ค. TIMESTAMP๋(์๊ฐ๋ ์์) ๊ฐ์ ๋จ์ํ ๋ฌ๋ ฅ ์๊ฐ์ผ๋ก ์ทจ๊ธํด ํ์๋ฅผ ์ํด ์ด๋์ํค์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ TIMESTAMP๋ฅผ TIMESTAMPTZ๋ก ๋ณํํ๊ฑฐ๋ ์๊ฐ๋ ์ธ์ง ๊ฐ๊ณผ ๋น๊ตํ ๋ ์ธ์
์๊ฐ๋๊ฐ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์์ต๋๋ค.\n\n์ธ์
์๊ฐ๋๋ ๋ฌด์ฌ์ฝ ์ค์ ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค: ์ ํ๋ฆฌ์ผ์ด์
์์ ์ค์ , ๋๋ผ์ด๋ฒ ํ๋ผ๋ฏธํฐ, ์ปค๋ฅ์
ํ์ด ์ด์ ์ธ์
์ ์ฌ์ฌ์ฉ, BI ๋๊ตฌ์ ๊ธฐ๋ณธ๊ฐ, ETL ์์
์ด ์๋ฒ ๋ก์ผ์ผ์ ์์, ๋๋ ๊ฐ์ธ SQL ์ฝ์์ด ๋
ธํธ๋ถ ์ค์ ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ฑ์
๋๋ค.\n\nํ๋ค์ด ๋
ผ์ํ๋ ์ํฉ์ ์ด๋ฐ ์์
๋๋ค. ์ฌ๊ฑด์ด TIMESTAMPTZ ์ด์ 2026-03-08 01:30:00+00์ผ๋ก ์ ์ฅ๋์ด ์๋ค๊ณ ๊ฐ์ ํฉ์๋ค. America/Los_Angeles ์ธ์
์ ๋์๋ณด๋๋ ์ด๋ฅผ ์ ๋ ์ ๋
์ ๋ก์ปฌ ์๊ฐ์ผ๋ก ํ์ํ ๊ฒ์ด๊ณ , API ์ธ์
์ด UTC์ด๋ฉด ๋ค๋ฅธ ์๊ณ ์๊ฐ์ ๋ณด์ฌ์ค ๊ฒ์
๋๋ค. ์ฐจํธ๊ฐ ์ธ์
๋ก์ปฌ ์ผ ๋จ์๋ก ๊ทธ๋ฃนํํ๋ฉด ์ผ๋ณ ํฉ๊ณ๊ฐ ๋ฌ๋ผ์ง ์ ์์ต๋๋ค.\n\nsql\n-- Make your output consistent for a reporting job\nSET TIME ZONE 'UTC';\n\nSELECT created_at, date_trunc('day', created_at) AS day_bucket\nFROM events;\n\n\n๋ฆฌํฌํธ๋ฅผ ์์ฑํ๊ฑฐ๋ API ์๋ต์ ๋ง๋๋ ๋ชจ๋ ๊ณณ์์๋ ์๊ฐ๋๋ฅผ ๋ช
์ํ์ธ์. ์ฐ๊ฒฐ ์ ์ค์ ํ๊ฑฐ๋(SET TIME ZONE์ ๋จผ์ ์คํ), ๊ธฐ๊ณ ์ถ๋ ฅ์ฉ ํ์ค(์ข
์ข
UTC)์ ์ ํํ๊ณ , โ๋ก์ปฌ ๋น์ฆ๋์ค ์๊ฐโ ๋ฆฌํฌํธ๋ ๋๊ตฐ๊ฐ์ ๋
ธํธ๋ถ ์ค์ ์ ์์กดํ์ง ๋ง๊ณ ์ก(job) ๋ด๋ถ์์ ๋น์ฆ๋์ค ์กด์ ์ค์ ํ์ธ์. ํ๋ง๋ ์ปค๋ฅ์
์ ์ฌ์ฉํ๋ค๋ฉด ์ปค๋ฅ์
์ ์ฒดํฌ์์ํ ๋ ์ธ์
์ค์ ์ ๋ฆฌ์
ํ์ธ์.\n\n## ๋์๋ณด๋๊ฐ ๊นจ์ง๋ ๋ฐฉ์: ๊ทธ๋ฃนํ, ๋ฒํท, DST ๊ฐ๊ทน\n\n๋์๋ณด๋๋ ๋จ์ํด ๋ณด์
๋๋ค: ํ๋ฃจ๋น ์ฃผ๋ฌธ ์๋ฅผ ์ธ๊ณ , ์๊ฐ๋ณ ๊ฐ์
์ ๋ณด์ฌ์ฃผ๊ณ , ์ฃผ๋ณ ๋น๊ต๋ฅผ ํฉ๋๋ค. ๋ฌธ์ ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ํ๋์ โ์๊ฐ(moment)โ๋ง ์ ์ฅํ๋๋ฐ ์ฐจํธ๊ฐ ๊ทธ๊ฒ์ ๋ณด๋ ์ฌ๋์ ๋ฐ๋ผ ์ฌ๋ฌ ๋ค๋ฅธ โ๋ ๋คโ๋ก ๋ฐ๊ฟ ๋ ์์๋ฉ๋๋ค.\n\n์ฌ์ฉ์ ๋ก์ปฌ ์๊ฐ๋ ๊ธฐ์ค์ผ๋ก ์ผ๋ณ ๊ทธ๋ฃนํ๋ฅผ ํ๋ฉด ๊ฐ์ ์ฌ๊ฑด์ด ๋ ์ฌ๋์๊ฒ ๋ค๋ฅธ ๋ ์ง๋ก ๋ณด์ผ ์ ์์ต๋๋ค. ๋ก์ค์ค์ ค๋ ์ค์์ 23:30์ ๋ค์ด์จ ์ฃผ๋ฌธ์ ๋ฒ ๋ฅผ๋ฆฐ์์๋ ์ด๋ฏธ โ๋ค์ ๋ โ์ผ ์ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ TIMESTAMP์ ๋ํด DATE(created_at)๋ก ๊ทธ๋ฃนํํ๋ฉด ์ค์ ์๊ฐ์ด ์๋ ๋ฒฝ์๊ณ ํ๋
๊ฐ์ผ๋ก ๊ทธ๋ฃนํํ๋ ๊ฒ์
๋๋ค.\n\nDST ์ฃผ๋ณ์ ์๊ฐ๋ณ ์ฐจํธ๋ ๋ ๋ณต์กํด์ง๋๋ค. ๋ด์๋ ํ ๋ก์ปฌ ์๊ฐ์ด ์์ ์กด์ฌํ์ง ์์ ์ฐจํธ์ ๊ฐ๊ทน์ด ์๊ธฐ๊ณ , ๊ฐ์์๋ ํ ๋ก์ปฌ ์๊ฐ์ด ๋ ๋ฒ ๋ฐ์ํด ์คํ์ดํฌ๋ ์ค๋ณต๋ ๋ฒํท์ด ์๊ธธ ์ ์์ต๋๋ค. ์ด๋ ์ฟผ๋ฆฌ์ ๋์๋ณด๋๊ฐ ์ด๋ค 01:30์ ์๋ฏธํ๋์ง ๋ค๋ฅด๊ฒ ํด์ํ ๋ ๋ฐ์ํฉ๋๋ค.\n\n์ค์ฉ์ ์ธ ์ง๋ฌธ: ๋น์ ์ ์ค์ ์๊ฐ(real moments)์ ์ฐจํธ๋ก ๊ทธ๋ฆฌ๋๊ฐ(๋ณํํด๋ ์์ ), ์๋๋ฉด ๋ก์ปฌ ์ค์ผ์ค ์๊ฐ(local schedule time)์ ๊ทธ๋ฆฌ๋๊ฐ(์ ๋ ๋ณํํ๋ฉด ์ ๋จ)? ๋์๋ณด๋๋ ๊ฑฐ์ ํญ์ ์ค์ ์๊ฐ์ ์ํฉ๋๋ค.\n\n### UTC๋ก ๊ทธ๋ฃนํํ ๋์ ๋น์ฆ๋์ค ์๊ฐ๋๋ก ๊ทธ๋ฃนํํ ๋\n\nํ๋์ ๊ทธ๋ฃนํ ๊ท์น์ ์ ํํด ๋ชจ๋ ๊ณณ(SQL, API, BI ๋๊ตฌ)์ ์ ์ฉํ์ธ์. ๊ทธ๋ ์ง ์์ผ๋ฉด ํฉ๊ณ๊ฐ driftํฉ๋๋ค.\n\n๊ธ๋ก๋ฒํ๊ณ ์ผ๊ด๋ ์๊ณ์ด(์์คํ
์ํ, API ํธ๋ํฝ, ๊ธ๋ก๋ฒ ๊ฐ์
)์ ์ํ๋ฉด UTC๋ก ๊ทธ๋ฃนํํ์ธ์. โ๊ทธ ๋ โ์ด ๋ฒ์ ยท์ด์์ ์๋ฏธ๊ฐ ์์ ๋(๋งค์ฅ ์์
์ผ, SLA, ๊ธ์ต ๋ง๊ฐ)๋ ๋น์ฆ๋์ค ์๊ฐ๋๋ก ๊ทธ๋ฃนํํ์ธ์. ๊ฐ์ธํ๊ฐ ๋น๊ต ๊ฐ๋ฅ์ฑ๋ณด๋ค ์ค์ํ ๋๋ง ๋ทฐ์ด์ ์๊ฐ๋๋ก ๊ทธ๋ฃนํํ์ธ์(๊ฐ์ธ ํ๋ ํผ๋ ๋ฑ).\n\n์ผ๊ด๋ โ๋น์ฆ๋์ค ์ผโ ๊ทธ๋ฃนํ ํจํด ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:\n\nsql\nSELECT date_trunc('day', created_at AT TIME ZONE 'America/New_York') AS business_day,\n count(*)\nFROM orders\nGROUP BY 1\nORDER BY 1;\n\n\n### ๋ถ์ ์ ๋ง๋ ๋ ์ด๋ธ\n\n์ซ์๊ฐ ํ๊ณ ์๋ฌด๋ ์ด์ ๋ฅผ ์ค๋ช
ํ์ง ๋ชปํ๋ฉด ์ฌ๋๋ค์ ์ฐจํธ๋ฅผ ์ ๋ขฐํ์ง ์์ต๋๋ค. UI์ ์ฌ์ฉํ ๊ท์น์ ๊ทธ๋๋ก ๋ผ๋ฒจ๋ก ํ์ํ์ธ์: โDaily orders (America/New_York)โ ๋๋ โHourly events (UTC)โ. ๋์ผํ ๊ท์น์ ๋ด๋ณด๋ด๊ธฐ์ API์๋ ์ฌ์ฉํ์ธ์.\n\n## ๋ณด๊ณ ๋ฐ API๋ฅผ ์ํ ๊ฐ๋จํ ๊ท์น ์งํฉ\n\n๊ฐ์ ์ ์ฅํ ๋ ๊ทธ ๊ฐ์ด ์ค์ ์๊ฐ์ ๋ฌ์ฌํ๋์ง, ์๋๋ฉด ๊ทธ๋๋ก ์ ์งํด์ผ ํ๋ ๋ก์ปฌ ์๊ฐ์ธ์ง ๊ฒฐ์ ํ์ธ์. ์ด ๋์ ์์ด ์ฐ๋ฉด ๋์๋ณด๋์ API๊ฐ ์๋ก ๋ค๋ฅด๊ฒ ๋ฉ๋๋ค.\n\n์์ธก ๊ฐ๋ฅํ ๋ณด๊ณ ๋ฅผ ์ํ ๊ท์น ์งํฉ:\n\n- ์ค์ ์ด๋ฒคํธ๋ TIMESTAMPTZ๋ก ์ ์ฅํ๊ณ UTC๋ฅผ ์ง์ค์ ์ถ์ฒ๋ก ์ผ์ผ์ธ์.\n- โ์ฒญ๊ตฌ์ผโ ๊ฐ์ ๋น์ฆ๋์ค ๊ฐ๋
์ DATE(๋๋ ์ง์ ํ ๋ฒฝ์๊ณ ์๊ฐ์ด ํ์ํ๋ฉด ๋ก์ปฌ ์๊ฐ ํ๋)๋ก ๋ฐ๋ก ์ ์ฅํ์ธ์.\n- API์์๋ ISO 8601๋ก ํ์์คํฌํ๋ฅผ ๋ฐํํ๊ณ ์ผ๊ด๋๊ฒ ํ์ธ์: ํญ์ ์คํ์
์ ํฌํจํ๊ฑฐ๋(์: +02:00) ํญ์ UTC์ Z๋ฅผ ์ฌ์ฉํ์ธ์.\n- ๋ณํ์ ์ฃ์ง(UI ๋ฐ ๋ณด๊ณ ๊ณ์ธต)์์ ์ํํ์ธ์. ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ก์ง๊ณผ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ก ์์์ ์๋ค ๊ฐ๋ค ๋ณํํ์ง ๋ง์ธ์.\n\n์ด ๋ฐฉ์์ด ์ ํจํ ์ด์ : ๋์๋ณด๋๋ ๋ฒ์๋ฅผ ๋ฒํทํ๊ณ ๋น๊ตํฉ๋๋ค. ์ธ์คํดํธ(TIMESTAMPTZ)๋ฅผ ์ ์ฅํ๋ฉด PostgreSQL์ DST ์ ํ ์์๋ ์ด๋ฒคํธ๋ฅผ ์์ ์ ์ผ๋ก ์ ๋ ฌํ๊ณ ํํฐ๋งํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ด๋ป๊ฒ ํ์ํ๊ฑฐ๋ ๊ทธ๋ฃนํํ ์ง ์ ํํ๋ฉด ๋ฉ๋๋ค. ๋ก์ปฌ ์๊ฐ(TIMESTAMP)๋ง ์ ์ฅํ๋ฉด PostgreSQL์ ๊ทธ ์๋ฏธ๋ฅผ ์ ์ ์๊ธฐ ๋๋ฌธ์ ์ธ์
์๊ฐ๋๊ฐ ๋ฐ๋ ๋ ๊ทธ๋ฃนํ ๊ฒฐ๊ณผ๊ฐ ๋ฌ๋ผ์ง ์ ์์ต๋๋ค.\n\nโ๋ก์ปฌ ๋น์ฆ๋์ค ๋ ์งโ๋ ์ธ์คํดํธ๊ฐ ์๋๋ฏ๋ก ๋ถ๋ฆฌํ์ธ์. โ2026-03-08์ ๋ฐฐ๋ฌโ์ ๋ ์ง์ ๊ฒฐ์ ์ด์ง ์๊ฐ์ด ์๋๋๋ค. ์ด๋ฅผ ํ์์คํฌํ์ ์ต์ง๋ก ๋ฃ์ผ๋ฉด DST๋ก ์ธํด ๋ก์ปฌ ์๊ฐ์ด ๋น ์ง๊ฑฐ๋ ์ค๋ณต๋์ด ๋์ค์ ๊ฐ๊ทน์ด๋ ์คํ์ดํฌ๋ก ๋ํ๋ฉ๋๋ค.\n\n## ๋จ๊ณ๋ณ: ๊ฐ ์๊ฐ ๊ฐ์ ์ ์ ํ ํ์
๊ณ ๋ฅด๊ธฐ\n\nTIMESTAMPTZ์ TIMESTAMP ์ฌ์ด ์ ํ์ ํ ์ง๋ฌธ์์ ์์ํฉ๋๋ค: ์ด ๊ฐ์ด ์ค์ ๋ก ์ผ์ด๋ ์๊ฐ์ ์ค๋ช
ํ๋๊ฐ, ์๋๋ฉด ์ ํํ ์ ํ ๋๋ก ์ ์ง๋์ด์ผ ํ๋ ๋ก์ปฌ ์๊ฐ์ธ๊ฐ?\n\n### 1) ์ค์ ์ด๋ฒคํธ์ ์์ฝ๋ ๋ก์ปฌ ์๊ฐ์ ๋ถ๋ฆฌํ์ธ์\n\n์นผ๋ผ ๋ชฉ๋ก์ ๋น ๋ฅด๊ฒ ์ ๋ฆฌํ์ธ์.\n\n์ค์ ์ด๋ฒคํธ(ํด๋ฆญ, ๊ฒฐ์ , ๋ก๊ทธ์ธ, ๋ฐฐ์ก, ์ผ์ ์ธก์ , ์ง์ ๋ฉ์์ง)๋ ๋ณดํต TIMESTAMPTZ๋ก ์ ์ฅํด์ผ ํฉ๋๋ค. ์๋ก ๋ค๋ฅธ ์๊ฐ๋์์ ๋ณด๋๋ผ๋ ํ๋์ ๋ช
ํํ ์๊ฐ์ ์ํ๊ธฐ ๋๋ฌธ์
๋๋ค.\n\n์์ฝ๋ ๋ก์ปฌ ์๊ฐ์ ๋ค๋ฆ
๋๋ค: โ๋งค์ฅ ์คํ 09:00โ, โํฝ์
์ฐฝ๊ตฌ 16:00โ18:00โ, โ์ฒญ๊ตฌ๋ ๋งค์ 1์ผ ํ์ง ์๊ฐ 10:00โ ๋ฑ์ TIMESTAMP์ ๋ณ๋์ ์๊ฐ๋ ํ๋๋ฅผ ํจ๊ป ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ๋ซ์ต๋๋ค. ์๋๊ฐ ํน์ ์ฅ์์ ๋ฒฝ์๊ณ ์๊ฐ์ ๋ฌถ์ฌ ์๊ธฐ ๋๋ฌธ์
๋๋ค.\n\n### 2) ํ์ค์ ์ ํ๊ณ ๋ฌธ์ํํ์ธ์\n\n๋๋ถ๋ถ ์ ํ์ ์ข์ ๊ธฐ๋ณธ๊ฐ์: ์ด๋ฒคํธ ์๊ฐ์ UTC๋ก ์ ์ฅํ๊ณ , ์ฌ์ฉ์ ์๊ฐ๋๋ก ํ์ํ์ธ์. ์ด๋ฅผ ์คํค๋ง ์ฃผ์, API ๋ฌธ์, ๋์๋ณด๋ ์ค๋ช
๋ฑ ์ฌ๋๋ค์ด ์ค์ ๋ก ์ฝ๋ ๊ณณ์ ๋ฌธ์ํํ์ธ์. ๋ํ โ๋น์ฆ๋์ค ๋ฐ์ดโ์ ์ ์(UTC ๋ฐ์ด์ธ์ง, ๋น์ฆ๋์ค ์กด ๋ฐ์ด์ธ์ง, ๋ทฐ์ด ๋ก์ปฌ ๋ฐ์ด์ธ์ง)๋ฅผ ๋ช
ํํ ํ์ธ์. ์ด ์ ํ์ด ์ผ๋ณ ๋ณด๊ณ ๋ฅผ ์ข์ฐํฉ๋๋ค.\n\nํ์ฅ์์ ์๋ํ๋ ์งง์ ์ฒดํฌ๋ฆฌ์คํธ:\n\n- ๊ฐ ์๊ฐ ์นผ๋ผ์ โevent instantโ ๋๋ โlocal scheduleโ๋ก ํ๊ทธํ์ธ์.\n- ์ด๋ฒคํธ ์ธ์คํดํธ๋ ๊ธฐ๋ณธ์ ์ผ๋ก UTC์ ์ ์ฅ๋ TIMESTAMPTZ๋ก ํ์ธ์.\n- ์คํค๋ง ๋ณ๊ฒฝ ์์๋ ์ ์คํ ๋ฐฑํ(backfill)ํ๊ณ ์ํ ํ์ ์์ผ๋ก ๊ฒ์ฆํ์ธ์.\n- API ํฌ๋งท์ ํ์คํํ์ธ์(์ธ์คํดํธ์๋ ํญ์ Z ๋๋ ์คํ์
ํฌํจ).\n- ETL, BI ์ปค๋ฅํฐ, ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ปค์์ ์ธ์
์๊ฐ๋๋ฅผ ๋ช
์์ ์ผ๋ก ์ค์ ํ์ธ์.\n\nโ๋ณํํ๊ณ ๋ฐฑํโ ์์
์ ์ฃผ์ํ์ธ์. ์ปฌ๋ผ ํ์
์ ๋ณ๊ฒฝํ๋ฉด ์ด์ ๊ฐ์ด ๋ค๋ฅธ ์ธ์
์๊ฐ๋ ํ์์ ํด์๋์์ ๊ฒฝ์ฐ ์๋ฏธ๊ฐ ์กฐ์ฉํ ๋ฐ๋ ์ ์์ต๋๋ค.\n\n## ํ๋ฃจ ์ฐจ์ด ๋ฐ DST ๋ฒ๊ทธ๋ฅผ ์ผ์ผํค๋ ํํ ์ค์\n\n๋๋ถ๋ถ์ ์๊ฐ ๋ฒ๊ทธ๋ โPostgreSQL์ ์ด์ํ ๋์โ์ด ์๋๋๋ค. ๋ณด๊ธฐ ์ข์ ๊ฐ์ ์๋ชป๋ ์๋ฏธ๋ก ์ ์ฅํด ์ฌ๋ฌ ๊ณ์ธต์ด ๋๋ฝ๋ ์ปจํ
์คํธ๋ฅผ ์ถ์ธกํ๊ฒ ๋ง๋ค์๊ธฐ ๋๋ฌธ์
๋๋ค.\n\n### ์ค์ 1: ๋ฒฝ์๊ณ ์๊ฐ์ ์ ๋ ์๊ฐ์ธ ์ ์ ์ฅํ๊ธฐ\n\nํํ ํจ์ ์ ์ง์ญ ๋ฒฝ์๊ณ ์๊ฐ(์: ๋ฒ ๋ฅผ๋ฆฐ์ 2026-03-29 09:00)์ TIMESTAMPTZ๋ก ์ ์ฅํ๋ ๊ฒ์
๋๋ค. PostgreSQL์ ์ด๋ฅผ ์๊ฐ์ผ๋ก ์ฒ๋ฆฌํ๊ณ ํ์ฌ ์ธ์
์๊ฐ๋์ ๋ฐ๋ผ ๋ณํํฉ๋๋ค. ๋ง์ฝ ์๋๋ โํญ์ ํ์ง ์๊ฐ ๊ธฐ์ค ์ค์ 9์โ์๋ค๋ฉด ์๋ฏธ๋ฅผ ์๊ฒ ๋ฉ๋๋ค. ๋ค๋ฅธ ์ธ์
์๊ฐ๋์์ ๊ฐ์ ํ์ ๋ณด๋ฉด ํ์๋๋ ์๊ฐ์ด ์ด๋ํฉ๋๋ค.\n\n์ฝ์(appointments)์ ๋ก์ปฌ ์๊ฐ์ TIMESTAMP๋ก ์ ์ฅํ๊ณ ๋ณ๋์ ์๊ฐ๋(๋๋ ์์น) ํ๋๋ฅผ ํจ๊ป ์ ์ฅํ์ธ์. ์ผ์ด๋ ์ฌ๊ฑด์ TIMESTAMPTZ๋ก ์ ์ฅํ์ธ์.\n\n### ์ค์ 2: ํ๊ฒฝ๋ง๋ค ๋ค๋ฅธ ๊ฐ์ \n\n๋ก์ปฌ ๋
ธํธ๋ถ, ์คํ
์ด์ง, ํ๋ก๋์
์ด ๋์ผํ ์๊ฐ๋๋ฅผ ์ฐ์ง ์์ ์ ์์ต๋๋ค. ํ ํ๊ฒฝ์ UTC๋ก, ๋ค๋ฅธ ํ๊ฒฝ์ ๋ก์ปฌ ์๊ฐ์ผ๋ก ๋์ํ๋ฉด โ์ผ๋ณ ๊ทธ๋ฃนํโ ๋ณด๊ณ ์๊ฐ ๋ฌ๋ผ์ง๋๋ค. ๋ฐ์ดํฐ๋ ๋ฐ๋์ง ์์์ง๋ง ์ธ์
์ค์ ์ด ๋ฐ๋ ๊ฒ์
๋๋ค.\n\n### ์ค์ 3: ์๊ฐ ํจ์์ ๋ณด์ฅ ์ฌํญ์ ๋ชจ๋ฅธ ์ฑ ์ฌ์ฉ\n\nnow()์ current_timestamp๋ ํธ๋์ญ์
๋ด์์ ์์ ์ ์
๋๋ค. clock_timestamp()๋ ํธ์ถํ ๋๋ง๋ค ๋ณํฉ๋๋ค. ํ ํธ๋์ญ์
์์ ์ฌ๋ฌ ์์ ์ ํ์์คํฌํ๋ฅผ ์์ฑํ๋ฉด์ ์ด ํจ์๋ค์ ์์ด ์ฐ๋ฉด ์ ๋ ฌ๊ณผ ๊ธฐ๊ฐ์ด ์ด์ํด ๋ณด์ผ ์ ์์ต๋๋ค.\n\n### ์ค์ 4: ๋ ๋ฒ ๋ณํํ๊ฑฐ๋ ๋ณํ์ ์ ํ ์ ํจ\n\n์์ฃผ ๋ฐ์ํ๋ API ๋ฒ๊ทธ: ์ฑ์ด ๋ก์ปฌ ์๊ฐ์ UTC๋ก ๋ณํํด ๋๊ณ , ์ด๋ฅผ ๋์ด๋ธ ๋ฌธ์์ด๋ก ์ ์กํ๋ฉด DB ์ธ์
์ด ์
๋ ฅ์ ๋ก์ปฌ ์๊ฐ์ผ๋ก ๊ฐ์ฃผํด ๋ค์ ๋ณํํ๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ๋ฐ๋ ๊ฒฝ์ฐ๋ ๋ฐ์ํฉ๋๋ค: ์ฑ์ด ๋ก์ปฌ ์๊ฐ์ ๋ณด๋๋๋ฐ Z(UTC)๋ฅผ ๋ถ์ฌ ์ ์กํด ๋ ๋๋ง ์ ์ด๋๋ฉ๋๋ค.\n\n### ์ค์ 5: ์๋ํ ์๊ฐ๋๋ฅผ ๋ฐํ์ง ์๊ณ ๋ ์ง๋ก ๊ทธ๋ฃนํ\n\nโ์ผ๋ณ ํฉ๊ณโ๋ ์ด๋ ๋ ๊ฒฝ๊ณ๋ฅผ ๋งํ๋์ง์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค. TIMESTAMPTZ์์ date(created_at)๋ก ๊ทธ๋ฃนํํ๋ฉด ๊ฒฐ๊ณผ๋ ์ธ์
์๊ฐ๋๋ฅผ ๋ฐ๋ฆ
๋๋ค. ๋ฆ์ ๋ฐค ์ด๋ฒคํธ๊ฐ ์ด์ ๋๋ ๋ค์ ๋ ๋ก ์ฎ๊ฒจ์ง ์ ์์ต๋๋ค.\n\n๋์๋ณด๋๋ API๋ฅผ ๋ฐฐํฌํ๊ธฐ ์ ์ ๊ธฐ๋ณธ์ ์ ๊ฒํ์ธ์: ์ฐจํธ๋ง๋ค ํ๋์ ๋ณด๊ณ ์๊ฐ๋๋ฅผ ์ ํํด ์ผ๊ด๋๊ฒ ์ ์ฉํ๊ณ , API ํ์ด๋ก๋์ ์คํ์
์ด๋ Z๋ฅผ ํฌํจ์ํค๊ณ , ์คํ
์ด์ง๊ณผ ํ๋ก๋์
์ ์๊ฐ๋ ์ ์ฑ
์ ์ผ์น์ํค๋ฉฐ, ๊ทธ๋ฃนํ ์ ์ด๋ค ์๊ฐ๋๋ฅผ ์๋ฏธํ๋์ง ๋ช
์ํ์ธ์.\n\n## ๋์๋ณด๋๋ API ๋ฐฐํฌ ์ ์ ๋น ๋ฅธ ์ ๊ฒํ\n\n์๊ฐ ๋ฒ๊ทธ๋ ๋ณดํต ํ๋์ ์๋ชป๋ ์ฟผ๋ฆฌ์์ ์ค๋ ๊ฒ์ด ์๋๋๋ค. ์ ์ฅ, ๋ณด๊ณ , API ๊ฐ๊ฐ์ด ์ฝ๊ฐ์ฉ ๋ค๋ฅธ ๊ฐ์ ์ ํ๊ธฐ ๋๋ฌธ์ ๋ฐ์ํฉ๋๋ค.\n\n๊ฐ๋จํ ์ถ๊ณ ์ ์ฒดํฌ๋ฆฌ์คํธ:\n\n- ์ค์ ์ด๋ฒคํธ(๊ฐ์
, ๊ฒฐ์ , ์ผ์ ์ ํธ)๋ ์ธ์คํดํธ๋ก TIMESTAMPTZ์ ์ ์ฅํ์ธ์.\n- ๋น์ฆ๋์ค ๋ก์ปฌ ๊ฐ๋
(์ฒญ๊ตฌ์ผ, ๋ณด๊ณ ๋ ์ง)์ DATE๋ TIME์ผ๋ก ์ ์ฅํ์ธ์. ๋์ค์ ๋ณํํ๋ ค๊ณ ํ์์คํฌํ์ ๋ฃ์ง ๋ง์ธ์.\n- ์ค์ผ์ค ์ก๊ณผ ๋ฆฌํฌํธ ๋ฌ๋์์๋ ์ธ์
์๊ฐ๋๋ฅผ ์๋์ ์ผ๋ก ์ค์ ํ์ธ์.\n- API ์๋ต์๋ ์คํ์
๋๋ Z๋ฅผ ํฌํจํ๊ณ , ํด๋ผ์ด์ธํธ๊ฐ ์ด๋ฅผ ์๊ฐ๋ ์ธ์ง๋ก ํ์ฑํ๋์ง ํ์ธํ์ธ์.\n- ๋์ ์๊ฐ๋์ DST ์ ํ ์ฃผ๋ฅผ ์ต์ ํ๋ ํ
์คํธํ์ธ์.\n\n๋น ๋ฅธ ์ข
๋จ๊ฐ ๊ฒ์ฆ: ํ๋์ ์๋ ค์ง ์ฃ์ง ์ผ์ด์ค ์ด๋ฒคํธ(์: DST ๊ด์ฐฐ ์ง์ญ์ 2026-03-08 01:30)๋ฅผ ๊ณจ๋ผ ์ ์ฅ, ์ฟผ๋ฆฌ ์ถ๋ ฅ, API JSON, ์ต์ข
์ฐจํธ ๋ผ๋ฒจ๊น์ง ๋ฐ๋ผ๊ฐ ๋ณด์ธ์. ์ฐจํธ๊ฐ ์ฌ๋ฐ๋ฅธ ๋ ์ง๋ฅผ ๋ณด์ฌ์ฃผ์ง๋ง ํดํ์ ์๋ชป๋ ์๊ฐ์ด ๋์ค๊ฑฐ๋ ๊ทธ ๋ฐ๋๋ผ๋ฉด ๋ณํ ๋ถ์ผ์น๊ฐ ์๋ ๊ฒ์
๋๋ค.\n\n## ์์: ๊ฐ์ ๋ ์ง ์์น๋ก ๋ ํ์ด ๋คํฌ๋ ์ด์ \n\n๋ด์์ ์ง์ํ๊ณผ ๋ฒ ๋ฅผ๋ฆฐ์ ์ฌ๋ฌดํ์ด ๊ฐ์ ๋์๋ณด๋๋ฅผ ๋ด
๋๋ค. DB ์๋ฒ๋ UTC๋ก ๋์ํฉ๋๋ค. ๋ชจ๋ ๊ฐ์ ์ซ์๊ฐ ๋ง๋ค๊ณ ์ฃผ์ฅํ์ง๋ง โ์ด์ โ๊ฐ ๋๊ตฌ์๊ฒ๋ ๋ค๋ฅด๊ฒ ๋ณด์
๋๋ค.\n\n์ฌ๊ฑด ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค: ๊ณ ๊ฐ ํฐ์ผ์ด ๋ด์ ์๊ฐ์ผ๋ก 3์ 10์ผ 23:30์ ์์ฑ๋์์ต๋๋ค. ์ด๋ UTC๋ก๋ 3์ 11์ผ 04:30, ๋ฒ ๋ฅผ๋ฆฐ์ผ๋ก๋ 05:30์
๋๋ค. ํ ๋ฒ์ ์ค์ ์๊ฐ, ์ธ ๊ฐ์ง ๋ฌ๋ ฅ ๋ ์ง.\n\n๋ง์ฝ ์์ฑ ์๊ฐ์ด TIMESTAMP(์๊ฐ๋ ์์)๋ก ์ ์ฅ๋์ด ์ฑ์ด ์ด๋ฅผ โ๋ก์ปฌโ๋ก ๊ฐ์ ํ๋ฉด ์ญ์ฌ๊ฐ ์กฐ์ฉํ ๋ค์ ์ฐ์ฌ์ง ์ ์์ต๋๋ค. ๋ด์์ 2026-03-10 23:30์ ๋ด์ ์๊ฐ์ผ๋ก ํด์ํ์ง๋ง ๋ฒ ๋ฅผ๋ฆฐ์ ๊ฐ์ ์ ์ฅ ๊ฐ์ ๋ฒ ๋ฅผ๋ฆฐ ์๊ฐ์ผ๋ก ํด์ํ ์ ์์ต๋๋ค. ๋์ผํ ํ์ด ์๋ก ๋ค๋ฅธ ๋ ์ง์ ๋์ด๊ฒ ๋ฉ๋๋ค.\n\nTIMESTAMPTZ๋ก ์ ์ฅํ๋ฉด PostgreSQL์ ์๊ฐ์ ์ผ๊ด๋๊ฒ ์ ์ฅํ๊ณ ์กฐํ๋ ํฌ๋งท ์์๋ง ๋ณํํฉ๋๋ค. ์ด ๋๋ฌธ์ TIMESTAMPTZ์ TIMESTAMP์ ์ฐจ์ด๊ฐ ๋ณด๊ณ ์์ โํ๋ฃจโ์ ์๋ฏธ๋ฅผ ๋ฐ๊ฟ๋๋ค.\n\nํด๊ฒฐ ๋ฐฉ๋ฒ์ ๋ ๊ฐ์ง ๊ฐ๋
์ ๋ถ๋ฆฌํ๋ ๊ฒ์
๋๋ค: ์ฌ๊ฑด์ด ๋ฐ์ํ ์๊ฐ(event instant), ๊ทธ๋ฆฌ๊ณ ์ฌ์ฉํ๊ณ ์ ํ๋ ๋ณด๊ณ ๋ ์ง(reporting date).\n\n์ค์ฉ์ ํจํด:\n\n1) ์ด๋ฒคํธ ์๊ฐ์ TIMESTAMPTZ๋ก ์ ์ฅํ์ธ์.\n2) ๋ณด๊ณ ๊ท์น์ ์ ํ์ธ์: ๋ทฐ์ด ๋ก์ปฌ(๊ฐ์ธ ๋์๋ณด๋)์ธ์ง, ์๋๋ฉด ํ๋์ ๋น์ฆ๋์ค ์กด(ํ์ฌ ์ ์ฒด ์ฌ๋ฌด)์ธ์ง.\n3) ์ฟผ๋ฆฌ ์ ํด๋น ๊ท์น์ผ๋ก ์ธ์คํดํธ๋ฅผ ์ ํํ ์กด์ผ๋ก ๋ณํํ ๋ค ๋ ์ง๋ฅผ ๊ณ์ฐํ์ธ์.\n\n## ๋ค์ ๋จ๊ณ: ์คํ ์ ๋ฐ์ ๊ฑธ์ณ ์๊ฐ ์ฒ๋ฆฌ ํ์คํ\n\n์๊ฐ ์ฒ๋ฆฌ ๊ท์น์ด ๋ฌธ์ํ๋์ด ์์ง ์์ผ๋ฉด ์ ๋ฆฌํฌํธ๋ง๋ค ์ถ์ธก ๊ฒ์์ด ๋ฉ๋๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค, API, ๋์๋ณด๋ ์ ๋ฐ์์ ์ง๋ฃจํ๊ณ ์์ธก ๊ฐ๋ฅํ ์๊ฐ ๋์์ผ๋ก ๋ชฉํ๋ฅผ ์ธ์ฐ์ธ์.\n\n์งง์ โ์๊ฐ ๊ณ์ฝ(time contract)โ์ ์์ฑํด ์ธ ๊ฐ์ง ์ง๋ฌธ์ ๋ตํ์ธ์:\n\n- ์ด๋ฒคํธ ์๊ฐ ํ์ค: ํน๋ณํ ์ด์ ๊ฐ ์๋ค๋ฉด ์ด๋ฒคํธ ์ธ์คํดํธ๋ฅผ TIMESTAMPTZ(๋ณดํต UTC)๋ก ์ ์ฅํ์ธ์.\n- ๋น์ฆ๋์ค ์๊ฐ๋: ๋ณด๊ณ ์ ์ฌ์ฉํ ํ๋์ ์กด์ ์ ํํ๊ณ ์ผ/์ฃผ/์์ ์ ์ํ ๋ ์ผ๊ด๋๊ฒ ์ฌ์ฉํ์ธ์.\n- API ํฌ๋งท: ํ์์คํฌํ๋ ํญ์ ์คํ์
์ ํฌํจํ ISO 8601(๋๋ Z)๋ก ๋ณด๋ด๊ณ , ๊ฐ ํ๋๊ฐ โinstantโ์ธ์ง โlocal wall timeโ์ธ์ง ๋ฌธ์ํํ์ธ์.\n\nDST ์์๊ณผ ์ข
๋ฃ ์ฃผ๋ณ์ ์์ ํ
์คํธ๋ฅผ ์ถ๊ฐํ์ธ์. ๋น์ฉ์ด ํฐ ๋ฒ๊ทธ๋ฅผ ์ด๊ธฐ์ ์ก์๋
๋๋ค. ์๋ฅผ ๋ค์ด, ํน์ ๋น์ฆ๋์ค ์กด์ ๋ํด โ์ผ๋ณ ํฉ๊ณโ ์ฟผ๋ฆฌ๊ฐ DST ๋ณ๊ฒฝ ์ ํ์๋ ์์ ์ ์ธ์ง, ๋ํ 2026-11-01T01:30:00-04:00๊ณผ 2026-11-01T01:30:00-05:00์ด ์๋ก ๋ค๋ฅธ ์๊ฐ์ผ๋ก ์ฒ๋ฆฌ๋๋์ง ๊ฒ์ฆํ์ธ์.\n\n๋ง์ด๊ทธ๋ ์ด์
์ ์ ์คํ ๊ณํํ์ธ์. ํ์
๊ณผ ๊ฐ์ ์ ์ ์๋ฆฌ์์ ๋ฐ๊พธ๋ฉด ์ฐจํธ์ ์ญ์ฌ๊ฐ ์กฐ์ฉํ ๋ค์ ์ฐ์ผ ์ ์์ต๋๋ค. ๋ ์์ ํ ๋ฐฉ๋ฒ์ ์ ์นผ๋ผ์ ์ถ๊ฐํ๋ ๊ฒ์
๋๋ค(์: created_at_utc TIMESTAMPTZ), ๊ฒํ ๋ ๋ณํ์ผ๋ก ๋ฐฑํํ๊ณ ์ฝ๊ธฐ๋ฅผ ์ ์นผ๋ผ์ผ๋ก ์ ํํ ๋ค, ์ ์ ๋์ ์ ๋ณด๊ณ ์ ์ ๋ณด๊ณ ๋ฅผ ๋ณํํด ์ผ๋ณ ์์น์ ๋ณํ๋ฅผ ๋ช
ํํ ํ์ธํ ๋ค์ ์ ์นผ๋ผ์ ์ ๊ฑฐํ์ธ์.\n\n๋ง์ฝ ๋ฐ์ดํฐ ๋ชจ๋ธ, API, ์คํฌ๋ฆฐ ์ ๋ฐ์์ ์ด โ์๊ฐ ๊ณ์ฝโ์ ์ ์ฉํ ์ค์ ์ฅ์๊ฐ ํ์ํ๋ค๋ฉด ํตํฉ๋ ๋น๋ ์ค์ ์ด ๋์์ด ๋ฉ๋๋ค. AppMaster (appmaster.io)๋ ํ๋์ ํ๋ก์ ํธ์์ ๋ฐฑ์๋, ์น ์ฑ, API๋ฅผ ์์ฑํด ํ์์คํฌํ ์ ์ฅ๊ณผ ํ์ ๊ท์น์ ์ฑ ์ฑ์ฅ์ ๋ง์ถฐ ์ผ๊ด๋๊ฒ ์ ์งํ๊ธฐ ์ฝ๋๋ก ํฉ๋๋ค.
์์ฃผ ๋ฌป๋ ์ง๋ฌธ
Use TIMESTAMPTZ for anything that happened at a real moment (signups, payments, logins, messages, sensor pings). It stores one unambiguous instant and can be safely sorted, filtered, and compared across systems. Use plain TIMESTAMP only when the value is meant to be a wall-clock time that should stay exactly as written, usually paired with a separate time zone or location field.
TIMESTAMPTZ represents a real instant in time; PostgreSQL normalizes it internally and then displays it in your session time zone. TIMESTAMP is just a date and clock time with no zone attached, so PostgreSQL wonโt shift it automatically. The key difference is meaning: instant versus local wall time.
Because the session time zone controls how TIMESTAMPTZ is formatted on output and how some inputs are interpreted. Two tools can query the same row and show different clock times if one session is set to UTC and another to America/Los_Angeles. For reports and APIs, set the session time zone explicitly so results donโt depend on hidden defaults.
Because โa dayโ depends on a time zone boundary. If one dashboard groups by viewer-local time while another groups by UTC (or a business zone), late-night events can fall on different dates and change daily totals. Fix it by picking one grouping rule per chart (UTC or a specific business zone) and using it consistently in SQL, BI, and exports.
DST creates missing or duplicated local hours, which can produce gaps or double-counted buckets when grouping by local time. If your data represents real moments, store it as TIMESTAMPTZ and choose a clear chart time zone for bucketing. Also test the DST transition week for your target zones to catch surprises early.
No, PostgreSQL does not preserve the original time zone label with TIMESTAMPTZ; it stores the instant. When you query it, PostgreSQL displays it in the session time zone, which may differ from the userโs original zone. If you need โshow it in the customerโs time zone,โ store that zone separately in another column.
Return ISO 8601 timestamps that include an offset, and be consistent. A simple default is to always return UTC with Z for event instants, then let clients convert for display. Avoid sending โnaiveโ strings like 2026-03-10 23:30:00 because clients will guess the zone differently.
Convert at the edges: store event instants as TIMESTAMPTZ, then convert to the desired zone when you display or bucket for reporting. Avoid converting back and forth inside triggers, background jobs, and ETL unless you have a clear contract. Most reporting problems come from double conversion or from mixing naive and time-zone-aware values.
Use DATE for business concepts that are truly dates, like โbilling day,โ โreporting date,โ or โdelivery date.โ Use TIME (or TIMESTAMP plus a separate time zone) for schedules like โopens at 09:00 local time.โ Donโt force these into TIMESTAMPTZ unless you really mean a single instant, because DST and zone changes can shift the intended meaning.
First, decide whether itโs an instant (TIMESTAMPTZ) or a local wall time (TIMESTAMP plus zone), then add a new column instead of rewriting in place. Backfill with a reviewed conversion under a known session time zone, and validate sample rows around midnight and DST boundaries. Run old and new reports side by side briefly so any shifts in totals are obvious before you remove the old column.


