스택큐힙리스트

왜 1927년 두 시간을 빼 보면 이상한 결과가 나오는 걸까요? 본문

카테고리 없음

왜 1927년 두 시간을 빼 보면 이상한 결과가 나오는 걸까요?

스택큐힙리스트 2023. 3. 10. 21:50
반응형

다음 프로그램을 실행하면, 1초 차이가 나는 두 날짜 문자열을 파싱하여 비교합니다.

public static void main(String[] args) throws ParseException {

SimpleDateFormat sf = new SimpleDateFormat(yyyy-MM-dd HH:mm:ss);

String str3 = 1927-12-31 23:54:07;

String str4 = 1927-12-31 23:54:08;

Date sDt3 = sf.parse(str3);

Date sDt4 = sf.parse(str4);

long ld3 = sDt3.getTime() /1000;

long ld4 = sDt4.getTime() /1000;

System.out.println(ld4-ld3);

}

결과는:

353

왜 시간차이가 1초 뿐인데 1이 아니라 353이 되는 걸까요?

날짜를 1초 뒤의 시간으로 변경하면:

String str3 = 1927-12-31 23:54:08;

String str4 = 1927-12-31 23:54:09;

그러면 #@#^@*!!$&은 #@!@&**$&이 될 것입니다.

자바 버전:

java version 1.6.0_22

Java(TM) SE Runtime Environment (build 1.6.0_22-b04)

Dynamic Code Evolution Client VM (build 0.2-b02-internal, 19.0-b04-internal, mixed mode)

Timezone(`TimeZone.getDefault()`):

sun.util.calendar.ZoneInfo[id=Asia/Shanghai,

offset=28800000,dstSavings=0,

useDaylight=false,

transitions=19,

lastRule=null]

Locale(Locale.getDefault()): zh_CN

답변 1

12월 31일 상하이는 시간대 변경입니다.

상세 내용은 상해의 1927년을 참조하세요. 기본적으로 1927년의 끝인 자정에 시계가 5분 52초 뒤로 돌아갔습니다. 따라서 1927-12-31 23:54:08은 사실 두 번 발생했으며, Java는 해당 지역 날짜/시간에 대한 나중 가능한 순간으로 구문 분석하는 것으로 보입니다. 이것이 차이의 원인입니다.

시간대의 종종 이상하고 놀라운 세계의 또 다른 에피소드입니다.

수정: 중단! 역사가 변화합니다...

2013년 버전의 TZDB로 재구축된 원래 질문은 이제는 전혀 다른 결과를 보여주지 않을 것입니다. 2013a에서는 결과가 358초이며, 전환 시간은 23:54:08이 아닌 23:54:03입니다.

나는 이것을 Noda Time에서 이처럼 질문을 수집하기 때문에 알아채게 되었다. 이제 테스트는 변경되었지만, 이것은 역사적인 데이터조차도 안전하지 않다는 것을 보여준다.

편집: 역사가 다시 바뀌었습니다 ...

TZDB 2014f에서는 변경 시간이 1900-12-31로 이동되었으며, 이제 단지 343초의 변경이 있습니다 (따라서 t와 t+1 사이의 시간은 344초입니다).

EDIT: 1900년 전의 모든 순간에 대해 Java 시간대 구현은 모든 시간대를 해당 기준 시간대로 취급하는 것으로 보입니다.

import java.util.TimeZone;

public class Test {

public static void main(String[] args) throws Exception {

long startOf1900Utc = -2208988800000L;

for (String id : TimeZone.getAvailableIDs()) {

TimeZone zone = TimeZone.getTimeZone(id);

if (zone.getRawOffset() != zone.getOffset(startOf1900Utc - 1)) {

System.out.println(id);

}

}

}

}

위의 코드는 내 Windows 기계에서 출력을 생성하지 않습니다. 따라서 1900년 초에 기준값과 다른 오프셋을 가진 모든 시간대는 그것을 전환으로 계산할 것입니다. TZDB 자체는 그보다 이른 데이터가 있으며, 고정표준 시간의 개념에 의존하지 않기 때문에(getRawOffset) 다른 라이브러리에서는 이 인공 전환을 도입할 필요가 없습니다.

답변 2

안녕하세요, 이번에는 1927 년 두 시간을 빼면 이상한 결과가 나오는 이유에 대해서 알아보겠습니다. 이 문제는 컴퓨터 과학 분야에서 유명한 문제 중 하나입니다.

이 문제는 1927 년 1 월 1 일에 런던과 뉴욕의 시간 차이가 5 시간 44 분이었고, 이를 기록하기 위해 두 도시에서 초 단위의 시간을 측정했던 것입니다. 그리고 두 도시에서 측정한 시간은 다음과 같습니다.

런던 : 02:13:00

뉴욕 : 20:18:00

그런데 이 두 시간을 빼면 이상한 결과가 나옵니다. 실제 계산 결과는 -18 시간 35 분이지만, 이 값이 무엇을 의미하는지는 모릅니다.

이 문제의 원인은 바로 1927 년에는 서머타임이 아직 적용되지 않았다는 것입니다. 서머타임은 1916 년부터 시작된 것으로, 일부 국가에서는 일정 기간 동안 시간을 조정하여 태양이 더 늦게 지도록 하는 것입니다.

그러나 런던과 뉴욕에서는 이 당시 서머타임을 적용하지 않았기 때문에, 이 두 도시의 시간 차이는 엄밀히 말하면 항상 정해져 있지 않았다는 것입니다.

결론적으로, 이 문제는 컴퓨터 과학 분야에서 자주 나오는 문제 중 하나이며, 프로그래밍에서 시간 차이를 계산할 때는 항상 서머타임을 고려해야 한다는 것을 알리는 좋은 사례입니다. 감사합니다.

반응형
Comments