2015년 6월 27일 토요일

01/02/03는 며칠일까? (12)

오늘은 날짜 표기에 대해서 다뤄보자. 날짜 표기 형식도 나라마다 다르다. 그런데 많은 소프트웨어들이 국가별, 로케일별로 다른 날짜 표기 형식을 제대로 처리하지 않아서 특정 국가에서 불만이 커지거나 잘못 사용되는 사례도 빈번하게 발생한다. 심지어는 날짜 표기를 제대로 고려한 소프트웨어에서도 입력의 복잡함과 모호함으로 문제가 발생하곤 한다. 국제화된 소프트웨어를 개발하는 개발자라면 날짜 형식을 다루는 지식과 노하우는 어느 정도 보유해야 한다.







우선 01/02/03은 무엇으로 보이는가? 물론 이런 날짜 형식은 애초에 모호함 때문에 잘 사용하지 않는다. 하지만 꼭 날짜를 이렇게 표현한다면 어떻게 보일까? 100%는 아니지만 미국, 호주, 한국 사람들은 각각 다른 날짜로 읽는 것이 일반적이다.

미국 사람들은 2003년 1월 2일로 볼 것이다. 물론 미국에는 워낙 많은 민족이 있어서 다르게 볼 수도 있지만 대체로 그렇다는 것이다. 호주 사람들은 2003년 2월 1일로 볼 것이다. 하지만 알다시피 한국사람들은2001년 2월 3일로 볼 것이다. 2002년으로 읽는 나라가 없다는 것은 그나마 다행이다.

추가로 그레고리력을 사용하느냐 다른 달력을 사용하느냐에 따라 다른 부분도 있다. 참고로 북한은 주체연호를 사용하고 일본과 태국도 다른 달력을 혼용한다. 이 주제는 따로 다루겠다.




그럼 국가별, 로케일별로 날짜 형식은 어떻게 되면 소프트웨어를 개발할 때 이를 어떻게 다뤄야 하는지 알아보자.

우리가 날짜를 표시하는 방법은 수십 가지가 넘는다. 연도만해도 두자리 또는 네자리로 사용하고 요일도 “월” 또는 “월요일”이라고 쓴다. 영어에서는 월을 표기할 때 “Aug” 또는 “August”로 표기를 한다. 시간까지 같이 표시할지 여부와 시간의 표시 형식까지 합하면 크게 나눠도 열 가지는 넘는다. 소프트웨어를 설계할 때는 소프트웨어의 성격에 따라서지원해야 할 날짜 형식을 표준화해야 한다. 개발자들이 멋대로 여러 가지 날짜 형식을 사용하게 되면 관리가 제대로 안된다. 나중에 버그가 발견되면 수많은 소스코드를 고쳐야 한다. 표준화된 날짜 함수를 제공해서 개발자에게 제공해야 하고 개발자들은 정해진 날짜 함수만 사용해야 한다.

날짜 함수는 입력, 출력 두가지 형태의 함수를 제공해야 한다. 입력은 문자열을 날짜 데이터로 변환하는 것이고 출력은 날짜 데이터를 문자열로 변환하는 함수다. 예를 들어 StrToDate(), DateToStr() 이런 함수를 만들면 된다. 날짜의 형식은 가장 먼저 긴 형식과 짧은 형식을 제공한다. 이는 소프트웨어마다 다르니 개발자가 정해야 한다.



국가별 로케일별로 서로 다른 날짜 형식만 살펴보도록 하자. 먼저 긴 날짜 형식은 어떻게 될까? 우선 로케일별 국가 이름을 소개한다.

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 : "Montag, 18. Mai 2015"
en_US : "Monday, May 18, 2015"
es_ES : "lunes 18 de mayo de 2015"
fr_FR : "lundi 18 mai 2015"
id_ID : "Senin, 18 Mei 2015"
it_IT : "lunedì 18 maggio 2015"
ja_JP : "2015年5月18日月曜日"
ko_KR : "2015년 5월 18일 월요일"
pl_PL : "poniedziałek, 18 maja 2015"
pt_PT : "Segunda-feira, 18 de Maio de 2015"
ru_RU : "понедельник, 18 мая 2015 г."
vi_VN : "Thứ hai, ngày 18 tháng năm năm 2015"
zh_CN : "2015年5月18日星期一"
zh_TW : "2015年5月18日星期一"
de_LI : "Montag, 18. Mai 2015"
th_TH : "วันจันทร์ที่ 18 พฤษภาคม 2015"

그럼 짧은 날짜 형식은 국가별, 로케일별로 어떻게 출력될까? 

ar_SA : "١٨‏/٥‏/٢٠١٥"
de_DE : "18.05.15"
en_US : "5/18/15"
es_ES : "18/05/15"
fr_FR : "18/05/15"
id_ID : "18/05/15"
it_IT : "18/05/15"
ja_JP : "2015/05/18"
ko_KR : "15. 5. 18."
pl_PL : "18.05.2015"
pt_PT : "18/05/15"
ru_RU : "18.05.15"
vi_VN : "18/05/2015"
zh_CN : "15-5-18"
zh_TW : "15/5/18"
de_LI : "18.05.15"
th_TH : "18/5/2015"

물론 위 날짜 형식 모두다 정답이 아닐 수도 있다. 필자가 특정 Framework을 사용해서 출력된 결과를 표시한 것뿐이다. 해당 Framework의 국제화 개발팀에서 적절하지 않는 날짜 형식을 구현해 놓았을 수도 있다. 특히, 한국의 짧은 날짜 형식은 마음에 들지 않는다. 하지만 일단 Framework이나 시스템에서 제공하는 날짜 형식을 믿고 개발해야 한다. 개발자가 국가별, 로케일별 날짜 포맷을 직접 연구할 수는 없다. 추후 버그가 보고 될 경우 수정은 할 수 있겠다.

필자가 테스트를 해본 결과 같은 C언어를 쓴다고 하더라도 C언어에서 제공하는 strftime()함수만 하더라도 Microsoft C와 gcc가 제공하는 날짜 형식이 다르다. 이는 OS나 개발툴 개발사마다 날짜 형식을 미묘하게 다르게 제공하고 있다는 것을 알아야 한다. 크로스 플랫폼 개발자는 더욱 유념해서 개발을 해야 한다.

위에서 예로든 두가지 형식 외에도 여러 가지 중간 길이의 날짜 형식이 필요하다. 이런 형식을 제공하기 위해서는 개발자가 날짜 형식에 대해서 조금 더 연구를 해야 한다. 기본 날짜 함수 제공은 쉽지만 여러 가지 형식을 제대로 제공하려면 점점 어려워진다. 소프트웨어 성격에 알맞게 제공할 날짜 포맷을 연구해서 국제화 라이브러리에 추가를 해야 한다.

다음에는 날짜를 다루는 방법을 조금 더 보겠다.

댓글 없음:

댓글 쓰기