자바의 GregorianCalendar를 이용하여 date를 계산하는 과정에서 문제가 발생해서 한 동안 애를 먹었다. 평소에 그냥 아무 문제 없이 돌아가던 테스트가 갑자기 에러를 발생시킨 것이다. 문제는 그 이후에 다시 그 문제가 발생하지 않았는데, 그냥 그러려니 하고 넘어가기에는 이해가 안가는 부분이 있어서 에러를 발생시킨 원인에 대해 알아봤다.

문제의 에러는 GregorianCalendar에 현재 timestamp를 저장해 놓고 add() method를 이용해서 13일씩 빼 나가던 중 발생했다. 테스트 시점의 timestemp는 2008-03-18 00:39:51이었고, 다음의 code를 실행시켰다. (그 후에는 아무리 같은 테스트를 수행해도 한 시간이 더해지는 경우는 생기지 않았다. ㅡ.ㅡ;;)

GregorianCalendar cal = new GregorianCalendar();
GregorianCalendar cal1 = (GregorianCalendar) cal.clone();
cal.setTime(new java.util.Date()); // 2008-03-18 00:39:51 이 저장되었다.
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

int step = 13;
for (int i = 0; i < 8000; i += step)
{
cal1.setTime(cal.getTime());
cal1.add(Calendar.DAY_OF_YEAR, -i);
System.out.println(df.format(cal1.getTime()));
}

척 보기에도 아주 간단한 코드인데, 문제는 아래와 같이 결과가 나오던 중 1988-05-08 01:39:51이라는 엉뚱한 값이 나와버린 것이다. 도대체 저 한시간이 어디서 더해진거란 말인가? ㅡ.ㅡ;;

2008-03-18 00:39:51
2008-03-05 00:39:51
2008-02-21 00:39:51
2008-02-08 00:39:51
...
1988-06-03 00:39:51
1988-05-21 00:39:51
1988-05-08 01:39:51 <- 여기가 문제의 값이 출력된 부분이다.
1988-04-25 00:39:51
1988-04-12 00:39:51
...

도전 정신이 생기면 아래 more를 누르지말고 스스로 그 원인을 찾아보길~

more..

2008/04/15 15:06 2008/04/15 15:06

Trackback Address >> http://oosoom.org/trackback/97

댓글을 달아 주세요

  1. OpenID Logo호빵맨 2008/04/17 02:02  address  modify / delete  reply

    ㅋ, 그런 경우가. 그래서 locale, calendar, keyboard 등이 한 데 얽혀 있는거군. 엄청 황당 했었겠군. 난 예전에 2 + 2가 4로 안나와서 거 때문에 당황한 적이 있었던 거 같다. 왜 그랬는 지는 지금은 기억이 안나네.

    • exedra 2008/04/17 13:44  address  modify / delete

      그래서 GregorianCalendar를 쓸 때는 아주 조심해야 할 것같다. DST가 적용되는 지역에서 쓸 때는 특히나 더.
      2+2가 4가 안되는 경우를 빨리 찾아서 올려라~

  2. OpenID Logoexedra 2008/04/19 03:23  address  modify / delete  reply

    GregorianCalendar를 time zone과 상관 없이 단순히 날짜 계산을 위해 사용하고 싶다면 GregorianCalendar를 생성할 때 GMT로 time zone을 세팅하면 될 것같다.
    즉 다음과 같이 한다는 말~
    Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));

[로그인][오픈아이디란?]