2013-02-13 1 views
7

java.util.Date의 getTime 메소드는이 Date 객체가 나타내는 1970 년 1 월 1 일 00:00:00 GMT 이후의 밀리 초 수를 반환합니다.다른 표준 시간대에서 날짜가 밀리 초 단위로 변경되는 이유는 무엇입니까?

아래와 같이 이상한 상황이 있음을 확인했습니다.

시스템 시간대입니다 (UTC + 02 : 00) 이스탄불

Date currentDate = new Date(); 
System.out.println(currentDate .getTime()); 
System.out.println(currentDate); 

자바 ConsoleOutput :

1,360,753,217,219

물 이월 13 13시 0분 17초 VET 2013


내 자바 스크립트 플러그인이 아래처럼이 긴 객체를 사용하고 있습니다.

자바 스크립트 :

console.log(new Date(1360753217219)); 

브라우저 ConsoleOutput :

날짜 {수요일 2013년 2월 13일 13시 00분 17초 (그리니치 표준시) + 0200 (터키 표준시)}


그게 다 괜찮아! 변경 후 내 로컬 시간대(UTC-04 : 30) 카라카스, 상황과 시간은 같은 밀리 초 단위로 아래와 같이 변경됩니다.


자바 스크립트 :

console.log(new Date(1360753217219)); 

브라우저 ConsoleOutput :

날짜 {수요일 2013년 2월 13일 그리니치 표준시 06시 30분 17초-0430 (베네수엘라 표준시)}

누군가 설명 할 수 있습니까? 그게 js 버그 야? 또는 더 중요하게, 어떻게 js 측면에서 다른 시간대에 대해 동일한 밀리 초 숫자로 같은 날짜를 얻으려면 자바 측에서 처리해야합니까?

감사합니다.

+0

console.log (new Date (1360753217219)). toString())'과'console.log ((new Date (1360753217219)) .UTTString())'은 무엇을합니까? – robertc

+6

죄송합니다, 문제가 보이지 않습니다. 카라카스에서 6:30은 터키에서 13:00입니다. 네가하려는 것은 무엇인가? – arcy

+0

밀리 초는 UTC와 관련이 있습니다. 요점은 무엇입니까? –

답변

2

버그가 아니며 시간대가 작동하는 방식입니다.

지금 베네수엘라에있는 사람에게 전화를 걸어 몇시에 물어 보면 그는 칠면조에있는 시간보다 일찍 6.5 (예를 들어) 시간 전이라고 말합니다. 당신이 언급 한 바와 같이

, 당신이 상대하고있는 수는 바로 그 같은 초에서 카라카스에, ​​시간이 31.12이었다 0시 0분 0초 GMT 1970 년 이후 (밀리 초)을 나타냅니다.1969 19:30 GMT-0430

그래도 몇 초 후 베네수엘라의 시간은 GMT에 비해 4:30 시간 빠릅니다.

동일한 입력 (밀리 초)을 사용하면 다른 표준 시간대에서 정확한 날짜를 얻을 수 없습니다. 그 이유는 단순히 잘못되었을 수 있기 때문입니다.

같은 결과를 얻으려면 시간대 (이 경우 6.5 시간)의 차이를 출력에 추가 할 수 있습니다. Dr.Dredel의 조언에 따르면 아마도 밀리 초를 낭비해서는 안됩니다.

+0

밀리 초를 변경하면 실제로 시간이 변경됩니다 (시간대가 아님). 각 날짜 스탬프는 초과 문자열의 일부로 시간대 오프셋을가집니다. 얼마나 많은 시간을 인간이 읽을 수있는 타임 스탬프에서 가산/감산해야하는지 계산하는 것은 매우 쉽습니다. 밀리 세컨드 (milliseconds)로 나사를 조이면 문제를 일으키고 절대적으로 잘못된 방향으로 갈 수 있습니다. –

+0

@ Dr.Dredel이 의견을 보내 주셔서 감사합니다. 그에 따라 답변을 수정했습니다. – yurib

6

밀리 초는 시간대에 무관합니다. 시간은 GMT 1970 년 1 월 1 일 이후 절대 값으로 측정됩니다. 따라서 아이디어는 밀리 초를 얻은 다음 주어진 시간대의 현지 시간이 사실에 뒤 따르는 것을 해결하는 것입니다. 그것에 대해 생각하면 이해가됩니다. 1970 년 이후로 경과 된 밀리 초는 사용자가 어디에 있든 상관없이 동일합니다.

다소 혼란 스럽지만 시간대를 조정하려면 밀리 초 단위로 돌아 가지 마십시오. 모든 날짜 라이브러리에는 밀리 초 스탬프를 시간대 특정 현지 시간으로 변환하는 메커니즘이 있습니다.

서버와 클라이언트간에 날짜를 효과적으로 전달하는 방법 (사용중인 언어가 중요하지 않음)에 대한 구체적인 질문은 밀리 초를 앞뒤로 전달하고 어느 쪽이 당신이 그 시간 동안 무엇을하고 있는지에 대한 컨텍스트에 중요하다면, 당신이 말하는 세계적인 특정 시간.

+1

그 이유는 "1970 년 1 월 1 일 * GMT * 이후로 - 에포크 시간이 하나의 시간대에 있다는 것을 이해하지 못해 OP의 혼동이 생길 수 있습니다. 그렇지 않은 경우에는 밀리 초 수가됩니다 통과해도 "당신이 어디에 있든 상관 없습니다". – arcy

+0

오른쪽 ... 죄송합니다, 제 답변을 바로 잡을 것입니다. –

0

TL; DR

Instant.ofEpochMilli(1_360_753_217_219L)   // UTC 

2013-02-13T11 : 00 : 17.219Z

Instant.ofEpochMilli(1_360_753_217_219L)  
     .atZone(ZoneId.of("Europe/Istanbul")) // Same moment, two hours *ahead* of UTC. 

2013-02-13T13 : 00 : 17.219 + 02 : 00 [유럽/이스탄불]

Instant.ofEpochMilli(1_360_753_217_219L)  
     .atZone(ZoneId.of("America/Caracas")) // Same moment, four-and-a-half hours *behind* UTC. 

2013-02-13T06 : 30 : 17.219-04 : 30 [미국/카라카스] java.time

당신은 초기에 번들 귀찮은 된 날짜 - 시간 클래스를 사용하는 사용

Java 버전. 그들은 현재 어떤 플랫폼에서나 최고의 날짜 - 시간 라이브러리 인 java.time 클래스에 의해 대체되었습니다.

1970 년 초의 epoch reference date이 (가) UTC (1970-01-01T00 : 00 : 00Z) 이후로 밀리 초 단위로 시작됩니다. 다른 사람들은 당신이 신기원의 기준 날짜가 시간대를 가지고 있다는 것을 파악하지 못한다고 지적합니다. 그리고이 신기원은 그 구역이 UTC 일 때, 0 시간의 오프셋입니다. 다른 모든 오프셋은이 시간과 비교하여 UTC 또는 UTC보다 시간과 분 단위로 측정됩니다.

Instant 클래스는 nanoseconds (소수 자릿수 9 자릿수까지)의 해상도로 UTC의 타임 라인에있는 순간을 나타냅니다.

long input = 1_360_753_217_219L ; 
Instant instant = Instant.ofEpochMilli(input) ; 

instant.toString() : 2013-02-13T11 : 00 : 17.219Z

특정 지역의 wall-clock time의 렌즈를 통해 같은 순간을보고 싶은 경우에 적용 시간대.

시간대는 특정 지역에서 사용중인 오프셋의 과거, 현재 및 향후 변경 내역입니다.

America/Montreal, Africa/Casablanca 또는 Pacific/Auckland 같이 continent/region의 형식으로 지정 proper time zone name. EST 또는 IST과 같은 3-4 문자 약어는 이 아니고 표준 시간대가 아니며 고유하지 않습니다 (!)로 사용하지 마십시오.

ZoneId zEurope_Istanbul = ZoneId.of("Europe/Istanbul") ; 
ZonedDateTime zdtEurope_Istanbul = instant.atZone(zEurope_Istanbul) ; 

zdtEurope_Istanbul.toString() : 2013-02-13T13 : 00 : 17.219 + 02 : 00 [유럽/이스탄불] 당신은 다른 시간대를 적용 할 수 있습니다

.

ZoneId zAmerica_Caracas = ZoneId.of("America/Caracas") ; 
ZonedDateTime zdtAmerica_Caracas = zdtEurope_Istanbul.withZoneSameInstant(zAmerica_Caracas) ; 

zdtAmerica_Caracas.toString() : 2013-02-13T06 : 30 : 17.219-04 : 30 아메리카/카라카스]

code live at IdeOne.com 참조.

이 세 개체는 즉시 & zdtEurope_Istanbul & zdtAmerica_Caracas는 모두가 똑같은 동시 순간, 타임 라인에 동일한 지점 을 나타냅니다.

획기 수는 UTC 기준 오전 11시를 나타냅니다. 이스탄불은 UTC의 두 시간 전이므로 동일한 시각에 오전 11시, 오후 1시 (13:00) 이후 2 시간이됩니다. 베네수엘라는 오후 4시 반에 뒤에 있으며, 같은 시간에 오전 6시 30 분에 시간대가 표시됩니다. 이것들은 모두 같은 순간이지만 벽 시계 시간은 다릅니다.

ISO

8601은 교환 또는 날짜 - 시간 값을 저장하기위한 카운트에서 - 시대를 사용하지 마십시오. 그것은 오류가 발생하기 쉽고, 사람이 의미있게 읽을 수 없으며 다양한 소프트웨어 시스템과 다른 입도 (초 단위, 밀리 초 단위, 마이크로 초 단위, 나노 초 단위 등)로 적어도 약 12 ​​개의 신기원 참조 날짜가 있기 때문에 모호합니다.).

JVM 외부에서 날짜 - 시간 값을 전달할 때 텍스트 표현에 표준 ISO 8601 형식을 사용하십시오. java.time 클래스는 문자열을 파싱/생성 할 때 기본적으로 표준 형식을 사용합니다. 이 Answer의 예제 코드에서 이러한 형식을 볼 수 있습니다. java.time

소개


java.time 프레임 워크는 나중에 자바 8에 내장되어 있습니다.이 클래스는 java.util.Date, Calendar, & SimpleDateFormat과 같이 문제가있는 이전 legacy 날짜 - 시간 클래스를 대체합니다.

maintenance mode에있는 Joda-Time 프로젝트는 java.time 클래스로의 마이그레이션을 권장합니다.

자세히 알아 보려면 Oracle Tutorial을 참조하십시오. 그리고 많은 예제와 설명을 위해 스택 오버플로를 검색하십시오. 사양은 JSR 310입니다.

어디에서 java.time 클래스를 얻을 수 있습니까?

ThreeTen-Extra 프로젝트는 추가 클래스와 java.time를 확장합니다. 이 프로젝트는 향후 java.time에 추가 될 수있는 가능성을 입증합니다. 여기에 Interval, YearWeek, YearQuartermore과 같은 유용한 클래스가 있습니다.

관련 문제