날짜 표시에 지역화(Localization)가 잘 고려된 DateFormat 클래스

필자의 경우 안드로이드 애플리케이션에서 날짜를 보여주기 위해서 자바 API의 DateFormat을 많이 사용한다. 그리고 이 애플리케이션은 플레이 스토어에 모든 나라에서 사용할 수 있는 애플리케이션으로 등록했다. 그래서 많은 애플리케이션을 보면 DateFormat을 미국에서 사용하는 포맷으로 사용하거나 개별 국가에 맞는 포맷을 지원(지역화)하려고 /res/values-xx 와 같은 국가별 리소스 폴더에 포맷을 문자열로 저장해서 사용하기도 한다.

국가별로 선호하는 날짜 포맷을 살펴보자. 국가별 날짜 포맷은 아래의 위키피디아 페이지에서 확인할 수 있다. 그리고 이 페이지의 국가별 날짜 포맷은 마이크로 소프트와 IBM에서 사용하는 형태로 정리되어 있다.
http://en.wikipedia.org/wiki/Date_format_by_country
이 페이지를 보면, 날짜를 표시하는데 연도, 달 그리고 일의 순서에 따라서 엔디안(Endican)이 달라지는 것을 알 수 있고, 개별 국가에서 사용하는 엔디안과 날짜를 표기하는 포맷을 확인할 수 있다.  우리나라와 미국에서 주로 사용하는 포맷을 살펴보자.

    • 우리나라
      yyyy년 mm월 dd일, yyyy.mm.dd, yyyy/mm/dd
  • 미국
    일반적으로는 mm/dd/yy or mm/dd/yyyy를 많이 사용하고, 군대, 학교 그리고 정부등에서는 dd mmm(m) yyyy and yyyy-mm-dd 를 많이 사용한다.

위에서 살펴본 우리나라와 미국의 포맷을 보면, 날짜를 표시하는 형태가 달라지기 때문에 지역화가 까다롭다는 것을 알 수 있다.

이렇게 불편한 지역별 날짜 표시를 쉽게 할 수 있도록, 구글님은 안드로이드 젤리빈 4.3(API 18)에 나라별로 날짜를 표시하기 위한 중요한 메서드를 하나 추가하였다. 이 메서드는 아래에서 확인할 수 있다.

static String getBestDateTimePattern(Locale locale, String skeleton)
Returns the best possible localized form of the given skeleton for the given locale.

와우, 로케일과 skeleton을 보고 젤루 좋은 지역화된 포맷을 넘겨준다고 한다. 개인적으로 어떻게 이렇게 좋은 기능을 제공할 수 있나?에 궁금함으로 확인해 보니, android.text.format.DateFormat 클래스는 안드로이드에 ICU4C를 포팅해서 JNI로 필요한 메서드를 호출하고 있다. 그리고 구글의 G+ 애플리케이션의 오픈소스 목록에서 ICU4J를 확인할 수 있다. 구글의 G+ 애플리케이션에서 ICU4J 라이브러리를 사용하는 이유는 안드로이드에 ICU4C가 늦게 포팅이 되기 때문으로 추측해볼 수 있다. 자 이제 이 메서드가 제대로 동작하는지 확인해 보자.

  • FileDateUtil 클래스
    – 이 클래스는 개인 프로젝트에서 파일의 날짜를 표시하기 위해서 사용하고 있다.
    – 이 클래스에서는 DateFormat.getBestDateTimePattern() 메서드가 API 18버전부터 지원하기에 18버전 이후부터는 사용할 수 있도록 구현했다.
package net.sjava.common.date;

import android.annotation.TargetApi;
import android.os.Build;
import android.text.format.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 *
 * Created by mcsong@gmail.com
 * 
 */
public class FileDateUtil {
	public static String getModifiedDate(long modified) {
		return getModifiedDate(Locale.getDefault(), modified);
	}

	public static String getModifiedDate(Locale locale, long modified) {
		SimpleDateFormat dateFormat = null;

		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
			dateFormat = new SimpleDateFormat(getDateFormat(locale));
		} else {
			dateFormat = new SimpleDateFormat("MMM/dd/yyyy hh:mm:ss aa");
		}

		return dateFormat.format(new Date(modified));
	}
	
	@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
	public static String getDateFormat(Locale locale) {
		return DateFormat.getBestDateTimePattern(locale, "MM/dd/yyyy hh:mm:ss aa");
	}
}
  • MainActivity 클래스
    – 안드로이드에서 화면을 보여주는 메인 클래스이다.
    – FileDateUtil 클래스를 사용해서 현재 시각을 국가별 포맷으로 보여준다.
public class MainActivity extends Activity {
	private TextView tv;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		tv = (TextView)findViewById(R.id.textview);
		
		
		String koreaData = FileDateUtil.getModifiedDate(Locale.KOREA, System.currentTimeMillis());
		String franceData = FileDateUtil.getModifiedDate(Locale.FRENCH, System.currentTimeMillis());
		String defaultData = FileDateUtil.getModifiedDate(Locale.getDefault(), System.currentTimeMillis());
		
		String result = "한국 : " + koreaData + System.getProperty("line.separator");
		result += "프랑스 : " + franceData + System.getProperty("line.separator");
		result += "기본 : " + defaultData + System.getProperty("line.separator");
		
		tv.setText(result);
	}
}

위의 소스를 사용해서 우리나라, 프랑스 그리고 미국(기본값)을 확인한 결과는 다음과 같다.

이제 안드로이드에서 날짜를 보여주는데 주로 사용했던 포맷을 선언해서 날짜를 가져오는 형태보다 DateFormat.getBestDateTimePattern() 메서드를 사용해서 국가별로 편하게 날짜를 확인할 수 있도록 지원할 수 있다.

* Reference
http://site.icu-project.org
http://developer.android.com/reference/android/text/format/DateFormat.html

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.