Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

후레임의 프로그래밍

왜 두 시간을 빼면 (1927년) 이상한 결과가 나오는 이유는 무엇입니까? 본문

스택오버플로우(Stack Overflow)

왜 두 시간을 빼면 (1927년) 이상한 결과가 나오는 이유는 무엇입니까?

후레임 2020. 10. 26. 01:34
질문

다음 프로그램을 실행하면 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이 아니라 ld4-ld3(1 초의 시간 차이에서 예상했듯이)이지만 353?

날짜를 1 초 후 시간으로 변경하는 경우 :

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

그런 다음 ld4-ld3 1이됩니다.


자바 버전 :

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



답변

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

 

See this page for details of 1927 in Shanghai. Basically at midnight at the end of 1927, the clocks went back 5 minutes and 52 seconds. So "1927-12-31 23:54:08" actually happened twice, and it looks like Java is parsing it as the later possible instant for that local date/time - hence the difference.

 

종종 이상하고 멋진 시간대의 또 다른 에피소드입니다.

 

수정 : 그만 누르세요! 역사 변경 ...

 

TZDB . 2013a에서 결과는 358 초이며 전환 시간은 23:54:08이 아니라 23:54:03입니다.

나는 Noda Time에서 단위 테스트 ... 이제 테스트가 변경되었지만 표시 될뿐입니다. 기록 데이터도 안전하지 않습니다.

 

수정 : 기록이 다시 변경되었습니다 ...

TZDB 2014f에서 변경 시간은 1900-12-31로 이동했으며 이제는 343 초에 불과합니다 (따라서 t t + 1 사이의 시간

는 344 초입니다. 무슨 뜻인지 알 수 있습니다.

 

수정 : 1900 년 전환에 대한 질문에 답하기 위해 자바 시간대 구현은 모든 시간대를 단순히 표준 시간대로 취급하는 것 같습니다. 1900 UTC가 시작되기 전의 모든 순간 :

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이 유효한 개념이라고 가정하는 것)에 대한 아이디어에 의존하지 않으므로 다른 라이브러리가 필요합니다. 이 인공적인 전환을 도입합니다.



출처 : http://stackoverflow.com/questions/6841333