2014-01-24 1 views
1

업데이트 된 캘린더 객체에서 getTimeInMilliseconds()를 호출 할 수 있도록 실제 날짜/시간을 유지하면서 캘린더 객체의 시간대를 변경하려고합니다.JAVA : 날짜/시간을 변경하지 않고 Calendar 객체의 TimeZone을 변경할 때 이상한 동작이 발생했습니다.

나는 this other question을 보았다. 여기서 허용되는 대답은 새 Calendar 객체의 각 필드를 개별적으로 설정하는 것입니다. 그러나 원래 캘린더 개체 복사본의 표준 시간대를 변경하는 것만으로 간단하게 작업 할 수있었습니다. 이상한 것은 timeZone을 재설정하기 전에 원래 일정을 약간 수정 한 경우에만 작동합니다. 다음 예는 불일치를 설명합니다.

public void TestCalendar() 
{ 
    Calendar nextYear = Calendar.getInstance(); 
    nextYear.add(Calendar.YEAR, 1); 
    log.info("Next Year: {}", getUTCMilliseconds(nextYear)); 

    Calendar now = Calendar.getInstance(); 
    log.info("Now: {}", getUTCMilliseconds(now)); 
} 

protected String getUTCMilliseconds(Calendar cal) 
{ 
    // Create a new calendar so we don't modify input 
    Calendar expectedDbTime = (Calendar) cal.clone(); 
    // Change the TimeZone the contained date is interpreted in 
    expectedDbTime.setTimeZone(TimeZone.getTimeZone("UTC")); 
    // Return millisecond value of this date in the UTC timezone 
    return String.valueOf(expectedDbTime.getTimeInMillis()); 
} 

내가 2:33 @ 오후 월 24 일이 프로그램 2015을 실행하고, 다음과 같은 결과를 얻었다 :

Next Year: 1422110038529 //(Corresponding UTC Date: Sat Jan 24 2015 2:33:58 PM) 
Now: 1390599238531 //(Corresponding UTC Date: Fri Jan 24 2014 9:33:58 PM) 

당신은, 예상대로 nextYear 인쇄 그러나 다음 줄을 볼 수 있듯이 이 예상대로 아닙니다 (2014 년 1 월 24 일 오후 2시 33 분 58 초에 대응해야하며 대신 2012 년 1 월 24 일 2:33:58 MTT 인 현재 날짜/시간에 해당). 누군가 여기서 무슨 일이 일어나는지 말해 줄 수 있니?

편집 : 일부 서식을 업데이트했습니다.

+1

setTimeZone'의 동작은()'매우 직관적이고 효과적으로 깨진입니다. 이 동작에 대해 제기 된 몇 가지 버그가 있습니다. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4827490 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id= 4177484 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4096231 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4227735 –

+0

귀하의 질문이 아닌 @goparkyourcar 명확한. 정확히 무엇부터 시작하고 싶습니까? 그리고 출력으로 무엇을 원하십니까/기대합니까? –

+0

의도는 특정 시간대 (일요일 12/01 1 월 12 일 MTN)에서 일부 날짜/시간을 나타내는 Calendar 객체가 주어진 경우 다른 날짜 영역에서 같은 날짜의 밀리 초 값을 가져 오려고합니다 (Say 2012 년 1 월 1 일 1시 12AM UTC). 이것에 관한 내 질문은 왜 제대로 작동하려면 함수를 얻으려면 내 getUTCMilliseconds() 함수를 호출하기 전에 캘린더 개체를 수정해야합니다. – Cod3Citrus

답변

2

시간대 설정은 입력란 설정과 같이 작동하지 않습니다. 필드를 설정하면 내부 밀리 초가 필드와 일치하도록 다시 계산됩니다. 시간대를 설정하면 필드가 다시 계산되어 밀리 초가 일정하게 유지됩니다! (즉, 당신이 2:00 PM의 산을 평가 한 후 UTC로 설정하면, 오후 2시를 나타내는 밀리 초가 계산되지 않고 오후 9 시로 변경됩니다.)

이제는 옆쪽으로 가면 set (또는 add 경우) 밀리 초 수를 다시 계산하도록 Calendar에 지시하는 플래그 (add으로 설정)가 밀리 초에서 텍스트 필드를 다시 계산할지 여부를 알려주는 플래그보다 우선합니다

토 2015년 1월 24일 2시 33분 58초 :

그래서 시나리오 1 달력) setTimeZone으로 설정 텍스트 값이 PM UTC이고 add은 "인간의 값을 기반으로 밀리 초를 다시 계산"하는 플래그가 켜져 있기 때문에 예상 한 # 호를 제공합니다.

시나리오 2 일정은 텍스트 값이 있습니다

토 2015년 1월 24일 세계 협정시 오후 2시 33분 58초하지만 밀리 초 #가없는 재 계산 말한다 플래그를, 그래서 대신에 플래그가 설정 시간대으로 설정 밀리 초를 기준으로 인간의 가치를 "재 계산"하는 기능이 켜져 있고 오후 9 시로 변경됩니다.() getTime를 호출하는 시간대를 설정하기 전에 밀리 초를 계산하는 플래그를 지 웁니다 때문에이 둘 사이에 일관된 동작을 볼 수

public void TestCalendar() { 
    Calendar nextYear = Calendar.getInstance(); 
    nextYear.add(Calendar.YEAR, 1); 
    nextYear.getTime(); 
    log.info("Next Year: {}", getUTCMilliseconds(nextYear)); 

    Calendar now = Calendar.getInstance(); 
    log.info("Now: {}", getUTCMilliseconds(now)); 
} 

:

에 당신이 당신의 코드를 변경하는 경우

.

이제 이런 질문에 대한 스톡 응답이 'omg use jodatime'인 이유를 알 수 있습니다!당신이 일이 기대했던 것을 얻을 수

'안전한'방법은 다음과 같습니다

protected String getUTCMilliseconds(Calendar cal) { 
    Calendar utcCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); 
    utcCal.set(Calendar.YEAR, cal.get(Calendar.YEAR)); 
    utcCal.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR)); 
    utcCal.set(Calendar.HOUR_OF_DAY, cal.get(Calendar.HOUR_OF_DAY)); 
    utcCal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE)); 
    utcCal.set(Calendar.SECOND, cal.get(Calendar.SECOND)); 
    utcCal.set(Calendar.MILLISECOND, cal.get(Calendar.MILLISECOND)); 
    return String.valueOf(utcCal.getTimeInMillis()); 
} 
관련 문제