자바 에서 타임 스탬프 를 계산 하 는 과정 에서 발생 한 데이터 넘 침 문제
3465 단어 자바
오늘 정시 임 무 를 수행 하 는 과정 에서 한 임무 가 데 이 터 를 설정 하 는 조회 시간 범위 가 이상 하고 시작 시간 스탬프 가 종료 시간 스탬프 보다 큰 이상 한 현상 이 나 타 났 다. 시간 스탬프 를 계산 하 는 코드 는 대체적으로 다음 과 같다.
package com.lingyejun.authenticator;
public class IntegerTest {
public static void main(String[] args) {
long endTime = System.currentTimeMillis();
long startTime = endTime - 30 * 24 * 60 * 60 * 1000;
System.out.println("end : " + endTime);
System.out.println("start : " + startTime);
}
}
먼저 결론 을 내 립 니 다. 자바 에서 정 수 는 기본적으로 int 형식 이기 때문에 계산 하 는 과정 에서
30 * 24 * 60 * 60 * 1000
계산 결과 가 Integer.MAX_VALUE
보다 많 기 때문에 데이터 가 넘 쳐 계산 결과 가 정확 하지 않 은 문제 가 발생 했 습 니 다.검증 하 다.
우 리 는 위의 코드 를 약간 개조 하여 포 지 셔 닝 문 제 를 확인 할 수 있 도록 합 니 다. 조 정 된 코드 는 다음 과 같 습 니 다.
package com.lingyejun.authenticator;
public class IntegerTest {
public static long calcStartTime(long endTime, long minusMills) {
System.out.println("end : " + endTime + " minus mills : " + minusMills);
long startTime = endTime - minusMills;
System.out.println("start: " + startTime);
return startTime;
}
public static void main(String[] args) {
long nowTime = System.currentTimeMillis();
long a = 30 * 24 * 60 * 60 * 1000;
calcStartTime(nowTime, a);
}
}
결 과 는 다음 과 같다.
end : 1560869539864 minus mills : -1702967296
start: 1562572507160
이것 은 우리 가 예상 한 것 과 다르다. 왜냐하면 30 * 86400000 = 25920000000 이지 만 계산 해 보면: - 1702967296 이다.
이 유 는 자바 의 정수 기본 유형 이 정형 int 이 고 int 의 최대 치 는 2147483647 이기 때 문 입 니 다.
코드 에서 자 바 는 오른쪽 값 을 계산 한 다음 에 롱 변수 에 값 을 부여 합 니 다.오른쪽 값 을 계산 하 는 과정 에서 (int 형 상승) 넘 침 이 발생 한 다음 에 넘 침 후 절 단 된 값 을 변수 에 부여 하여 결과 가 정확 하지 않 습 니 다.
코드 를 작은 변경 을 해서 다시 한 번 봅 시다.
package com.lingyejun.authenticator;
public class IntegerTest {
public static long calcStartTime(long endTime, long minusMills) {
System.out.println("end : " + endTime + " minus mills : " + minusMills);
long startTime = endTime - minusMills;
System.out.println("start: " + startTime);
return startTime;
}
public static void main(String[] args) {
long nowTime = System.currentTimeMillis();
long a = 30 * 24 * 60 * 60 * 1000L;
calcStartTime(nowTime, a);
}
}
결과
end : 1560869539864 minus mills : 2592000000
start: 1558277539864
이렇게 하면 아무 문제 가 없 을 것 같 습 니 다. 그런데 이렇게 하면 정말 보험 이 됩 니까? 만약 에 제 가 30 을 24856
(Integer.MAX_VALUE / 86400 = 24855)
으로 조정 하려 면 long a = 24856 * 24 * 60 * 60 * 1000L
으로 바 꾸 면 똑 같이 넘 칠 것 입 니 다.자바 의 연산 규칙 은 왼쪽 에서 오른쪽으로 마지막 long 형의 1000 을 곱 하기 전에 이미 넘 쳤 기 때문에 결과 도 틀 렸 습 니 다. 정확 한 방식 은 다음 과 같 아야 합 니 다.
long a = 24856L * 24 * 60 * 60 * 1000
package com.lingyejun.authenticator;
public class IntegerTest {
public static long calcStartTime(long endTime, long minusMills) {
System.out.println("end : " + endTime + " minus mills : " + minusMills);
long startTime = endTime - minusMills;
System.out.println("start: " + startTime);
return startTime;
}
public static void main(String[] args) {
long a = 30L * 24 * 60 * 60 * 1000;
calcStartTime(nowTime, a);
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.