2014-11-17 3 views
1

나는시간대 B (EST)시간대 A (UTC)에서 날짜 시간 문자열을 변환 할 필요가 시나리오를 .변환 날짜 시간 문자열

여기에서이 변환이 발생하는 JVM은 시간대 C (HKT) 날짜 객체입니다.

그래서 코드 블록은 다음과 같다 :

내가 기대하고 출력은 즉, 마지막 문장에서, 최종 "동부 표준시 16시 30분 0초 2014
11월 14일 금"이 될 것입니다
String dateString="20141114213000"; 
dateString += " UTC"; 
String formatString ="yyyyMMddHHmmss"; 
SimpleDateFormat sdf = new SimpleDateFormat(formatString + " z"); 

Date localDate = sdf.parse(dateString); 
System.out.println("Local Date::"+localDate); // Local Date::Sat Nov 15 05:30:00 HKT 2014 

Calendar localCal = Calendar.getInstance(); 
localCal.setTime(localDate); 

TimeZone estTimeZone = TimeZone.getTimeZone("America/New_York"); 

localCal.setTimeZone(estTimeZone); 
sdf.setTimeZone(estTimeZone); 

System.out.println(sdf.format(localCal.getTime()));//20141114163000 EST 

System.out.println(localCal.getTime());//Sat Nov 15 05:30:00 HKT 2014 

사용할 수있는 날짜 개체는 EST이어야합니다.

아무에게도 정보가 있으면 알려 주시기 바랍니다.


업데이트 :
그냥 내 요청을 명확하게 할 수는 출력 Date 객체 만에 있어야합니다.

인쇄 된 샘플 코드와 출력은 더 명확한 설명을위한 것입니다. 그래서 기본적으로 UTC 날짜 문자열EST 날짜 개체로 변환 할 필요가있다 문자열 "20141114213000"을하고 JVM이 변환이 일어나고

HKT입니다.

+2

결과는 코드 전체에 걸쳐 주석으로 표시됩니다. – Vinod

+1

날짜 개체에 표준 시간대 정보가 없습니다. – assylias

+0

@assylias 틀렸을 수도 있습니다. 나는 오라클 JDK의 소스 코드 인'java.util.Date'를'sun.util.calendar.BaseCalendar.Date' 타입의 내부 필드'cdate'로 체크하고 있었는데,이 필드는 (다른 것들 중에서) 기본 타임 존으로 초기화되었습니다. – lexicore

답변

1

자바의 날짜 및 시간 클래스에는 주목할만한 문제가있는 것으로 보입니다.

인기는 Joda-Time - Java date and time API입니다. 최신 안정 릴리스를 다운로드하고 jar 파일을 프로젝트의 빌드 경로에 추가하기 만하면됩니다.

줄 단위로 코드를 주석 처리하고 Joda Time 대안을 다시 작성했습니다. 이렇게하면 기존 코드를 Joda Time API로 전환 한 방법을 이해할 수 있습니다.

import java.text.ParseException; 

import org.joda.time.DateTime; 
import org.joda.time.DateTimeZone; 
import org.joda.time.format.DateTimeFormat; 
import org.joda.time.format.DateTimeFormatter; 

public class JodaTimeTransition { 
    public static void main(String[] args) throws ParseException { 
     String dateString="20141114213000"; 
     dateString += " UTC"; 

     /*new*/ 
     String formatString = "yyyyMMddHHmmss z"; 
//  String formatString ="yyyyMMddHHmmss"; 

     /*new*/ 
     DateTimeFormatter dtf = DateTimeFormat.forPattern(formatString); 
//  SimpleDateFormat sdf = new SimpleDateFormat(formatString + " z"); 

     /* new - Create localDate using JodaTime DateTime class */ 
     DateTime localDate = DateTime.parse(dateString, dtf); 
//  Date localDate = sdf.parse(dateString); 

     /* new - convert time to MST, since it is currently UTC*/ 
     localDate = localDate.toDateTime(DateTimeZone.forID("America/Denver")); 

     /* new - print out <local date> using specified format.*/ 
     System.out.println("Local Date::" + localDate.toString("EEE MMM dd HH:mm:ss z yyyy")); 
     /* Where did you get the local date mentioned at comments of line below? */ 
//  System.out.println("Local Date::"+localDate); // Local Date::Sat Nov 15 05:30:00 HKT 2014 


     /* new - Get reference to current date/time as <localCal> 
     * (This step can be omitted, and the previous localDate variable can be used) 
     */ 
     DateTime localCal = DateTime.now(); 
//  Calendar localCal = Calendar.getInstance(); 

     /* new - Set <localCal> to <localDate> */ 
     localCal = localDate; 
//  localCal.setTime(localDate); 

     /* new - Create new EST time zone*/ 
     DateTimeZone estTimeZone= DateTimeZone.forID("America/New_York"); 
//  TimeZone estTimeZone = TimeZone.getTimeZone("America/New_York"); 

     /* new - set <localCal> time zone from MST to EST */ 
     localCal = localCal.toDateTime(estTimeZone); 
//  localCal.setTimeZone(estTimeZone); 
//  sdf.setTimeZone(estTimeZone); 

     /* new - print <localCal> as new EST time zone */ 
     System.out.println(localCal.toString("yyyyMMddHHmmss z")); 
//  System.out.println(sdf.format(localCal.getTime()));//20141114163000 EST 

     /* new - print in desired format: Fri Nov 14 16:30:00 EST 2014 */ 
     System.out.println(localCal.toString("EEE MMM dd HH:mm:ss z yyyy")); 
//  System.out.println(localCal.getTime());//Sat Nov 15 05:30:00 HKT 2014 
    } 
} 
+0

요청을 명확하게하기 위해 제 질문이 업데이트되었습니다. Joda Time에 대한 제안에 감사드립니다. – Vinod

1

이 실제로 (그것은 좋은 라이브러리가되지 않는 것이 Joda 시간 필요 없음) 매우 간단합니다, 당신은 단지 SimpleDateFormat의에 시간대를 설정해야합니다. 구문 분석 할 때 원본 TimeZone을 사용하고 서식을 지정할 때 대상 TimeZone을 사용합니다. 중간 달력은 필요하지 않습니다.

업데이트 :

날짜에는 시간대가 없습니다. String이 아닌 TimeZone을 사용하여 무언가를 원하면 Calendar가 필요합니다. 현재 코드는 구문 분석 전에 SimpleDateFormat에 소스 TimeZone을 설정하지 않았다는 점을 제외하면 대부분 정확합니다. 코멘트에서 논의 후

+0

나는 그것을 시도하고 항상 EST 대신 HKT에서 Date 객체를 얻고있었습니다. – Vinod

0

업데이트

, 그것은 당신이은 모든 시간대에 대한 java.util.Date에 의존하지 것을 지금 분명히 보인다.아래에서 스케치 한 트릭 (원래 대답)은 아마도 작동하지만 은 올바른 작업이 아니기 때문에입니다. 시간대 (예 : java.util.Calendar)를 지원하지만 JodaTime을 사용하는 것이 좋습니다.


경고

:이 (또는하지 않을 수 있습니다) 내부 구조 시간대 초기화됩니다 java.util.Date의 Sun의 구현을 위해 일할 수있는 트릭입니다.

기본 시간대를 TimeZone.setDefault(...)으로 설정해보십시오.

귀하의 마지막 호출 :

System.out.println(localCal.getTime()); 

실제로 :

System.out.println(new Date(localCal.getTimeInMillis()).toString()); 

그래서 달력에있는 모든 시간대 정보를 설정은 무의미하다.

Date.toString() 그러나 처음에는 날짜의 내부 정규화를 수행하고 정적 인 TimeZone.getDefaultRef()을 사용합니다. 기본 시간대는 보통 TimeZone.setDefailt(...)을 통해 설정할 수 있습니다 (기본 설정).

그리고 꼭 JodaTime을 사용하십시오.

+0

TimeZone.setDefault (...)를 사용하면 모든 날짜 객체가 내 경우에 EST로되어 예상치 않게 나타납니다. 특정 날짜 개체 만 EST에 있어야하며 HKT에 모두 있어야합니다. – Vinod

+0

"이전"기본 시간대를 저장하고 기본 시간대를 EST로 설정하고 달력을 날짜로 변환하고 ** normalize ** (예 :'toString() '을 사용) 그런 다음 "old"기본 시간대를 기본값으로 설정하십시오 다시. 날짜의 시간대는 글로벌 설정에서 제공되므로 시간대와 함께 날짜를 사용하지 않거나 특정 시점에 전역 설정을 설정하지 마십시오. – lexicore