나무모에 미러 (일반/어두운 화면)
최근 수정 시각 : 2020-03-02 21:25:45

2038년 문제

1. 개요2. 문제점3. 해결책4. 기타5. 관련 문서

1. 개요

서기 2038년 1월 19일 3시 14분 7초
2038년 문제까지
D[dday(2038-01-19)]

파일:external/upload.wikimedia.org/Year_2038_problem.gif
유닉스 시간에 32비트 정수형을 쓰는 모든 컴퓨터의 시계가 UTC 0 기준으로 2038년 1월 19일 3시 14분 7초[1](대한민국 표준시 UTC+9 기준으로 2038년 1월 19일 12시 14분 7초)가 지나는 순간 음수값이 적용돼 1901년 12월 13일 20시 45분 52초나, 자동으로 오류를 감지하고 초기값인 0, 즉 1970년 1월 1일 0시 0분 0초로 돌아가게 되는 버그를 칭한다. 영어론 Year 2038 problem, Unix Millennium bug 등으로 표기한다.

원인은 프로그래머라면 알아야만 하는 오버플로 현상 때문이다.


안드로이드 스마트폰을 가지고 있다면 이 버그를 미리 체험해볼 수 있다. 단, 안드로이드 7.1.2 이하의 기기에서 재현이 되며 안드로이드 8.0 이후부터는 버그 재현이 불가능하다. 만약 안드로이드 7.1.2 버전 이하가 탑재된 기기의 경우 구글 캘린더로 일정을 2038년 1월 19일에 추가해 주면 추가된 날짜가 1970년으로 변한다.

단, 요즘은 7.1 이하의 일부 기기에서도 정상적으로 날짜 추가가 되는걸로 보아, 안드로이드 운영체제 자체의 문제가 아닌 구글 캘린더 자체의 문제로 판단되며, 현재는 구글이 캘린더 앱 자체를 수정한 것으로 보인다. 화웨이와 샤오미의 캘린더는 일정을 2037년 12월 31일까지만 설정할 수 있으며, Samsung Experience 8.1 이상 버전의 캘린더와 LG의 캘린더는 2036년 12월 31일까지 설정이 가능하다.

2. 문제점

컴퓨터에서 사람들이 쓰는 태양력을 계산하는 방법은 여러 가지가 있는데, 가장 많이 쓰는 방법이 유닉스 운영체제에서 채용한 유닉스 시간이다. 여기서 쓴 방식이 32비트 크기의 정수형으로 시간을 나타내는 변수를 선언하고 초당 1씩 증가하도록 처리했다. 이로 인해 값이 32비트 크기의 표현한계인 2,147,483,647까지 증가하면 더 이상 증가할 수 없게 된다. 컴퓨터에서 이런 오버플로가 발생할 경우 해당범위의 최소값으로 돌아가는 식으로 처리된다. 가령 값(x)에 할당된 공간이 1바이트고 범위가 0≤x≤255 일 때 255다음의 수는 256이 아니라 0이 되고 플래그가 세트되는 식이다.

이로 인해 2038년 1월 19일 3시 14분 7초가 지나면 유닉스 시간이 맨 처음으로 돌아가게 되고, 그로 인해 컴퓨터의 각종 연산에 문제를 줄 수 있다. 과장일 수 있지만 Y2K 문제에서 언급된 문제들이 발생할 수 있다. Y2K는 사람이 헷갈리는 거지만 이건 기계가 헷갈리는 거다.

시간을 나타내는 변수를 32비트 크기가 아니라 64비트 크기의 정수형으로 바꾸면 되지만 말처럼 쉬운 게 아니란 점이 골칫거리. 시간을 표현하는 변수의 형식을 그냥 막 바꿔버리면 기존에 구현한 알고리즘들도 꼬이고 각종 호환성 문제가 터질 수 있기 때문.

정수형을 부호 없는 정수형(Unsigned Integer)으로 바꾸면 2106년까지 늦출 수 있다. 음수 부분 없이 0부터 시작해 4,294,967,295까지 증가하기 때문. 물론 이렇게 하면 음수부분의 시간이 없어져서 Unix Time 0에 해당하는 1970-01-01 이전의 시간을 셀 수 없으므로 이 역시 문제가 있다.

만약 16비트를 쓴다면 4시간 33분 3초, 8비트라면 2분 7초밖에 못 셀 것이다. 물론 주요 시스템 중 8비트나 16비트를 쓰는 것은 거의 없고, 그나마 이쪽이 주력인 MCU임베디드 시스템이 있긴 하나 8비트 16비트 급에선 외부 RTC를 두는 게 일반적이므로 문제 없다.

3. 해결책

시간을 저장할 때 64비트 정수형을 쓰도록 OS와 프로그램을 고치는 건 누구나 할 수 있는 생각이지만, 그러려면 기존에 나온 프로그램이나 데이터를 전부 갈아엎어야 한다. 32비트 OS가 주류였던 시기에는 누구나 시간을 저장할 때 32비트를 사용했기 때문에 실행 파일, 라이브러리, OS API/ABI는 시간을 다룰 때 32비트 정수형이 올 것을 가정하고 만들어져 있다. 이런 상황에서 시간 함수 및 자료형만 64비트 정수형으로 바뀌면 기존의 실행 파일과 라이브러리는 OS에서 64비트 정수형으로 시간을 처리한다는 걸 모르기 때문에, 수정한 OS에 맞춰서 다시 컴파일하지 않으면 의도한 대로 작동하지 않는다. 한 예로 OpenBSD 5.5는 32비트 플랫폼에서도 64비트로 시간 값을 처리해서 2038년 문제에서 벗어났지만, 바로 이 문제 때문에 ABI가 바뀌어서 OpenBSD 5.4의 실행 파일과 라이브러리를 실행시킬 수 없다. 게다가 일부 네트워크 프로토콜, 파일 형식은 내부적으로 32비트로 시간을 저장하는데 이걸 단시일 내에 모두 64비트로 전환할 수 있다는 보장이 없다. 게다가, 9x 계열의 윈도우지금까지도 계속해서 쓸 수밖에 없는 상황에 놓여있는 사람들 입장에선(...)[2]

컴퓨터 업계쪽 사람들은 의외로 느긋하게 생각하고 있는데, 지금부터 프로그램을 짤 때 유닉스 시간에 64비트 정수형을 쓰면 되기 때문. 유닉스 시간을 설계하던 당시에도 이 문제를 알고 있었지만 "후손들이 그 전에 알아서 잘 해결할 거야"였다나 뭐라나... 하지만 이미 현실에선 문제가 발생하고 있다. 바로 미래를 다루는 구형 시스템들. 예를 들어 2038년 문제를 보정하지 않은 구형 시스템으로 연금보험을 처리하는 경우, 1977년생이 만 61세부터 연금을 탈 수 있다고 가정하면 바로 2038년에 첫 연금을 수령하게 된다. 수령 예상액 등을 미리 계산해보면 이 사람은 태어나기도 전인 1970년에 연금을 수령하는 꼴이 된다. 물론 국내 시스템은 2038년 문제가 없다고 봐도 된다. 중국에선 국내 소프트웨어를 이용해 시스템을 구축하고 상용화하기 전에 테스트를 통해 2038년 문제를 감지하고 수정 버전을 요청한 적이 있다.

64비트 정수형도 수 표시에 한계가 있으나 오류가 발생하는 시점은 서기 2922억 7702만 6596년[3]이다. 정말 머나먼 미래의 일인데, 사실 이 정도의 시간은 중형 적색 왜성의 수명과 맞먹는 수준이고 태양도 활동을 멈춘 지 오래됐을 것이기 때문에 태양계는 그냥 죽은 행성계가 된다. 혹시나 유지되고 살아있다고 쳐도 역시나 128비트나 그 이상으로 진작에 시스템을 발전시켜서 쓰고 있을 것이다.

아래는 마야 달력2012년과 유닉스 시간을 빗댄 만화이다.

파일:2012Calendarko.png
위 상황이 닥치면 128비트 정수형으로 넘어가면 될 것인데, 128비트 정수형으로는 우주 멸망을 논할 수 있을 정도의 시간[4]이 나온다.

4. 기타

5. 관련 문서



[1] 초기값인 1970년 1월 1일 0시 0분 기준으로 68년 18일 3시간 14분 7초.[2] 오랜 시간이 지난 2009년에도 아프리카에서는 486에 담겨 현역으로 돌아가고 있다. 사실 그런 동네는 컴퓨터 사양도 486이 아직까지도 현역인 경우도 많아 상위 OS를 설치하기가 어려운 정도가 아닌 사실상 불가능 하거니와 이젠 골동품이 된 CD들이 어찌어찌 이런 곳까지 기부되어 현역으로 잘 쓰이고 있다. 인터넷도 없고(물론 전화선이 연결되어있다면 PC통신이 서비스가 끝날때까진 네트워킹을 할수있을듯..) 문서 작업 위주로 일하는 수준이니 지원하든 말든 상관도 없으니 아직은 쓸만한 모양. 동영상 재생 등 기능이 좀 더 늘어난 타자기의 역할인 셈. 하지만, 이 날짜버그 앞에서는 9x 계열밖에 설치할 수가 없는 컴퓨터를 사용하기가 불가능 해지기 때문에 결국엔 하드웨어부터 근본적으로 갈아엎어야 하는 문제가 다가오고 있다.[3] unsigned 타입을 쓴다면 서기 5845억 5405만 1223년에 문제가 발생한다.[4] 2127-1초, 약 5,395,141,535,403,007,094,485,264,577,495년. 부호 없는 정수형이라면 2128-1초, 약 1.08×1031년.[5] 세금이 약 21억이 넘어가도록 세금 징수를 하면 32비트 시스템의 한계로 오버플로가 일어나 -21억이 되는 버그가 악명 높았다. 현재는 수정이 된 상태.