NAME

tzfile - 시간대 정보

DESCRIPTION

tzset(3)에서 쓰는 시간대 정보 파일들은 보통 /usr/share/zoneinfo 같은 이름의 디렉터리 아래에 있다. 이 파일들은 인터넷 RFC 8536에서 설명하는 형식을 쓴다. 각 파일은 8비트 바이트들의 열이다. 파일 안에선 네트워크 순서(빅 엔디언, 상위 바이트 우선)의 한 개 이상 바이트의 열로 이진 정수를 표현하는데, 모든 비트를 사용하며, 부호 있는 이진 정수는 2의 보수로 표현한다. 불리언은 0(거짓) 아니면 1(참)인 한 바이트짜리 이진 정수로 표현한다. 그 형식은 다음 필드들을 담은 44바이트 헤더로 시작한다.

위 헤더 다음으로 다음 필드들이 오는데, 헤더 내용에 따라 길이가 정해진다.

표준/벽시계 및 UT/지역 표시자는 TZif 파일의 전이 시간을 규칙이 결여된 POSIX 방식 TZ 문자열을 통해 지정된 다른 시간대에 적합한 전이들로 변환하기 위해 설계되었다. 예를 들어 TZ="EET-2EEST"이고 TZif 파일 "EET-2EEST"가 없는 경우에 미리 정해진 "posixrules"라는 TZif 파일에서 전이 시간을 가져다 조정한다는 것이었는데, 그 파일은 이 용도로만 존재하며 UT 오프셋이 다른 파일인 "Europe/Brussels" 파일의 사본이다. POSIX에서 이런 구식 변환 동작에 대해 명세하고 있지 않으며, 설치본마다 기본 규칙들이 다를 수 있다. 그리고 2037년 후 타임스탬프에 대해 이 기능을 지원하는 알려진 구현체가 전혀 없으므로 (가령) 그리스 시간을 원하는 사용자라면 폭넓은 하위 호환성이 중요하면 TZ="Europe/Athens"를 지정하면 되고, POSIX 준수가 필수고 다른 타임스탬프들을 정확하게 다룰 필요가 없으면 TZ="EET-2EEST,M3.5.0/3,M10.5.0/4"로 대처하면 된다.

tzh_timecnt가 0이거나 시간 인자가 파일에 기록돼 있는 첫 번째 전이 시간보다 앞인 경우에 localtime(3) 함수는 보통 파일의 첫 번째 ttinfo 구조체를 사용한다.

버전 2 형식

버전 2 형식의 시간대 파일에서는 위의 헤더 및 데이터 다음에 두 번째 헤더 및 데이터가 오는데, 전이 시간과 윤초 시간에 각각 8바이트를 쓴다는 점을 빼곤 동일한 형식이다. (윤초 개수는 여전히 4바이트다.) 두 번째 헤더 및 데이터 다음에는 개행으로 감싼 POSIX TZ 환경 변수 스타일 문자열이 오는데, 파일에 저장된 마지막 전이 시간 후의 순간들을 (파일에 전이가 없다면 모든 순간들을) 처리할 때 쓰기 위한 것이다. 그 순간들에 대한 POSIX 표현이 존재하지 않는 경우에는 POSIX 스타일 TZ 문자열이 비어 있다. (즉 개행 사이에 아무것도 없다.) POSIX 스타일 TZ 문자열이 비어 있지 않은 경우에는 그 여덟 바이트 데이터로 된 전이 시간이 있다면 마지막 전이 시간 후의 지역 시간 종류와 그 TZ 문자열이 부합해야 한다. 예를 들어 그 문자열이 "WET0WEST,M3.5.0,M10.5.0/3"라고 하고, 마지막 전이 시간이 7월에 있다면 그 전이의 지역 시간 종류에서 UT보다 한 시간 동쪽이고 "WEST"로 줄여 쓰는 일광 절약 시간을 명시해야 한다. 또한 전이가 최소 한 번은 있을 때 무한대 과거부터 가장 이른 전이 시간 전까지의 기간에는 시간 종류 0번이 연계된다.

버전 3 형식

버전 3 형식의 시간대 파일에서는 newtzset(3)에서 기술하는 POSIX TZ 형식에 대한 두 가지 소규모 확장을 그 POSIX TZ 스타일 문자열에서 쓸 수 있다. 첫째로, 전이 시간의 시간 부분이 POSIX에서 요구하는 0에서 24까지의 부호 없는 값이 아니라 -167에서 167까지 범위의 부호 있는 값일 수 있다. 둘째로, DST가 1월 1일 00:00에 시작해서 12월 31일 24:00에 일광 절약 시간과 표준시 차이를 더한 때에 끝나는 경우에는 DST가 연중 내내 효력이 있다.

연동 관련 사항

향후 형식이 바뀌면서 더 많은 데이터가 덧붙을 수 있다.

버전 1 파일은 구식 형식이며 피하는 게 좋다. 2038년 후의 전이 시간을 지원하지 않는다. 버전 1만 지원하는 읽기 프로그램에선 계산한 버전 1 데이터 블록 다음으로 이어지는 데이터를 모두 무시해야 한다.

쓰기 프로그램에선 전이 시간들을 정확히 명세하기 위해 TZ 문자열 확장이 필요하다면 버전 3 파일을 생성하는 게 좋다. 그게 아니라면 버전 2 파일을 생성하는 게 좋다.

버전 1 헤더와 데이터 블록에서 규정하는 시간 변화들의 열이 버전 2+ 헤더와 데이터 블록, 그리고 마지막 부분에서 규정하는 시간 변화들의 연속 부분열이게 하는 게 좋다. 이렇게 하면 그 연속 부분열 내의 타임스탬프들에 대해 구식 버전 1 읽기 프로그램과 최신 읽기 프로그램의 의견이 일치할 수 있게 된다. 또한 구식 읽기 프로그램을 지원하지 않으려는 쓰기 프로그램에서 버전 1 데이터 블록의 tzh_timecnt에 0을 써서 공간을 절약할 수 있게 된다.

시간대 명칭을 최소 세(3) 글자에 여섯(6) 글자를 넘지 않는 ASCII 문자로 하고, 영자와 숫자, "-", "+"만 쓰는 게 좋다. 시간대 축약명에 대한 POSIX 요구 사항과의 호환성을 위한 것이다.

버전 2 또는 3인 파일을 읽을 때 읽기 프로그램은 건너뛰는 목적 말고는 버전 1 헤더와 데이터 블록 내용을 무시하는 게 좋다.

읽기 프로그램에서 파일 유효성을 검사할 때 헤더와 데이터 블록들의 총 길이를 계산해서 그게 모두 실제 파일 크기 안에 들어가는지 확인해 보는 게 좋다.

흔한 연동 이슈

이 절에선 TZif 파일을 읽고 쓸 때의 흔한 문제들을 설명한다. 이 문제들 대부분은 구식 읽기 프로그램에서 이용할 TZif 파일을 생성할 때의 문제이다. 이 절의 목표는 이렇다.

새로운 TZif 형식들이 정의되었을 때의 설계 목표 하나는 읽기 프로그램의 설계보다 파일이 이후 TZif 버전이더라도 읽기 프로그램이 TZif 파일을 성공적으로 쓸 수 있게 하는 것이었다. 완벽한 호환성을 달성할 수 없는 경우에는 문제들을 잘 안 쓰는 타임스탬프들로 제한하려는, 그리고 쓰기 프로그램에서의 간단하고 불완전한 해결책들을 통해 구식 버전 읽기 프로그램에서도 이용 가능한 새 버전 데이터를 생성할 수 있게 하려는 시도가 이뤄졌다. 그런 호환성 문제들과 해결책, 그리고 읽기 프로그램들에 흔한 여타 버그들을 이 절에 기록해 둔다.

다음은 몇 가지 TZif 관련 호환성 문제들이다.

연동 문제 중 일부는 읽기 프로그램의 버그이며, 다음은 읽기 프로그램 개발자를 위한 주의 사항이라 할 수 있다.

SEE ALSO

time(2), localtime(3), tzset(3), tzselect(8), zdump(8), zic(8).

Olson A, Eggert P, Murchison K. The Time Zone Information Format (TZif). 2019 Feb. Internet RFC 8536 https://www.rfc-editor.org/info/rfc8536 doi:10.17487/RFC8536 https://doi.org/10.17487/RFC8536.


2020-04-27