TAI
고친 사람 github-actions[bot]
TAI 는 원자시계가 센 초를 한 번도 끊지 않고 이어 세는 세계 기준 시각입니다. 1초를 끼우거나 빼는 일이 없어서 값이 건너뛰거나 되돌아가지 않습니다. 일상에서 쓰는 UTC 는 이 시각보다 몇십 초 뒤에 서 있습니다.
쉽고 빠른 이해
TAI 는 원자시계의 초를 처음부터 쉬지 않고 세어 온 시각입니다. 지금 TAI 는 우리가 쓰는 UTC 보다 37초 앞서 있습니다.
UTC 는 지구 자전에 맞추려고 가끔 1초를 끼워 넣습니다. 그 1초 동안 시계가 같은 초를 두 번 가리키거나 뒤로 돌아가는 시스템이 생깁니다. TAI 에는 끼우는 1초가 없습니다. 두 시각을 빼기만 하면 그 사이에 흐른 초가 맞게 나옵니다.
- 세계 여러 연구소의 원자시계가 1초씩 셉니다
- 국제도량형국이 그 값을 모아 하나의 시각으로 엮습니다
- UTC 는 1초를 끼울 때마다 이 시각에서 1초씩 더 뒤로 처집니다
대가는 사람의 달력과 어긋난다는 것입니다. TAI 로 적힌 시각을 사람에게 보여 주려면 그때의 차이를 알아야 UTC 로 바꿀 수 있습니다.
상세
TAI(Temps Atomique International, 국제원자시)를 알려면 시각을 세는 두 방식을 먼저 갈라야 합니다. 하나는 원자의 떨림으로 초를 세는 방식입니다. 다른 하나는 지구가 한 바퀴 도는 것으로 하루를 재는 방식입니다. TAI 는 앞의 방식만 따라서 1초를 끼우거나 빼는 일이 없습니다.
아래 소절들은 원자시계가 1초를 정하는 방식에서 출발합니다. 이어서 그 초를 모아 TAI 를 만드는 과정, 일상에서 쓰는 시각과 벌어진 차이, 백엔드가 TAI 를 만나는 곳을 차례로 짚습니다.
TAI 는 프랑스어 이름의 머리글자입니다. 프랑스어로 「국제원자시」라는 뜻입니다. 영어로는 International Atomic Time 이라 부르지만 머리글자는 프랑스어 이름에서 땄습니다.
원자시계가 정하는 1초
원자시계는 원자가 내놓는 전자기파의 떨림을 세는 시계입니다. 같은 종류의 원자는 언제 어디서든 같은 빠르기로 떨립니다. 떨림을 정해진 횟수만큼 센 길이를 1초로 삼으면 1초의 길이가 흔들리지 않습니다.
국제단위계가 정한 1초는 세슘 원자가 내놓는 특정 전자기파가 9,192,631,770번 떨리는 길이입니다. 지구가 도는 빠르기나 계절과는 상관이 없습니다. TAI 는 이 1초를 단위로 셉니다.
여러 원자시계를 모아 만드는 시각
시계 하나만 믿으면 그 시계가 고장 나거나 조금씩 틀어질 때 기준도 같이 흔들립니다. 그래서 TAI 는 세계 여러 연구소가 돌리는 원자시계의 값을 모아 만듭니다.
모으고 계산하는 일은 BIPM(Bureau International des Poids et Mesures, 국제도량형국)이 맡습니다. 연구소들이 자기 시계의 값을 보내면 국제도량형국이 이를 견주어 하나의 시각으로 엮습니다. 이렇게 엮은 시각이 TAI 입니다.
TAI 는 1958년 1월 1일을 출발점으로 삼습니다. 그때부터 끊김 없이 이어집니다. 적는 모양은 보통 시각과 같습니다. 날짜와 시·분·초로 적습니다.
UTC 와 벌어진 37초
UTC(Coordinated Universal Time, 협정 세계시)는 전 세계가 일상에서 함께 쓰는 기준 시각입니다. 서버 로그와 데이터베이스의 시각도 대개 UTC 로 적힙니다. 1972년부터 UTC 는 TAI 와 같은 빠르기로 갑니다. TAI 가 1초 늘면 UTC 도 1초 늡니다.
둘이 갈리는 곳은 윤초입니다. 사람의 하루는 해가 뜨고 지는 것, 곧 지구가 도는 것이 정합니다. 그런데 지구가 도는 빠르기는 조금씩 흔들립니다. 원자시계만 따르면 시계의 정오와 해의 정오가 서서히 벌어집니다.
UTC 는 이 벌어짐을 1초 단위로 메웁니다. 벌어짐이 커지면 어느 달의 마지막 1분에 1초를 끼워 넣습니다. 이 1초가 윤초입니다. TAI 는 윤초를 받지 않습니다. 그래서 윤초가 하나 들 때마다 UTC 는 TAI 보다 1초씩 더 뒤로 처집니다.
차이는 0 에서 시작하지 않았습니다. 1972년 전의 UTC 는 1초의 길이를 원자시계와 조금 다르게 두고, 1초보다 작은 조각을 끼우면서 지구 자전을 따라갔습니다. 그동안 UTC 는 TAI 에서 조금씩 떨어졌습니다.
지금 같은 윤초 방식은 1972년 1월 1일에 시작했습니다. 그날 그때까지 벌어진 차이를 10초라는 정수로 끊어 맞췄습니다. 그 뒤로 윤초가 27번 들었습니다. 2017년 1월 1일부터 지금까지 TAI 는 UTC 보다 37초 앞서 있습니다.
윤초가 드는 순간을 두 시각으로 나란히 적으면 차이가 벌어지는 모습이 보입니다. 아래는 2016년 12월 31일 끝에 든 마지막 윤초의 앞뒤 세 초입니다. 왼쪽이 UTC 이고 주석이 같은 순간의 TAI 입니다.
UTC 12-31 23:59:59 // TAI 01-01 00:00:35
UTC 12-31 23:59:60 // TAI 01-01 00:00:36
UTC 01-01 00:00:00 // TAI 01-01 00:00:37
UTC 는 59초 다음에 60초라는 번호를 하나 더 씁니다. TAI 는 35, 36, 37 로 늘 하던 대로 셉니다. 윤초 앞에는 차이가 36초였습니다. 윤초 뒤에는 37초가 됐습니다.
방금 본 두 시각이 어디서 나오는지 한 그림으로 모으면 아래와 같습니다.
flowchart TD
C["여러 연구소의 원자시계"] --> B["국제도량형국 · 값을 모아 엮는다"]
B --> T["TAI · 끊김 없이 1초씩 는다"]
T --> U["UTC · TAI 보다 37초 뒤"]
E["지구 자전"] -.->|"벌어지면 윤초"| U
위에서 아래로 시각 하나가 만들어집니다. TAI 는 원자시계의 값만 받습니다. UTC 는 TAI 의 빠르기를 받습니다. 그리고 옆에서 들어오는 지구 자전에 맞춰 윤초를 받습니다.
정의로는 이 순서대로 TAI 가 먼저 서고 UTC 가 거기서 나옵니다. 그런데 TAI 는 여러 연구소의 값을 모아 계산한 뒤에야 확정됩니다. 그래서 지금 이 순간의 TAI 를 곧바로 받을 수는 없습니다.
실시간으로는 방향이 거꾸로입니다. 컴퓨터는 각 나라 연구소가 자기 원자시계로 내보내는 UTC 를 시각 동기화로 받아 씁니다. 그리고 TAI 가 필요하면 손에 쥔 UTC 에 그때의 차이 37초를 더해 얻습니다.
윤초 없이 세야 하는 까닭
유닉스 시간은 1970년 1월 1일 0시 UTC 부터 흐른 초의 수로 시각을 적습니다. 하루를 늘 86400초로 칩니다. 윤초에 붙일 번호가 없어서 윤초 1초를 세지 않습니다.
그래서 윤초를 사이에 둔 두 유닉스 시간을 빼면 흐른 초보다 1초 적게 나옵니다. 앞의 예에서 UTC 23시 59분 59초부터 이튿날 0시 0분 0초까지는 2초가 흘렀습니다. 유닉스 시간으로 빼면 1초가 나옵니다. TAI 로 빼면 2초가 나옵니다.
리눅스의 CLOCK_REALTIME 처럼 UTC 를 따르는 시계는 윤초가 끝날 때 1초 뒤로 돌아가 같은 초를 한 번 더 셉니다. 그러면 나중에 찍은 로그가 먼저 찍은 로그보다 이른 시각을 받습니다. TAI 는 번호가 건너뛰지도 되풀이되지도 않으므로 이런 일이 없습니다.
TAI 를 나르는 프로토콜과 위성
PTP(Precision Time Protocol, 정밀 시간 프로토콜)는 네트워크의 기기끼리 시각을 아주 정밀하게 맞추는 프로토콜입니다. PTP 는 시각을 TAI 로 나릅니다. 윤초가 드는 날에도 나르는 값이 건너뛰지 않게 하려는 것입니다. 받는 쪽은 함께 온 TAI 와 UTC 의 차이를 빼서 UTC 를 얻습니다.
GPS(Global Positioning System, 위성 위치 확인 시스템) 위성이 쓰는 시각도 윤초 없이 셉니다. GPS 시각은 1980년 1월 6일에 그때의 UTC 와 맞춰 출발했고, 그때 UTC 는 TAI 보다 19초 뒤였습니다. 그래서 GPS 시각과 TAI 의 차이는 늘 19초로 고정되어 있습니다. TAI 가 19초 앞섭니다.
리눅스의 CLOCK_TAI
리눅스에서 프로그램은 clock_gettime 호출로 시각을 읽습니다. 이때 어느 시계를 읽을지 이름으로 고릅니다. 앞에서 본 CLOCK_REALTIME 은 「지금 몇 시」를 알려 주는 시계라서 벽시계라고도 부릅니다. UTC 를 따르므로 윤초 때 흔들립니다.
CLOCK_TAI는 CLOCK_REALTIME 에 TAI 와 UTC 의 차이를 더해 만든 시계입니다. 더하는 일은 커널이 맡습니다. 윤초가 들면 이 차이도 1초 늘어서 CLOCK_TAI 는 건너뛰거나 되돌아가지 않습니다.
그런데 커널은 이 차이를 스스로 알지 못합니다. 시각을 맞추는 NTP(Network Time Protocol, 네트워크 시간 프로토콜) 데몬 같은 프로그램이 adjtimex 호출로 알려 줘야 합니다.
아래는 두 시계를 잇달아 읽은 값입니다. 둘 다 1970년 1월 1일 0시를 0으로 놓고 센 값입니다. CLOCK_TAI 는 거기에 TAI 와 UTC 의 차이를 더한 값입니다.
CLOCK_REALTIME : 1585985459.446 // UTC
CLOCK_TAI : 1585985496.447 // 37초 앞
두 값은 37초 차이가 납니다. 앞에서 본 TAI 와 UTC 의 차이와 같습니다.
아무도 차이를 알려 주지 않은 기계에서는 이 차이가 0 으로 남습니다. 그러면 CLOCK_TAI 가 CLOCK_REALTIME 과 똑같은 값을 냅니다. 오류가 나지 않아서 틀린 줄 모르고 지나가기 쉽습니다.
TAI 와 UTC 와 단조 시계의 쓰임
단조 시계는 늘기만 하고 뒤로 가지 않는 시계입니다. 한 기계 안에서 걸린 시간을 재는 데는 이것으로 충분합니다. 대신 출발점이 기계마다 달라서 다른 기계의 값과 견줄 수 없습니다.
TAI 는 세계가 함께 쓰는 시각이라 기계끼리 견줄 수 있고, 윤초를 넘어도 초를 잃지 않습니다. 사람의 달력과는 37초 어긋나 있어서 보여 줄 때는 UTC 로 바꿔야 합니다.
| 하려는 일 | 고르는 시각 |
|---|---|
| 사람에게 시각을 보여 준다 | UTC |
| 로그와 데이터베이스에 시각을 적는다 | UTC |
| 한 기계 안에서 걸린 시간을 잰다 | 단조 시계 |
| 여러 기계에 걸쳐 윤초 너머까지 흐른 초를 센다 | TAI |
백엔드가 흔히 만나는 일은 위 세 줄입니다. TAI 는 마지막 줄처럼 1초의 끊김도 견디지 못하는 일에서 고릅니다.
관련 항목
TAI 의 1초를 정하는 시계와 단위
원자시계 · 세슘 원자시계 · 국제단위계 · 초
TAI 를 계산하고 규칙을 적는 기관과 권고
BIPM · 국제도량형총회 · IERS · ITU-R · TF.460-6
TAI 와 나란히 굴러가는 시간 척도
UTC · UT1 · 세계시 · GMT · GPS 시간 · 타임스케일
UTC 를 TAI 에서 떼어 놓는 윤초 보정
윤초 · 윤초 문지르기 · leap-seconds.list · DTAI
TAI 를 기기 사이에 나르는 프로토콜
TAI 를 읽고 맞추는 리눅스 시계와 호출
CLOCK_TAI · CLOCK_REALTIME · CLOCK_MONOTONIC · clock_gettime · adjtimex
TAI 대신 시각과 경과를 재는 수단
다른 이름: International Atomic Time · Temps Atomique International · 국제원자시 · 국제 원자시