Java

[Java] 서울-뉴욕간의 시차를 구하는 문제에서 뉴욕의 ZoneOffset이 '-05:00'가 아니라 '-04:00'로 나오는 이유

haehyun 2021. 10. 23. 18:50

아래는 서울과 뉴욕간의 시차가 얼마인지 계산하는 소스코드이다.

import java.time.*;
import java.time.temporal.*;

public class Exercise10_8 {
	public static void main(String[] args) {
		//ZonedDateTime
		ZonedDateTime seoulTime = ZonedDateTime.now();
        	ZoneId nyId = ZoneId.of("America/New_York");
		ZonedDateTime nyTime = ZonedDateTime.now().withZoneSameInstant(nyId);
		
		//ZonedDateTime -> ZoneOffset
		ZoneOffset krOffset = seoulTime.getOffset();
		int krOffsetInSec = krOffset.get(ChronoField.OFFSET_SECONDS);
		ZoneOffset nyOffset = nyTime.getOffset();
		int nyOffsetInSec = nyOffset.get(ChronoField.OFFSET_SECONDS);
		
        	//Hour = Second / (60*60)
		int diffOffset = (krOffsetInSec - nyOffsetInSec) / (60 * 60);

		System.out.println(seoulTime);
		System.out.println(nyTime);
		System.out.println("sec1=" + krOffsetInSec);
		System.out.println("sec2=" + nyOffsetInSec);
		System.out.println("diff=" + diffOffset + " hrs");
	}
}
//실행결과
2021-10-23T18:24:55.030+09:00[Asia/Seoul]
2021-10-23T05:24:55.031-04:00[America/New_York]
sec1=32400
sec2=-14400
diff=13 hrs

 

소스코드를 제대로 작성했으나, 위 문제의 정답과 내 실행결과가 다른 것을 볼 수 있다.

정답 실행결과

 

뉴욕의 ZonedDateTime을 구하는 과정에서 시차(ZoneOffset) 값이 -04:00과 -05:00으로 각각 다르게 나타난다.

실행결과 비교

 

위와 같이 차이가 생기는 이유는 ZonedDateTime를 구할 때 ZoneId로 시간대(time zone)를 추가했기 때문이다.

ZoneId nyId = ZoneId.of("America/New_York");
ZonedDateTime nyTime = ZonedDateTime.now().withZoneSameInstant(nyId);

 

뉴욕을 포함한 대부분의 도시들은  일광 절약시간(DST, Daylight Saving Time) 혹은 섬머타임(Summer Time)이라는 것이 있어 시차가 고정되어 있지 않고 유동적이다.

일광 절약시간이란 여름철에 지방의 표준시보다 1시간 시계를 앞당겨 놓는 것(시차-01:00)으로, 시간이 당겨진 만큼 하루를 일찍 시작하고 해가 떠있는 시간에 활동하게 된다.

ZoneId는 시간대와 관련된 규칙들을 포함하고 있어 일광 절약시간을 자동으로 처리해준다.
일광 절약시간 등을 고려하지 않고 일관된 시차를 구하고 싶다면 ZoneOffset을 사용하여 OffsetDateTime을 구한다.

아래는 ZonedDateTime 대신 OffsetDateTime을, ZoneId 대신 ZoneOffset을 사용한 소스코드이다.

import java.time.*;
import java.time.temporal.*;

public class Exercise10_8 {

	public static void main(String[] args) {
		//ZonedDateTime <- ZoneOffset
		ZoneOffset krOffset = ZoneOffset.of("+9");
		OffsetDateTime seoulTime = OffsetDateTime.now().withOffsetSameInstant(krOffset);
		ZoneOffset nyOffset = ZoneOffset.of("-5");
		OffsetDateTime nyTime = OffsetDateTime.now().withOffsetSameInstant(nyOffset);
		
		//ZoneOffset -> Second
		int krOffsetInSec = krOffset.get(ChronoField.OFFSET_SECONDS);
		int nyOffsetInSec = nyOffset.get(ChronoField.OFFSET_SECONDS);
		
		int diffOffset = (krOffsetInSec - nyOffsetInSec) / (60 * 60);

		System.out.println(seoulTime);
		System.out.println(nyTime);
		System.out.println("sec1=" + krOffsetInSec);
		System.out.println("sec2=" + nyOffsetInSec);
		System.out.println("diff=" + diffOffset + " hrs");
	}
}
//실행결과
2021-10-23T18:56:19.957+09:00
2021-10-23T04:56:19.957-05:00
sec1=32400
sec2=-18000
diff=14 hrs

 


참고자료

  • Java의 정석 3rd / 남궁 성 / 도우출판