Skip to content
Published on

2026년에도 윤초는 없다 — 그리고 아무도 겪어본 적 없는 음의 윤초

공유하기
Authors

들어가며 — 윤초, 그리고 UTC와 TAI와 지구 자전

대부분의 개발자는 시간을 "그냥 균일하게 흐르는 것"으로 가정하고 코드를 짭니다. 하지만 우리가 쓰는 UTC는 두 개의 서로 다른 시간 사이의 타협물입니다. 하나는 원자시계로 재는 국제원자시(TAI)로, 완벽하게 균일한 초를 뿜어냅니다. 다른 하나는 지구 자전으로 정의되는 천문시(UT1)인데, 지구는 조석 마찰과 내부 요동 때문에 조금씩 흔들리며 자전 속도가 변합니다.

UTC는 TAI의 균일한 초로 째깍거리되, UT1에서 0.9초 이상 벌어지지 않도록 가끔 1초를 끼워 넣습니다. 이 끼워 넣는 1초가 윤초(leap second)입니다. 양의 윤초는 이렇게 생깁니다 — 그날의 마지막 분이 61초가 됩니다.

양의 윤초:   23:59:58 → 23:59:59 → 23:59:60 → 00:00:00

문제의 씨앗은 여기 있습니다. 23:59:60이라는 시각은 실제로 존재하지만, 뒤에서 보듯 유닉스 시간에는 이걸 담을 자리가 없습니다. 1972년 도입 이후 윤초는 27번 들어갔고 전부 양의 윤초였습니다. 마지막은 2016년 12월 31일. 그 결과 현재 TAI - UTC = 37초, 뒤집어 말하면 UTC - TAI = -37초입니다.

2026년: 윤초 없음, 그리고 처음 겪을 음의 윤초

2026년 7월 6일, 파리에서 IERS가 Bulletin C 72를 발표했습니다. 핵심은 한 줄입니다.

IERS Bulletin C 72 — Paris, 06 July 2026
"NO leap second will be introduced ... at the end of December 2026."
UTC - TAI = -37 s   (2017-01-01 이후 변동 없음)

즉 2026년 12월에도 윤초는 없습니다(6월 말에도 없었습니다). 벌써 몇 년째 아무 조정이 없는 셈인데, 이게 조용한 뉴스가 아닌 이유가 있습니다. 2016년 무렵부터 지구 자전이 오히려 빨라지기 시작했습니다. 자전이 계속 빨라져 UT1이 UTC보다 앞서 나가면, 언젠가는 UTC에서 1초를 빼서 따라잡아야 합니다. 사상 처음으로 음의 윤초(negative leap second)를 넣어야 하는 상황입니다.

음의 윤초는 양의 윤초와 정반대로, 1초를 지웁니다. 그날의 마지막 분은 59초가 됩니다.

음의 윤초:   23:59:58 → 00:00:00        (23:59:59 삭제)

지금까지 27번 모두 양의 윤초였고, 음의 윤초는 규격에만 존재할 뿐 지구상 어디에서도 실제로 적용된 적이 없습니다. BIPM 시간부의 Patrizia Tavella는 "2035년까지 기다리면 음의 윤초가 필요해질 확률이 30%"라고 추정했습니다. 한편 2022년 CGPM 결의 4호는 윤초를 "2035년 또는 그 이전"에 사실상 폐지하고 UT1과 UTC의 허용 오차를 훨씬 크게 늘리기로 했으며, 새 허용치는 2026년 10월 제28차 CGPM에서 정해질 예정입니다. 하지만 이 결정도 2035년까지 남은 위험을 없애 주지는 않습니다.

왜 분산 시스템에 위험한가 — POSIX 시간, NTP, 그리고 2012·2017년의 교훈

유닉스 시간의 정의는 단순합니다. 유닉스 시간 = (에포크 이후 일수) × 86400 + 그날의 초. 즉 "하루는 무조건 86400초"라고 못 박습니다. 그래서 23:59:60을 표현할 자리가 없습니다.

  • 양의 윤초에서 유닉스 계열은 보통 그 1초를 반복하거나 시계를 1초 되돌립니다. 시간이 뒤로 가거나 같은 타임스탬프가 두 번 나옵니다(비단조).
  • 음의 윤초에서는 타임스탬프가 한 칸을 건너뜁니다. 시간은 여전히 앞으로만 가지만, 23:59:59 자리에 해당하는 유닉스 값은 아무 실제 순간에도 대응하지 않는 "구멍"으로 남습니다.

이 가정이 깨지면 무슨 일이 나는지 우리는 이미 봤습니다. 2012년 7월 1일 윤초 때 리눅스 커널 타이머(hrtimer) 버그가 라이브락을 일으켜 CPU가 100%로 튀었고, Reddit과 Mozilla 등이 영향을 받았으며, 아마데우스 항공 예약 시스템 장애로 콴타스 항공편 일부가 지연됐습니다. 대개는 NTP를 재시작하거나 시계를 리셋해 넘겼습니다.

2016년 12월 31일 윤초가 자정에 적용되자, Cloudflare의 Go로 짠 DNS 리졸버가 "시간은 항상 앞으로만 간다"고 가정하고 두 시각을 빼다가 음수 간격을 얻었고, 그 값이 난수 범위 계산에 들어가면서 일부 DNS 질의가 에러를 냈습니다. Cloudflare는 이 사후분석을 공개했습니다.

두 사건의 뿌리는 같습니다 — 코드가 "시간은 균일하고 단조롭게 흐른다"고 믿은 것입니다. 여기서 반전이 하나 있습니다. 음의 윤초는 시간을 앞으로 건너뛰므로, 2017년 Cloudflare식 "음수 간격" 버그는 오히려 나지 않습니다(단조성 유지). HN 토론에서도 "앞으로 점프하는 건 뒤로 점프처럼 시간 루프를 만들지 않는다"는 지적이 나왔습니다. 진짜 문제는 다릅니다 — 음의 윤초 처리 경로는 지금껏 어떤 프로덕션에서도 한 번도 실행된 적이 없습니다. "1분은 60초", 항상 +1만 가정하는 하드코딩된 윤초 테이블, 스미어를 반대 방향(시계를 빠르게)으로 도는 로직은 전부 검증되지 않은 코드입니다.

NTP 쪽도 마찬가지입니다. Google, Amazon, Meta는 윤초를 일정 구간에 걸쳐 "문질러(smear)" 없앱니다(Google과 AWS는 24시간). 그래서 애플리케이션에는 23:59:60이 아예 보이지 않습니다. 하지만 구간 길이와 곡선이 회사마다 다르고, 스미어 서버와 비스미어 서버를 한 함대에 섞으면 시계가 서로 어긋납니다. 음의 윤초에서는 스미어가 시계를 살짝 빠르게 돌려 1초를 회수해야 하는데, 이 역시 대규모로 돌려본 적이 없습니다.

마치며 — 지금 확인해야 할 것

  • 내 플랫폼이 윤초를 어떻게 다루는지 알아 두세요 — 스텝(step), 반복(repeat), 스미어(smear) 중 무엇인가. 함대 전체가 같은 방식이어야 하고, 스미어와 비스미어 NTP를 섞지 마세요.
  • 기간과 타임아웃 측정에는 벽시계(CLOCK_REALTIME)가 아니라 단조 시계(CLOCK_MONOTONIC)를 쓰세요. 2017년 Cloudflare 버그가 정확히 벽시계 뺄셈이었습니다.
  • "1분 = 60초", "하루 = 86400초", "윤초는 항상 +1"을 코드에 박지 마세요.
  • 정렬, 유일성, 순서 보장을 벽시계 타임스탬프에 의존하지 마세요 — 논리 시계나 단조 소스, TrueTime식 구간을 쓰세요.
  • 테스트하세요. 시계를 실제로 한 칸 건너뛰게 만들면 음의 윤초를 흉내 낼 수 있습니다. 대부분의 조직은 한 번도 해 본 적이 없습니다.

정직하게 말하면, 2026년 12월에는 아무 일도 일어나지 않습니다(윤초 없음). 이 글의 요점은 공포가 아니라 준비입니다. 지구 자전은 이미 방향을 틀었고, 언젠가(아마 2035년 전에) 우리는 한 번도 실행된 적 없는 코드 경로를 전 지구가 동시에 밟게 됩니다. 그 전에, 벽시계를 맹신하는 코드부터 골라내는 게 좋습니다.

참고 자료