질문 : 이 두 번을 빼면 (1927 년) 이상한 결과가 나오는 이유는 무엇입니까?
다음 프로그램을 실행하면 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
왜 ld4-ld3
1
아니라 (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 일 상하이의 시간대 변경입니다.
상하이 1927 년에 대한 자세한 내용은 이 페이지 를 참조하십시오. 기본적으로 1927 년 말 자정에 시계는 5 분 52 초로 거슬러 올라갑니다. 따라서 "1927-12-31 23:54:08"은 실제로 두 번 발생했으며 Java가 해당 로컬 날짜 / 시간에 대해 나중에 가능한 순간으로 파싱하는 것처럼 보입니다. 따라서 차이가 있습니다.
종종 이상하고 멋진 시간대 세계의 또 다른 에피소드입니다.
편집 : 그만 누르십시오! 역사 변경 ...
원래 질문은 TZDB 버전 2013a로 다시 빌드하면 더 이상 동일한 동작을 보여주지 않습니다. 2013a에서 결과는 358 초가되며 전환 시간은 23:54:08이 아니라 23:54:03입니다.
나는 Noda Time에서 단위 테스트 의 형태로 이와 같은 질문을 수집하고 있기 때문에 이것을 발견했습니다. 테스트는 이제 변경되었지만 단지 보여줄 것입니다. 심지어 과거 데이터조차 안전하지 않습니다.
편집 : 역사가 다시 변경되었습니다 ...
TZDB 2014f에서 변경 시간은 1900-12-31로 이동했으며 이제는 343 초에 불과합니다. 즉, t
와 t+1
사이의 시간은 344 초입니다.
편집 : 1900 년 전환에 대한 질문에 대답하려면 ... Java 시간대 구현이 모든 시간대를 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
이 유효한 개념이라고 가정하는 것)에 대한 아이디어에 의존하지 않으므로 다른 라이브러리에서이 인공적인 전환을 도입 할 필요가 없습니다.
출처 : https://stackoverflow.com/questions/6841333/why-is-subtracting-these-two-times-in-1927-giving-a-strange-result
'프로그래밍 언어 > JAVA' 카테고리의 다른 글
다중 JFrame의 사용 : 좋은 습관인가? 나쁜 습관인가? (0) | 2021.07.08 |
---|---|
Java에서 올바른 마이크로 벤치 마크를 작성하는 방법 (0) | 2021.07.06 |
macOS에서 기본 Java (JDK) 버전을 설정하거나 변경하는 방법 (0) | 2021.07.06 |
ISO 8601 호환 문자열을 java.util.Date로 변환 (0) | 2021.06.30 |
Java import 문에 와일드 카드를 사용하는 것이 왜 나쁜가요? (0) | 2021.06.26 |