Java SimpleDateFormat을 이용하여 Millisec 취급 시 주의 사항 (Bug ID: 4516915)
Posted 2009.08.14 16:57자바에서 날짜를 millisec 단위로 다룰 때, 주의 사항이 있다. Sun에서 인정하지 않는 관련 버그(?) (→ "견해 차" 정도가 좋겠다)가 있다는 것. 0.1 초는 분명 100 millisec인데, 1 millisec으로 취급하는 경우가 있다. 아래의 예를 보고 Bug Report를 참고해 보시길...
밀리초 단위를 다룰 일이 없어, 전혀 몰랐는데. 같이 일하는 후배를 통해 우연히 발견했다.
이미 2001년도에 Sun에 버그리포팅 된 내용인데, "Not a defect"로 분류가 되어 있다.
내용은 다음의 테스트 케이스를 통해 확인해 볼 수 있다. 10.4 초 부분을 SimpleDateFormat을 이용해 millisec을 3자리로 바꾸어 표현하고 확인하는 내용이다. 즉, 10.400 초를 기대하고 테스트 한다.
public static void testSimpleDateFormat() throws Exception { String timeString = "2009-08-14 10:10:10.4"; /* * 주어진 문자열을 SimpleDateFormat으로 Date 형식으로 변환 */ Date time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S").parse(timeString); /* * 밀리초 단위를 세자리로 설정 * 10.4 초 = 10.400 초 이여야 한다. */ assertEquals( "2009-08-14 10:10:10.400" , new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(time)); } |
결과는 다음과 같다.
이건 아무리 봐도 수정되야 할 것 같은데... 암튼 이 자리를 빌어 유용한 정보를 알려준 후배에게 감사!
+ 2009-08-16 내용 추가
Sun 이 이유 없이 "Not a Defect"로 분리하였을 리는 없다. Sun 이 주장하는 내용에 대한 이야기를 요약하고, 그에 반하는 이유를 좀 더 구체적으로 적어 봤다.
Sun 이 제시하는 관점은 new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S") 에서 S는 숫자일 뿐이라는 것이다. 이 말은 더욱 근본적이고 중요한 가정을 하나 포함하고 있는데, "." 또한 문자열일 뿐이라는 가정이 그 것이다. 다음의 예를 보면 이 말이 더욱 와 닿을 것이다.
new SimpleDateFormat("yyyy-MM-dd HH 시 mm 분 ss 초 S 밀리초") |
위 경우 S를 통해 4가 전달되었다면 이를 멋대로 400 밀리초라고 해석하거나 해선 곤란할 것이다.
이 쯤 되면 "뭐야 Sun 말이 맞네!" 라고 돌을 던질 수(저... 연약합니다! )도 있지만. 문제는 밀리초는 애당초 날짜를 나타내는 다른 숫자들과는 성격이 다르다는 사실이다. 연/월/일/분/초 의 경우는 일단 특정 숫자가 정해지면 그 숫자는 죽어도 그 값을 나타낸다. 8월은 죽었다 깨어나도 8월이다.10초는 죽었다 깨어나도 10초이다. 즉 숫자 표기와 그 의미가 1:1로 정확하게 떨어진다. 그러나, 시(h)와 밀리초(ms)는 좀 다르다. "1시"라는 표기는 우리가 늘 사용하지만, 상황에 따라서 오후 1시 일 수도 있고 오전 1시 일 수도 있다. 그렇기 때문에 이를 정확하게 표현하기 위한 방법인 24시 표기법이나 AM/PM 표기 등을 SimpleDateFormat에서 지원하는 것을 익히 알고 있을 것이다. 밀리초도 표기와 의미가 1:1 관계가 아니라는 점에서는 시(h)와 같다. 앞서 본 경우처럼 4라는 밀리초 단위의 숫자는 초와 연동되어 0.4초 의 의미일 수도 있다. 또는 간혹 (사실 밀리초 표기 관례 상 드문 경우일 것 같지만...) 말 그대로 4밀리초일 수도 있다.
생각해보면, 애당초 밀리초(millisec)라는 단어 자체가 작은 초 단위라는 의미이지 아닌가! 초를 떼어놓기 생각하기 힘든게 당연하다. 본인이 생각하는 문제는 "시"에 대한 표기와는 달리 우리의 표기 관례 대로 밀리초를 다룰 방법에 대한 지원이 이루어지지 않는다는 것이다. 초 단위가 소수점 이하로 다루어질 수 있는 것도 아니고, 밀리초 표기에 다른 방법도 없다. Sun이 Not a Defect로 분류한 이 내용은 본인에게는 마치 다음과 같이 들린다.
1시는 죽어도 한시이다. 그러니까 오후 1시를 표기하기 위해서는 반드시 13시라고 표시해라.그 외에도 SimpleDateFormat은 Thread관련 문제를 안고 있으면서도 무겁다. 이에 관해서는 다음에 적어보겠다. (이는 누군가가 다루었을 것 같아 일단 다른 분들의 글 좀 검색하고...)