2015년 6월 27일 토요일

국제화된 소프트웨어에서 날짜와 시간을 다루는 방법 (18)

개발자들이 소프트웨어를 개발하면서 가끔 하는 실수 중 하나가 현지 시간을 저장했다가 나중에 소프트웨어가 확장되면서 꼬이는 것이다. 보통의 소프트웨어라면 시간에 그렇게 민감하지 않다. 하지만 일정관리, 항공권 예약, 배송 시스템 등 시간에 민감한 소프트웨어들이 있다. 이 외에도 시간을 신경 써서 다뤄야 하는 소프트웨어가 많다. 이런 소프트웨어에서 시간의 기록과 처리를 현지 시간을 기준으로 처리를 하다가는 문제가 발생하고 꼬이게 된다. 



여기서 현지 시간이란 날짜와 시각을 모두 의미한다. 또 현지 시각은 그레고리력을 기준으로 하는 날짜 일 수도 있고 해당 나라에서 사용하는 독특한 달력을 기준으로 한 날짜일 수도 있다. 개인 혼자서 쓰는 시스템, 예를 들어 일기장과 같은 소프트웨어라면 문제가 안되지만 전세계 여러 사용자가 공유하는 시스템이라면 시간의 표시가 지역마다 다르게 표시되어야 한다. 또한 혼자 사용하더라도 일정 관리 소프트웨어 같은 경우에는 지역을 옮겨 다닐 때마다 현지 시간에 맞게 보정해서 보여줘야 한다.

그래서 시스템에 시간을 저장할 때는 절대 시간을 기록해야 한다. 소프트웨어에서 절대 시간이란 유닉스 시간을 말한다. POSIX 시간이라고도 부른다. 유닉스 시간은 영국 그리니치 천문대에서 그레고리력으로1970년 1월 1일 0시 0분 0초에 0으로 시작된 시간 표시로 1초에 1씩 증가한다. 예를 들어 한국에서 2015년6월5일 오전2시16분37초의 유닉스 시간은 1433524597이다. 거의 모든 OS와 Database에서는 유닉스 시간을 기준으로 시간을 처리한다. 그리고 화면에 출력할 때 타임존을 고려하여 변환하여 출력한다. 

따라서 시간을 기록할 때는 유닉스 시간을 얻어와서 DB나 파일에 저장을 하고 입출력 시 사용자의 입맛에 맞게 변환을 해야 한다. 출력 시에는 예를 들어 아래와 같은 변환 과정을 거쳐야 하고, 입력 시는 반대 과정을 거친다.


(유닉스 시간 10억초 달성 기념)

1. 유닉스 시간 : 1433524597
2. 협정 세계시 : 2015-06-05 17:16:37 UTC
3. 달력 변환 : 2015-06-05 17:16:37 UTC
4. 한국의 타임존 : 2015-06-06 02:16:37+09:00(or PDT)
5. 한국의 시간포맷 : 2015년 6월 6일,오전 2시 16분 37초

1~4번까지는 소프트웨어 내부에서 일어나는 변환 과정이고 5번이 사용자에게 보여지게 된다. 또한 형식은 언어(로케일)별로 다르다.

달력 변환에서 그레고리력일 경우에는 변환할 필요가 없지만 사용자가 그레고리력이 아닌 다른 달력을 사용하는 경우에는 변환이 필요하다. 예를 들어 일본 일왕의 연호나 불기, 음력을 사용한다면 변환이 필요하다.

개발 환경 즉, 개발 프레임워크나 라이브러리에서 제공하는 시간 함수들은 여러가지가 있고 위 변환 과정을 거의 모두 지원하는 것도 있고 일부만 지원해서 개발자가 추가로 개발을 해야 하는 경우도 있다. 대부분은 유닉스 시간과 타임존 변환은 제공하지만 달력 변환을 지원하는 경우는 거의 없고 로케일별 시간 포맷 제공도 프레임워크마다 제각각이다. 개발자가 상당한 세심한 신경을 써야 하는 이유다.


(타임존 지도)

그 외에 일정관리나 항공권예약 시스템에서는 시간과 관련해서 좀더 많은 정보를 보관해야 한다. 매 시간마다 위치나 타임존을 기록해서 하나의 시간에 대해서도 현지 시간과 현재 사용자가 있는 위치의 시간을 동시에 보여주기도 한다. 국제화가 잘된 소프트웨어에서는 시간 처리에 여러 가지 신경을 써야 한다.

그럼 국가별, 로케일별로 시간 표시 형식은 어떨까? 우선 로케일별 국가 이름을 보자

ar_SA : 사우디아라비아
de_DE : 독일
en_US : 미국
es_ES : 스페인
fr_FR : 프랑스
id_ID : 인도네시아
it_IT : 이탈리아
ja_JP : 일본
ko_KR : 대한민국
pl_PL : 폴란드
pt_PT : 포르투갈
ru_RU : 러시아
vi_VN : 베트남
zh_CN : 중국
zh_TW : 타이완
de_LI : 리히텐슈타인
th_TH : 태국

로케일(국가)별 시간 형식의 예는 다음과 같다. 

ar_SA : " ٣:٠٢:٢٧ م"
de_DE : "15:02:27"
en_US : "3:02:27 PM"
es_ES : "15:02:27"
fr_FR : "15:02:27"
id_ID : "15.02.27"
it_IT : "15:02:27"
ja_JP : "15時02分27秒"
ko_KR : "오후 3시 2분 27초"
pl_PL : "15:02:27"
pt_PT : "15:02:27"
ru_RU : "15:02:27"
vi_VN : "15:02:27"
zh_CN : "下午3时02分27秒"
zh_TW : "下午3時02分27秒"
de_LI : "15:02:27 "
th_TH : "15 นาฬิกา 2 นาที 27 วินาที "

위 시간의 포맷은 특정 Framework를 사용한 한 예다. 

물론 모든 소프트웨어가 위에서 언급한 타임존, 특수한 달력, 지역에 맞는 형식을 모두 지원하는 것은 아니다. 또한 우리가 만드는 소프트웨어도 모두 지원해야 하는 것은 아니다. 소프트웨어 성격과 판매 지역, 전력에 따라서 지원해야 하는 범위를 개발 초기에 결정해야 한다. 그래야 소프트웨어 국제화가 성공적으로 진행될 수 있다.

댓글 5개:

  1. 좋은 내용 감사합니다.
    국제화와 지역화에 대한 예시를 찾다가 좋은글 보고 개인 블로그에 인용을 하려고합니다.
    http://dalmyo0328.blog.me/220780459797
    혹시나 문제된다면 해당내용 삭제하도록 하겠습니다.

    답글삭제
    답글
    1. 인용은 출처만 표시하면 문제없습니다.
      국제화에 대해서 궁금한 것이 있으면 문의하세요.

      삭제
    2. 엇, 감사합니다. 제가 위의 내용을 인용하면서 한줄로 정리한 내용이
      POSIX 시간으로 저장하는것이 I18n, 타임존을 고려하여 변환해서 출력하는것이 L10n 에 해당한다.
      그리고 이렇게 만들어진 시스템이 G11n 되어진 것이라고 볼수있다.

      라고 설명했는데 혹시 틀린부분이나 애매한부분이 있나요??

      삭제
    3. i18n과 L10n은 기술적인 용어입니다. 하지만 G11n은 비즈니스적인 용어입니다. 따라서 설명한 내용이 틀린 말이 아닙니다.
      저는 보통 G11n이라는 용어는 사용하지 않습니다.

      삭제
    4. 아 그렇군요 감사합니다 ㅎㅎ

      삭제