소프트웨어의 국제화 (i18n)

이은찬
PLUS TV
Published in
16 min readAug 19, 2019

소프트웨어 제품의 글로벌 진출을 준비하며 해야하는 작업에 대해 공유드리려 합니다. (i18n)
단순히 번역 원고를 받아 글자 바꾸는 것보다 신경 써야 할 부분이 많습니다.

그 부분들을 통틀어 국제화(Internationalization; i18n) 라고 합니다.

i18n ?
i18n은 어떤 프레임워크가 아니고 i와 n 사이에 18개의 알파벳이라는 뜻입니다. http://www.i18nguy.com/origini18n.html

글자 번역 외에 국제화에 필요한 작업에는 무엇이 더 있을까요?

  • 언어, 지역 별 번역
  • OS/플랫폼 인코딩
  • 문자열 치환 방법
  • 국제화 UI (문자열 크기 변화, 폰트, 아이콘 등)
  • 쓰기 방향의 차이 (LTR, RTL)
  • 숫자, 공백, 화폐, 날짜, 주소, 측정 단위 등 표기
  • 타임존, 썸머타임 등 시각
  • 문자열 정렬 방법

하나씩 알아보도록 하겠습니다.

언어, 지역 별 번역

국제화의 가장 큰 의미이자 시작과 끝인 항목입니다.
소프트웨어상에서 전달하는 문자열들을 언어와 지역별로 번역해야 합니다.
아시다시피 같은 언어도 지역별로 조금씩 달라질 수 있습니다.
예로 미국과 중국이 있습니다.

color/colour
humor/humour
realize/realise
center/centre
I learned / I learnt

위 예시는 미국과 영국 영어의 차이입니다.
보시다시피 같은 언어인데도 지역별로 달라질 수 있습니다.

소개해 드릴 BCP 47은 언어/지역을 위한 표준 표현 태그입니다.
en-US/en-UK 등으로 위와 같은 상황을 구분해 낼 수 있습니다.

BCP? BCP 47?
Best Current Practice; IETF(Internet Engineering Task Force; 국제 인터넷 기술 위원회)에서 발의된 RFC(Request For Comments; 표준 발의 전 리뷰 상태의 문서)를 좀 더 실용적인(de facto) 단계로서 게재해놓은 문서를 뜻합니다. 이 중 BCP 47은 Globalization에 관련된 문서입니다. 이 위키페이지에서 더 많은 BCP를 확인할 수 있습니다.

위는 BCP 47에서 말하는 langtag 의 정의입니다.
language는 필수 값이며 이외에는 모두 옵션입니다.
각각에 대한 설명은 아래와 같습니다.

  • language : ISO(International Organization for Standardization; 국제 표준화 기구)에서 정의한 ISO 639-1와 ISO 639–2를 따르는 언어 코드 (예: en, ko, ja, zh 등)
  • script : ISO 15924 정의를 따르는 글자 표기법 관련 코드 (예: sr-Latn; Latin으로 쓰인 Serbian어)
  • region : ISO 3166 정의를 따르는 지역 구분 코드 (예: sr-Latn-RS; Latin으로 쓰이고 RS(Serbia) 지역에서 쓰이는 Serbian어)
  • variant : 다른 코드들로 표현되지 않는 추가적인 방언등을 다루기 위한 서브태그. 하나 이상 올 수 있으며 IANA(Internet Assigned Numbers Authority)에 등록되어야 함. 알파벳 5자, 숫자 4자 등의 규칙이 있음. section 2.2.5 참조 (예: de-CH-1996; 스위스에서 쓰이는 독일어, 96년에 바뀐 철자 교정법이 적용됨)
  • extensions : 언어 자체에 속하진 않지만 어플리케이션 표현시 필요한 포맷에 관련된 추가 서브태그. section 2.2.6 참조RFC6067 참조. CLDR(Unicdoe Common Locale Data Repository) 등에서 정의한 것들이 예.
  • privateuse : 공식적이 아닌 소규모로 합의된 표현 방식. (예: 특정 중세시대의 Greek 문자를 표현한다던지 등이 예시로 문서에 언급되어 있음. 항상 x 로 시작함.)

사용할 수 있는 language tag는 이 곳에서 확인하실 수 있습니다.

OS/플랫폼 인코딩

ISO 8859–1, Windows 1252 그리고 MacRoman 등은 영어와 서유럽권 언어를 위한 정의입니다. 이들은 1바이트 만으로 모든 글자를 표현하기에 충분했습니다. 그러나 아시아권 언어(한국어와 중국어 등)을 위해서 2바이트가 필요했고 이 필요가 발전되어 Unicode를 탄생시켰습니다. 2019년 5월 발표된 Unicode는 12.1 버전으로 137,994개의 글자와 이모지 등을 담고 있습니다. ISO 10646 표준을 따르고 있습니다.

Unicode는 하나의 표준이고 이제 실제로 인코딩으로서는 UTF-8과 UTF-16이 있습니다. 각각 최소 크기가 8비트(1바이트)이냐 16비트(2바이트)이냐를 뜻합니다. 둘다 가변형인 것은 같습니다. UTF8은 ASCII 문자들을 그대로 1바이트로 표현하여 UTF16에 비해 메모리를 아낄 수 있습니다. 또한 호환성도 더 높습니다.

이 외에도 중국 정부 공식 문자열 인코딩인 GB 18030 가 있습니다.

문자열 치환 방법

문자열을 해당 언어/지역에 맞게 변환하는 방법도 중요한데 이는 성능, UX 그리고 지속적 통합에 큰 영향을 주기 때문입니다. 방법은 크게 두가지가 있습니다.

  1. 서버에서 요청 언어별 리소스를 교체 (Server Side)
  2. 클라이언트에서 요청 언어별 리소스 요청, 교체 (Client Side)

1번보단 2번이 많은 경우에 좋은 방법입니다. 리소스 캐시와 선호 언어 설정 등이 가능하기 때문입니다. 하지만 서비스에 따라 1번의 방법이 더 적합할 수 있습니다. 모바일의 경우에 하드웨어적인 한계로 리소스 다운로드를 비롯해 렌더링에도 성능 이슈가 발생할 수 있으며 이에 소모되는 배터리 전력 등이 UX에도 영향을 끼칠 수 있습니다.

또한 새로운 언어가 추가되거나 새로운 기능이 추가되는 등 지속적인 제품 개발 과정에 있어서 국제화가 같이 진행되는데 이때 문자열 치환 방법이 중요해집니다. 따라서 서비스와 사내 개발 과정에 맞추어 적절한 방법을 선택해야 합니다.

https://www.nomensa.com/blog/2010/7-tips-for-multi-lingual-website-accessibility

국제화 UI (문자열 크기 변화, 폰트, 아이콘 등)

리소스가 언어/지역 별로 변환 되면 그에 맞게 UI도 바뀌어야 합니다. 사진 예시처럼 글자 길이가 달라지기도 하고 언어/지역 별로 가독성 등으로 적절한 폰트가 필요하기도 합니다. 영어의 경우 10pt 만으로도 가독성 있는 표현을 할 수 있지만 중국어는 최소 12pt는 되어야 합니다.

문화에 따른 색 의미 차이

또한 문화에 따라 아이콘이나 색의 의미가 달라질 수 있습니다. 위의 그림에서는 문화권 별로 돈/사랑/건강 등의 개념에 대한 색을 보여줍니다.

더 나아가 인공지능의 발전으로 기계 번역의 수준이 기대되는 만큼 UI 내의 많은 리소스를 이미지가 아닌 텍스트 기반으로 변경/유지 하여 기계 번역의 힘을 많이 받을 수 있도록 합니다.

이는 범문화적 인터페이스 디자인(Cross-cultural interface design)이라는 제목으로 좋은 글이 있습니다.

https://www.transifex.com/blog/2015/localization-friendly-ui-design-part-1/

쓰기 방향의 차이 (LTR, RTL)

가장 간과하면서도 가장 널리 알려진 부분입니다. 일부 중동/고대 국가 등에서 사용되는 표기 방식으로 오른쪽에서 왼쪽으로 읽습니다. 이에 따라 인터페이스가 좌우 대칭이 되어버립니다. 위의 국제화 UI에 포함되는 내용이지만 따로 뺄 만큼 극적인 변화가 필요하기 때문입니다. HTML 엘리먼트들의 정렬방식이 달라지는 등 코드적으로도 수정이 필요해집니다.

https://stackoverflow.com/questions/43752248/how-to-determine-where-to-place-the-currency-symbol-when-formatting-a-number

숫자, 공백, 화폐, 날짜, 주소, 측정 단위 등 표기

언어/지역 별로 여러가지 개념 표기가 다릅니다. 화폐에 콤마부터 시작하여 주소 표현방식도 다릅니다. 한국의 2019년 9월 3일은 미국에서 9/3/2019 으로, 유럽에서 3/9/2019 으로 각각 쓰입니다. 이 외에도 일 이라는 표현이 없어 3일 을 3 이라고 표현하게 됩니다. 이러한 부분은 번역 원고로는 담을 수 없고 프로그래밍 차원에서 프레임워크의 도움을 받아야 합니다.

https://www.timetemperature.com/images/dst-united-states.jpg

타임존, 썸머타임 등 시각

타임존은 GMT(Greenwich Mean Time; 그리니치 표준시)를 기반으로 나라/지역 별로 시차를 정해 놓은 것을 뜻합니다. 서울의 경우 GMT+09:00 으로 GMT 에서 9시간 늦습니다. 타임존에 맞추어 시간과 관련된 비즈니스 로직은 민감하게 작성되어야 하며 서비스에 따라 사용자가 타임존을 바꾸는 것도 대응해야 합니다. 무엇보다 타지역에서 실시간으로 접근하는 경우 타임존 차를 넘어 전송/동기화 시간까지도 고려해야 합니다.

썸머 타임(a.k.a. DST; Daylight Saving Time)이란 유럽을 포함하여 전세계 일부 지역에서 여름과 겨울 계절에 낮의 길이가 달라져 이를 맞추기 위해 적용되는 시간 보정입니다. 봄에 한시간을 앞으로 당기고 가을에는 한시간을 뒤로 늦추게 됩니다.

2019년 3월 26일, EU(Europe Union)은 DST를 하지 않기로 투표하였습니다. (참고) 이에 따라 앞으로의 국제화에 있어서 DST가 어떻게 될지는 더 살펴보아야겠습니다.

문자열 정렬 방법

English와 American English는 서로 다른 문자가 없습니다. 마찬가지로 한국어도 문자열 갯수가 엄청 많을 뿐 지역별로 다른 문자를 쓰는 경우는 없습니다. 다만 라틴어에서 파생되었지만 더 많은 문자가 추가된 유럽의 몇몇 국가들에 경우에 ASCII, ISO 8859–1 에 정의된 대로 정렬할 수 없습니다. 나라마다 알파벳을 정렬하는 방법이 다르기 때문입니다. 그 예로 발음의 강세가 표현된 e, ë, é, ě, è 가 있습니다.

cote < côte < coté < côté (French collation)
cote < coté < côte < côté (Latin1 collation)

이를 다루는 것이 Collation입니다. 아마도 데이터베이스에서 많이 보셨으리라 생각합니다.

지금까지 국제화에 있어서 필수적인 요소 몇가지를 살펴보았습니다. 이제 이를 제품 개발 과정에 통합시키기 위해 구체적으로 어떠한 절차가 있는지 살펴보겠습니다.

국제화 이해하기(Understanding Internationalization)

국제화된 소프트웨어를 개발하는 것은 단순히 그렇게 코딩하는 것 뿐 아니라 지역에 맞게 디자인/설계가 필요합니다. 국제화된 소프트웨어는 아래의 특징이 있습니다.

  • 소프트웨어의 국제화 : 언어/지역에 독립적인 소스 코드를 설계합니다. 입력, 출력, 유니코드 지원 및 언어/지역 관련된 데이터 취급 방법 등을 고려합니다. (예: 언어/지역별 소팅 방법, 인코딩 설정, RTL 등)
  • 디자인의 국제화 : 언어/지역에 따라 유연하고 일관된 UI/UX를 디자인합니다. 소스 코드의 변경 없이도 다양한 언어/지역을 지원할 수 있도록 합니다. (예: 충분한 길이의 텍스트 박스)
  • 리소스의 국제화 : 번역가가 담당하는 부분으로서 언어/지역에 가장 적절하게 리소스를 준비하며 시장에 알맞는 전략을 제시합니다.

마이크로소프트의 글을 참고하였습니다.
이 외에도 국제화 체크리스트 글을 통해 실무에 직접적 도움을 받을 수 있습니다.

국제화를 위해 디자인과 번역가가 노력해야하는 부분은 이 글의 범위를 벗어납니다. 좋은 디자이너와 비싼 번역가에게 그 일을 맡기고 우리는 개발자로서 국제화 응용 단계로 나아가보겠습니다.

국제화 요소 중에서 프레임워크의 도움을 받을 수 있는 부분이 있습니다. 바로 숫자, 화폐, 날짜 등 표기에 관련된 부분입니다. 비즈니스 세부 분야에 상관없이 공통된 부분이기에 여러 기구와 업체에서 뜻을 모아 함께 성장해온 거대한 기둥들이 있습니다.

Unicode CLDR 35.1 bcp47/currency.xml

Unicode CLDR(Common Locale Data Repository)

소프트웨어에서 주로 사용되는 언어/지역 별 키 값을 정의해 놓은 마크업 저장소 입니다. LDML(Locale Data Markup Language)로 정의되어 있으며 간단히 말해 XML로 정리해놓은 것 입니다. 실제 번역이 이루어진 값들을 저장하고 있는 것은 아닙니다. LI18NUX 단체에서부터 모태된 단체인 OpenI18N에서 2004년 1월 16일 CLDR 1.0을 처음 발표하며 최근 2019년 4월 17일까지 꾸준히 업데이트 되어 오고 있습니다. 공식 사이트깃허브가 있습니다.

애플, 구글, 마이크로소프트 등 많은 곳에서 사용 중인 ICU

ICU(International Components for Unicode)

Unicode CLDR을 기반으로 실제 번역(변환)을 제공하는 프레임워크입니다. Taligent사에서 개발하여 이후 IBM Globalization Center에 합병되고 오픈 소스 커뮤니티의 큰 지원을 받으며 성장하였습니다. C와 Java를 각각 ICU4C, ICU4J라는 프레임워크로 지원하고 있습니다. 공식 홈페이지에 자세하고 친절한 설명이 있습니다. 애플, 구글, 마이크로소프트등도 사용한다고 합니다.

i18next.js

자바스크립트 기반의 i18n 프레임워크로 i18next가 있습니다. 서버와 클라이언트 모두에서 사랑 받는 언어 기반이라 활용도가 매우 높고 이 글을 읽는 분들도 도입 고려중이라 생각됩니다. 다만 이 부분은 문자열 치환 부분에 해당하며 숫자, 화폐, 날짜 등을 변환해주는 ICU와 같은 성격의 프레임워크가 아닙니다.

MDN web docs

Intl

더이상 자바스크립트는 90년대 jQuery로 범벅이된 그때 그친구가 아닙니다. 수 많은 표준과 개발자의 노력으로 어느새 가장 많이 쓰이며 가장 급성장 중인 언어입니다. 그 증거로 국제화를 위한 내장 객체가 있습니다. 아래 6가지의 속성이 제공됩니다.

  • Intl.Collator : 문자열 비교
  • Intl.DateTimeFormat : 날짜/시간 표기
  • Intl.ListFormat : 목록 표기
  • Intl.NumberFormat : 숫자 표기
  • Intl.PluralRules : 단/복수 표기
  • Intl.RelativeTimeFormat : 상대 시간 표기

이 중 제가 현재 플러스티브이에서 캘린더를 개발하며 사용했던 DateTimeFormat을 예시로 보여드리겠습니다.

Intl.DateTimeFormat().format()

또한 Date 객체에서 직접 toLocaleString()으로 간접적으로 사용할 수 있으며 옵션을 통해 다양한 포맷을 사용할 수 있습니다.

Date.toLocaleString with variety options

(번외) 플러스티브이 캘린더 국제화 초석 다지기

react-big-calendar 를 수정한 react-plus-calendar

번외로 사내에서 필요에 의해 캘린더를 개발하며 추후 국제화를 위해 초석을 두며 조금이지만 국제화를 위해 고민했던 부분을 공유하려고 합니다.

당연하면서도 가장 기본이 되었던 것은 서버 기준 모든 시간 데이터를 UTC로 보관해야했던 것 입니다. 이후 브라우저 단에서는 현재 타임존을 가져와 알맞게 전처리하여 보여줍니다.

타임존을 프론트단에서 추가 연산한다고? 의문이 드실 수 있겠지만 프론트단에서 타임존 관련 작업을 위임하므로써 해당 셋탑의 스크린 일정을 전세계 어디에서나 접근하고 수정할 수 있게 됩니다. 마치 Single Source, Multiple Views와 같습니다.

브라우저의 언어가 한국어일때
브라우저의 언어가 영어일때

이후 디자이너를 통해 이쁘게 디자인된 캘린더 헤더를 보면 D일 (ddd) 으로 표현된 부분이 있습니다. 첫번째 사진은 디자인을 그대로 구현한 것인데, 만약 D일 (ddd) 로 구현했다면 두번째 사진처럼 영미권에서 저렇게 표현하기 힘들었을겁니다.

대신 Intl을 이용하여 현재 브라우저의 언어를 기준으로 i18n 작업을 하였습니다. 국제화를 염두하고 작업하여 UI적인 요소도 범용적으로 설계할 수 있었습니다.

How I handled locale-independent day column header

이렇듯 자바스크립트에서 기본적으로 지원해주는 Intl 때문에 추가적인 프레임워크 의존 없이도 충분히 국제화의 초석을 놓을 수 있었습니다. 이후에도 타임존마다 다른 스크린 일정을 동시에 관리하는 등 아직 더 고민하고 해결해야할 이슈가 있습니다. 더 깔끔하고 유연한 방법을 공부하고 연구하여 다음 포스팅에서 보다 도움되는 내용으로 찾아뵙도록 하겠습니다.

마치며

글을 준비하며 국제화는 전세계 대상으로 하는 만큼 많은 기구들이 표준화에 노력과 심혈을 기울였다는 것을 알 수 있었습니다. 또한 단순히 문자열 변환 뿐 아닌 디자인과 기획단에서 부터 준비해야 하는 부분이 있으며 서비스 마다 추가적으로 고민해야합니다. 이 글이 독자 분들의 프로젝트의 국제화에 작은 도움이 되었길 바라며 글을 마치겠습니다.

감사합니다.

--

--