사전 시간과 시계
영역

시간과 시계

gabury1

컴퓨터가 시각을 재고 적고 맞추는 일이 모여 있는 자리입니다. 지금이 몇 시인지 묻는 일과 얼마나 흘렀는지 재는 일이 여기서 갈립니다. 잰 값을 남이 읽을 수 있게 적어 두는 규칙도 이 자리에 있습니다. 여러 대의 시계를 서로 맞추는 일도 여기서 마주칩니다.

쉽고 빠른 이해

컴퓨터가 시각을 재고 적고 맞추는 일이 모여 있는 자리입니다. 서버가 지금이 몇 시인지 묻는 일도, 요청이 얼마나 걸렸는지 재는 일도 여기서 갈립니다. 한 문장 정의가 안 서는 까닭은 재는 것이 하나가 아니어서입니다 — 지금 몇 시인지와 얼마나 흘렀는지는 서로 다른 시계가 답합니다.

안에서는 대략 이렇게 갈립니다.

  1. 지금 몇 시인지 재는 시계와 얼마나 흘렀는지 재는 시계
  2. 잰 값을 남에게 적어 넘기는 표기 규칙
  3. 여러 대의 시계를 서로 맞추는 일
  4. 사람이 쓰는 달력과 지역 규칙

여러 대의 시계는 가만두면 어긋나므로, 맞추는 일이 이 목록 전체를 따라다닙니다.

타임아웃처럼 얼마나 흘렀는지만 재는 일은 이 안에 들지만, 사건의 앞뒤만 가리고 시각은 재지도 적지도 않는 방식은 밖입니다.

상세

컴퓨터가 시각을 다룰 때 먼저 만나는 것은 숫자 하나입니다. POSIX(Portable Operating System Interface, 이식 가능 운영체제 인터페이스) 기본 정의는 그 값을 「Epoch(시각을 셀 때 기준으로 삼는 고정된 출발점) 이후 초」라는 이름으로 적습니다. Epoch 이후 흘러간 초의 수에 근사하는 값이라는 정의입니다. 이 값을 흔히 유닉스 시각이라고 부릅니다. 같은 문서가 그 값과 UTC(Coordinated Universal Time, 협정 세계시) 이름 사이의 관계를 식으로 함께 적습니다. 연도가 1970보다 작거나 값이 음수이면 그 관계는 정의되지 않습니다.

그다음이 흥미롭습니다. 실제 하루 시각과 Epoch 이후 초의 현재 값 사이의 관계는 명시되지 않은 채 남습니다. 그 값을 원하는 관계에 맞추려고 어떻게 바꾸는지는 구현이 정합니다. 다만 Epoch 이후 초로 표현할 때 하루하루는 정확히 86400초로 셈해야 한다고 못 박습니다. 즉 규격은 셈하는 규칙만 못 박고, 그 값을 실제 하루 시각에 맞추는 방법은 구현마다 갈립니다.

같은 규격은 시계를 하나로 두지 않습니다. 모든 구현은 CLOCK_REALTIME 을 지원해야 합니다. 시스템의 실제 시각을 재는 시계이고, 여기서 읽고 쓰는 값은 Epoch 이후의 시간량입니다. 이 값을 흔히 벽시계 시각이라고도 부릅니다. 단조 시계 옵션을 지원하는 경우에는 CLOCK_MONOTONIC 도 지원해야 합니다. 이것이 앞서 말한 「얼마나 흘렀는지 재는 시계」입니다. 이 시계가 돌려주는 값은 과거의 명시되지 않은 어떤 시점 이후의 시간량이고, 그 시점은 시스템 시작 이후로는 바뀌지 않습니다. 그래서 이 값은 뒤로 가지 않습니다 — 연이어 불러도 줄어드는 법이 없습니다. 구현은 시계를 더 지원할 수도 있으며, 그런 시계들의 시각 값을 어떻게 해석할지는 명시되어 있지 않습니다.

CLOCK_REALTIME CLOCK_MONOTONIC
무엇을 재나 시스템의 실제 시각 과거의 정해지지 않은 시점 이후 흐른 시간량
값의 원점 Epoch 과거의 명시되지 않은 시점

잰 값을 남에게 넘기려면 적는 규칙이 필요합니다. RFC(Request for Comments, 의견 요청) 3339 는 날짜와 시각 형식이 인터넷에서 많은 혼란과 상호운용성 문제를 일으킨다는 문장으로 시작합니다. 그 문서는 마주친 여러 문제 가운데 상당수를 다루고, 인터넷 프로토콜에서 날짜와 시각을 표현하고 사용할 때의 일관성과 상호운용성을 개선할 권고를 낸다고 적습니다. 그레고리력을 쓴 날짜와 시각 표현에 관한 ISO(International Organization for Standardization, 국제표준화기구) 8601 표준의 인터넷 프로파일을 담습니다. 인터넷 프로토콜에서 날짜와 시각 값이 나타날 수 있는 방식은 많지만, 이 문서는 인터넷 프로토콜 사건의 타임스탬프라는 한 가지 흔한 용법에만 초점을 둔다고 적습니다. 표현되는 모든 시각은 UTC 에 대한 명시된 관계인 오프셋을 가집니다. 기간이나 구간을 기술하는 일은 여기서 다루지 않는다고 못 박습니다.

여러 대의 시계는 가만두면 어긋납니다. 레슬리 램포트는 1978년 논문에서 서로 다른 두 시계가 결코 정확히 같은 속도로 돌지 않으므로 점점 더 멀리 벌어지는 경향이 있다고 적었습니다. 그래서 맞추는 일이 따로 필요해지고, 맞추려면 먼저 시각을 무엇으로 잴지부터 합의해야 합니다. RFC 5905 는 이 합의를 타임스케일이라 부르고, 시각이 정해지지 않은 수의 비트를 가진 단조 증가 이진 계수기의 값으로 표현되는 기준 틀이라고 정의합니다. 쉽게 말해 처음부터 한 방향으로만 늘어나는 숫자 하나로 시각을 나타내는 방식입니다. UTC 타임스케일은 ITU-R(International Telecommunication Union Radiocommunication Sector, 국제전기통신연합 전파통신부문) TF.460 이 정의한다고 적습니다. 시스템 시각은 하드웨어와 운영체제가 유지하는 시스템 시계로 표현됩니다. 이 시스템 시각을 POSIX 쪽에서 읽고 쓰는 이름이 앞서 나온 CLOCK_REALTIME입니다. NTP(Network Time Protocol, 네트워크 시간 프로토콜) 알고리즘의 목표는 UTC 와 시스템 시계 사이의 시각 차이와 주파수 차이를 둘 다 최소로 만드는 것입니다. 그 차이들이 미리 정해 둔 허용 범위인 공칭 허용치 아래로 줄어들면 시스템 시계가 UTC 에 동기화되었다고 말합니다.

그 위에 사람이 쓰는 지역 규칙이 다시 얹힙니다. tz database 문서는 이 데이터베이스가 민간 시각 체계의 역사와 예측된 미래를 기록하려 시도한다고 적습니다. POSIX Epoch 이후에 발생하는 타임스탬프에 대해 시계가 모두 일치하는 타임존으로 세계를 나누어, 타임존 데이터와 서머타임 데이터를 정리합니다. 대부분의 타임존은 주목할 만한 위치에 대응하며 그 위치의 알려진 모든 시계 전환을 기록합니다. 일부 타임존은 대신 고정된 UTC 오프셋에 대응합니다. 여기서 타임존은 흔히 말하는 시간대와 다른 것을 가리킵니다. 각 타임존은 대개 전통적인 시간대보다 작은 지리적 구역에 대응합니다. 한 타임존 안의 시계들은 1970년 이후로 일치하는 반면 전통적인 시간대는 현재의 표준시만 규정하기 때문입니다.

그래서 이 표제어는 한 문장으로 닫히지 않습니다. 지금이 몇 시인지 묻는 일과 얼마나 흘렀는지 재는 일이 서로 다른 시계로 갈립니다. 값을 적는 규칙, 여러 대의 시계를 맞추는 일, 사람이 쓰는 달력과 지역 규칙이 각각 따로 이름을 가집니다. 이 자리에서는 그 이름들을 목록으로 마주칩니다.

경계

경과 시간을 재는 일

타임아웃이나 재시도 간격처럼 얼마나 흘렀는지를 재는 일도 이 구역인가. 맞습니다. POSIX 는 단조 시계의 절대값이 그 원점이 임의이기 때문에 무의미하며, 따라서 그것을 설정할 필요가 없다고 적습니다. 이어서 실시간 응용은 이 시계의 값이 결코 설정되지 않는다는 사실에, 그래서 이 시계로 잰 시간 간격이 clock_settime()(시계 값을 다시 맞추는 호출)의 영향을 받지 않는다는 사실에 의존할 수 있다고 적습니다. 간격을 재는 데 쓸 시계가 이 구역 안에서 따로 정의되고 용도까지 규정된 것입니다.

성능을 재는 계측 시각도 같은 자리에 섭니다. 리눅스 매뉴얼은 이 프로세스가 소비한 CPU(Central Processing Unit, 중앙처리장치) 시간을 재는 시계와 이 스레드가 소비한 CPU 시간을 재는 시계를 각각 따로 둡니다. 둘 다 다른 시계들과 같은 방식의 시계 식별자 — clock_gettime 에 넘겨 어느 시계인지 고르는 이름 — 로 불립니다. 무엇을 재느냐가 다를 뿐 시계를 고르는 자리는 하나입니다.

물리 시각을 쓰지 않는 순서

분산 시스템에서 사건의 앞뒤를 가리는 논리 시계도 이 구역인가. 아닙니다. 램포트는 1978년 논문 서두에서 분산 시스템에서는 두 사건 중 어느 쪽이 먼저 일어났는지 말하는 것이 때때로 불가능하다고 적었습니다. 그래서 「happened before」 관계는 시스템 안 사건들의 부분 순서일 뿐이라고 적습니다. 명세가 물리적 시간으로 되어 있다면 시스템은 실제 시계를 담고 있어야 합니다. 실제 시계를 담고 있더라도 그런 시계들이 완벽히 정확하지 않으며 정밀한 물리 시간을 지키지 못한다는 문제가 여전히 남습니다. 논문은 그래서 물리 시계를 쓰지 않고 그 관계를 정의하겠다고 선언합니다. 시각을 재지도 적지도 맞추지도 않겠다는 선언이므로 그쪽은 이 구역 밖입니다.

다만 같은 논문의 초록이 곧바로 덧붙입니다. 그 알고리즘을 물리 시계를 동기화하는 쪽으로 특수화하고, 시계들이 얼마나 어긋날 수 있는지에 대한 한계를 유도한다는 것입니다. 그 대목에서는 이 구역과 다시 만납니다.

여담

기준 시각이 하필 1970년 첫날인 데에는 사정이 있습니다. 데니스 리치는 1971년 유닉스 매뉴얼에 붙인 해제에서, 그때 시각이 1971년 1월 1일 이후 60분의 1초 단위로 32비트 값으로 측정되었다고 적었습니다. 같은 매뉴얼 time 항목의 BUGS 절에는 연대에 밝은 독자라면 2의 32제곱 60분의 1초가 2.5년쯤밖에 안 된다는 것을 알아차릴 것이라는 말이 적혀 있었습니다. 리치는 그 뒤 새 기준 시각을 선언하는 식으로 한 번 이상 기웠고, 1973년에 단위를 온전한 초로 바꾸면서 1970년 새해를 기준으로 삼았다고 적었습니다. 그것이 「고전적」 유닉스 기준 시각이며, 물론 그 조치는 문제를 2038년으로 미뤘을 뿐이라고 덧붙였습니다.

지구 자전에 맞추려고 넣던 여벌 1초에도 결정이 났습니다. CGPM(Conférence générale des poids et mesures, 국제도량형총회)는 2022년 27차 회의 결의 4호에서, 윤초 도입이 만드는 불연속이 위성항법 시스템과 통신과 에너지 전송 시스템을 포함한 중요한 디지털 기반 시설에 심각한 오작동을 일으킬 위험이 있다는 점을 적었습니다. 그러면서 UT1(Universal Time 1, 지구 자전 각도로 정하는 세계시) 과 UTC 의 차이에 허용되는 최대값을 2035년 또는 그 이전에 늘리기로 결정했습니다. 같은 결의는 국제도량형위원회에, 앞서 UTC 타임스케일을 정의한 그 국제전기통신연합을 비롯해 영향을 받을 수 있는 다른 기관들과 협의하도록, 그리고 UTC 의 연속성을 최소 한 세기 동안 보장할 새 최대값을 제안하고 실행 계획을 준비하도록 요청했습니다. 허용 오차를 그만큼 늘리면 그 사이에는 여벌 초를 넣을 필요가 거의 사라진다는 뜻입니다.

관련 항목

시각을 재는 값과 시계

유닉스 시각 · Epoch · 벽시계 · 단조 시계 · 시스템 시계 · CLOCK_REALTIME · CLOCK_MONOTONIC · CLOCK_TAI · CLOCK_PROCESS_CPUTIME_ID · CLOCK_THREAD_CPUTIME_ID · 동적 시계 · clock_gettime · clock_settime · clock_getres · time_t

시각을 적는 규칙

ISO 8601 · RFC 3339 · 타임스탬프 · UTC 오프셋 · 그레고리력 · 타임스케일

시계를 서로 맞추는 프로토콜과 문서

NTP · RFC 5905 · PTP(Precision Time Protocol, 정밀 시각 프로토콜) · 시계 동기화 · 시계 드리프트

사람이 쓰는 달력과 지역 규칙

UTC · TAI(International Atomic Time, 국제원자시) · UT1 · 윤초 · 타임존 · tz database · 서머타임 · 민간 시각 · ITU-R TF.460

물리 시각 없이 순서를 정하는 개념

happened-before 관계 · 램포트 시계 · 부분 순서

이 구역에서 자주 나는 오류와 장애

2038 문제 · EOVERFLOW · 타임아웃

다른 이름: 시간 · 시계 · time and clocks · timekeeping · 시각 처리