ISO 8601, 그리고 날짜를 모호하지 않게 쓰는 법
· 약 3분
ISO 8601이 존재하는 이유는 03/04/2026이 미국에서는 3월이고 다른 곳에서는 4월이기 때문입니다. 2026-04-03이라고 쓰면 모호함이 사라지고, 텍스트로도 올바르게 정렬되며, 모든 인터페이스가 받아들여야 할 형식이 됩니다.
03/04/2026은 세계 대부분에서 4월 3일이고 미국에서는 3월 4일입니다. 그 문자열만으로 어느 쪽을 뜻했는지 알 길은 없고, 두 읽기 모두 지극히 합당합니다. 해마다 이 모호함은 놓친 마감과 이중 예약, 그리고 적어도 한 번의 기억할 만한 장애를 만들어 냅니다.
ISO 8601은 그것을 없애는 국제 표준입니다.
핵심 형식
2026-04-03T14:30:00Z
왼쪽에서 오른쪽으로, 큰 단위에서 작은 단위로 읽습니다.
2026-04-03— 연, 월, 일. 각각 0을 채우고, 언제나 이 순서로T— 날짜와 시각의 구분자. 엄격한 형식에서는 필수14:30:00— 24시간제의 시, 분, 초Z— 시간대 지시자.Z는 정확히 UTC를 뜻함
핵심은 순서입니다. 구성 요소가 가장 중요한 것에서 가장 덜 중요한 것으로 이어지기 때문에, ISO 8601 문자열은 평범한 텍스트로도 올바르게 정렬됩니다. 단순 문자열 비교에서 2026-04-03이 2026-04-10보다 앞에 옵니다. 다른 어떤 흔한 형식도 해내지 못하는 일입니다. 이 성질 하나만으로도 표준은 값을 합니다.
시간대 지시자
세 가지 형태가 유효하고, 뜻하는 바가 서로 다릅니다.
| 형태 | 뜻 |
|---|---|
2026-04-03T14:30:00Z |
14:30 UTC. 모호하지 않음 |
2026-04-03T14:30:00+05:45 |
UTC보다 5시간 45분 빠른 시간대의 지역 시각 14:30. 모호하지 않음 |
2026-04-03T14:30:00 |
명시되지 않은 시간대의 14:30. 타임스탬프가 아님 |
말썽을 부르는 것은 세 번째입니다. 그것은 지역 날짜-시각, 곧 시간축 위에 놓을 방법이 없는 벽시계 읽기입니다. 그것을 시스템 경계 너머로 넘기면서 상대편이 당신과 같은 시간대를 가정해 주기를 바라는 것은, 다른 지역으로의 배포를 기다리고 있는 결함입니다.
시차가 무엇이 아닌지도 눈여겨보세요. +05:45는 네팔의 시차를 알려 줄 뿐, 그 타임스탬프가 네팔의 것이라고 말하지 않습니다. 시차는 시간대가 아닙니다. 같은 시차를 여러 시간대가 함께 쓰고, 한 시간대의 시차는 바뀝니다. 어디인지 알아야 한다면 식별자를 나란히 지니세요.
RFC 3339, 아마도 당신이 원하는 프로파일
ISO 8601은 큽니다. 주 날짜(2026-W14-5), 서수 날짜(2026-093), 소수 단위, 그리고 세기를 생략하는 축약 형태까지 허용합니다. 그 대부분은 인터페이스에서 원하는 것이 아닙니다.
RFC 3339은 인터넷 프로토콜을 위해 죈 프로파일입니다. 완전한 날짜를 요구하고, 시간대 지시자를 요구하며, 구분자로 T나 공백을 허용합니다. API를 두고 누군가 “ISO 형식”이라고 말한다면 거의 언제나 RFC 3339를 뜻합니다.
쓸 만한 규칙: 좋은 파서가 받아 주는 것은 무엇이든 받아들이되, 내보내는 것은 Z가 붙은 엄격한 RFC 3339뿐이게 하세요.
기간과 구간
덜 쓰이지만, 마주쳤을 때 알아 두면 좋습니다.
기간은 「period」의 P로 시작하고, T가 날짜 부분과 시각 부분을 가릅니다.
P3Y6M4D— 3년 6개월 4일PT1H30M— 1시간 30분P1DT12H— 1일 12시간
T는 선택이 아닙니다. P1M은 1개월이고 PT1M은 1분입니다. ISO 8601 기간의 고전적인 결함이 이것입니다.
구간은 두 지점을 빗금으로 잇습니다. 2026-04-03T14:00Z/2026-04-03T16:00Z, 또는 한 지점과 기간으로 2026-04-03T14:00Z/PT2H.
이 사이트의 HowTo 구조화 데이터는 기간 문법을 씁니다. 2분짜리 작업이면 PT2M입니다. schema.org가 ISO 8601 기간을 규정하기 때문입니다.
주 날짜, 그리고 그 안의 함정
2026-W14-5는 2026년 열네 번째 ISO 주의 금요일입니다. ISO 주는 월요일에 시작하고, 1주는 1월의 첫 목요일이 든 주입니다.
사람들이 걸려 넘어지는 결과는 이것입니다. ISO 주 연도는 늘 달력 연도와 같지 않습니다. 2027년 1월 1일은 2026년의 53번째 ISO 주에 듭니다. ISO 주 번호를 달력 연도와 짝지어 놓은 형식화 코드는 해마다 며칠 동안 틀린 날짜를 만들어 냅니다. 게다가 대부분의 언어에서 형식 지정자는 거의 똑같이 생겼습니다(YYYY 대 GGGG, 또는 %Y 대 %G).
실무 규칙
- UTC로 저장하고
Z로 내보내세요.2026-04-03T14:30:00Z는 어디서나 뜻이 정확히 하나입니다. - 맨 지역 날짜-시각을 경계 너머로 내보내지 마세요. 시간대를 붙일 수 없다면 그것은 타임스탬프가 아닙니다.
- 모든 자리를 0으로 채우세요.
2026-4-3은 유효한 ISO 8601이 아닙니다. 대부분의 파서가 받아 준다 해도요. -와:구분자를 쓰세요. 압축 형태(20260403T143000Z)는 합법이지만 불친절하고, 거부하는 파서도 있습니다.- 시간대 식별자는 따로 지니세요. _어느 시차인지_가 아니라 _어디인지_를 알아야 할 때 말입니다.
Europe/London은 규칙 변경에서 살아남지만+01:00은 그러지 못합니다.
파싱의 함정
표준이 있어도 일이 틀어지는 곳은 파싱입니다.
자바스크립트의 Date 생성자는 ISO가 아닌 입력에서 일관되지 않습니다. new Date('2026-04-03')은 UTC 자정으로 해석됩니다. new Date('2026-04-03T00:00:00')은 — 시간대 지시자가 없으므로 — 지역 자정으로 해석됩니다. 둘은 여러분의 시차만큼 다르고, 그 말은 같은 코드가 실행되는 곳에 따라 다른 날짜를 낸다는 뜻입니다. 언제나 시간대 지시자를 넣으세요.
두 자리 연도는 모호하니 거부해야 합니다. ISO 8601은 축약 형태를 허용하지만, 그것을 받아들여야 할 것은 거의 없습니다. 26-04-03은 1926년일 수도 2026년일 수도 있고, 그것을 판정하는 이동 창은 파서 안에 숨은 정책 결정입니다.
초의 소수 자릿수는 정밀도가 제각각입니다. 14:30:00.5, 14:30:00.500, 14:30:00.500000은 모두 유효하고 모두 같은 순간입니다. 순간이 아니라 문자열을 비교하는 파서는 그렇게 보지 않습니다.
쉼표는 합법입니다. ISO 8601은 14:30:00,5라는 소수점 쉼표를 허용하고, 오히려 선호합니다. 대부분의 파서는 거부합니다. 유럽 시스템에서 데이터를 받는다면 대비하세요.
자정에는 두 가지 표기가 있습니다. 어느 날의 24:00:00은 다음 날의 00:00:00과 같은 순간이고, 둘 다 유효한 ISO 8601입니다. 내보낼 때는 뒤엣것으로, 받을 때는 둘 다 받으세요.
정렬에 관한 한마디
ISO 8601의 정렬 가능성은 시간대 표현이 같은 문자열들 사이에서만 성립합니다. 2026-04-03T14:00:00Z와 2026-04-03T10:00:00-05:00은 같은 순간이지만, 문자열로는 뒤엣것이 앞에 옵니다.
타임스탬프를 텍스트로 정렬한다면 — 로그 파일에서, 파일 이름에서, 텍스트로 정의된 데이터베이스 열에서 — 먼저 전부 Z가 붙은 UTC로 정규화하세요. 그러지 않으면 그 순서는 시간의 성질이 아니라 서식의 성질이 됩니다.