2017-12-16 17 views
-1

다음 코드 스니 j을 고려하십시오. 왜 아직도 EST를 표시하는 날짜의 출력 인 시간대 변경 후자바 캘린더 개체의 시간대를 설정해도 효과가없는 이유는 무엇입니까?

sun.util.calendar.ZoneInfo[id="GMT",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null] 
before setting time zone: Mon Dec 25 22:39:53 EST 2017 
after setting time zone: Mon Dec 25 22:39:53 EST 2017 

: 여기

TimeZone tz = TimeZone.getTimeZone("GMT"); 
    System.out.println(tz); 

    Calendar cal = Calendar.getInstance(); 
    cal.set(2017, Calendar.DECEMBER, 25); 

    System.out.println("before setting time zone: " + cal.getTime()); 
    cal.setTimeZone(tz); 

    System.out.println("after setting time zone: " + cal.getTime()); 

은 결과입니까? GMT가 아니어야합니까?

+1

'cal'에 영역을 설정하고 'cal.getTime()'에 영역을 설정하지 마십시오. 이후의 것은'java.util.Date' 타입입니다 만, 존을 설정할 수 없습니다. java.util.Date.toString() 메소드는 시스템 tz만을 사용합니다. –

+0

'cal.getTime()'이이 유명한 블로그 항목이 도움이 될 수있는'java.util.Date'를 제공한다는 것을 깨달으십시오 : [All about java.util.Date] (https://codeblog.jonskeet.uk/2017/04)/23/all-about-java-util-date /). –

답변

5

TL; DR

LocalDate.of(2017 , Month.DECEMBER , 25) 
     .atStartOfDay(ZoneId.of("America/New_York")) 

않도록 기존의 날짜 - 시간 수업

이제 기존 있습니다 몹시 귀찮은 된 날짜 - 시간 클래스를 사용하고 있습니다.

직접 질문에 대답하려면 Calendar::getTime 메서드는 Date을 반환합니다. 이러한 클래스의 많은 디자인 결함 중에서 Date::toString은 문자열을 생성하는 동안 JVM의 현재 기본 시간대를 동적으로 적용합니다. 따라서 귀하의 EST이 표시됩니다.

이러한 클래스를 사용하지 마십시오. 업계 최고의 java.time 클래스 인 대체 클래스 만 사용하십시오.

java.time

LocalDate 클래스는 시간 - 일 - 중 및 시간대없이없이 날짜 만 값을 나타냅니다

.

LocalDate xmas2017 = LocalDate.of(2017 , Month.DECEMBER , 25) ; 

당신이 날짜 - 시간을 원하는 경우에

, 하루의 첫 순간, 당신은 시간대를 지정해야합니다. 시간대는 날짜를 결정하는 데 중요합니다. 어떤 주어진 순간에, 날짜는 지구에 따라 지역마다 다릅니다. 예를 들어, 자정 몇 분 후 Paris France은 새로운 날이며, 어제는 " Montréal Québec"입니다.

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

00:00:00에 시작하지 마십시오. 일부 지역에서는 Daylight Saving Time (DST)과 같은 예외적 인 경우 01:00:00과 같은 다른 시간에 시작될 수 있음을 의미합니다. java.time가 그날의 최초의 순간을 결정하게합니다.

ZoneId을 적용하여 ZonedDateTime을 얻으십시오.

ZoneId z = ZoneId.of("America/New_York") ; 
ZonedDateTime zdtNewYork = xmas2017.atStartOfDay(z) ; 

크리스마스는 뉴욕보다 인도에서 훨씬 더 일찍 시작한다는 점에 유의하십시오.

ZonedDateTime zdtKolkta = xmas2017.atStartOfDay(ZoneId.of("Asia/Kolkata")) ; 

이는 왜 자신의 첫 배달에 대한 Kiribati에 엘프 물류 부서 노선 산타입니다. 그 섬들은 UTC보다 14 시간 앞서있는 시간대를 가진 가장 오래된 크리스마스를 가지고 있습니다.거기에서 순록은 새로운 날의 햇빛으로 지구가 회전하는 것처럼 계속되는 midnight를 차례로 쫓고 동쪽으로 날아갑니다.

같은 순간을 UTC로 조정하려면 Instant을 추출하고 항상 UTC로 작성하십시오. java.time

소개

Instant instant = zdt.toInstant() ; 

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과 같은 유용한 클래스가 있습니다.