2012-11-02 211 views
18

我想獲得從一個時區到另一個使用Java日期和日曆的簡單轉換。我試圖運行下面的代碼轉換時間到不同的時區

Calendar instance = Calendar.getInstance(TimeZone.getTimeZone("Europe/London")); 
    Date date = instance.getTime(); 
    System.out.println(date); 

    GregorianCalendar instance2 = new GregorianCalendar(TimeZone.getTimeZone("Europe/Athens")); 
    instance2.setTime(instance.getTime()); 
    System.out.println(instance2.getTime()); 

但仍返回相同的日期,而不是1小時...整個問題似乎微不足道,但我無法找到任何簡單的答案。在此先感謝您的幫助。

+4

你想使用[喬達時間](http://stackoverflow.com/a/375803/1037210)?這是我的偏好。 – Lion

+0

檢查[這個答案](http://stackoverflow.com/questions/230126/how-to-handle-calendar-timezones-using-java)。它可以派上用場。 – Gamb

+0

我在網上發現了另一件事,它可能是最乾淨的解決方案,它使用日期時間格式來解析日期字符串並在相應時區返回日期 – Bober02

回答

31

當您使用System.out.println(date); or System.out.println(instance2.getTime());打印日期時,instance2.getTime()返回的DateTimeZone independent,並且始終在當地時區打印日期。

相反,你可能需要使用DateFormat/SimpleDateFormat

DateFormat formatter= new SimpleDateFormat("MM/dd/yyyy HH:mm:ss Z"); 
    formatter.setTimeZone(TimeZone.getTimeZone("Europe/London")); 
    System.out.println(formatter.format(date)); 

    formatter.setTimeZone(TimeZone.getTimeZone("Europe/Athens")); 
    System.out.println(formatter.format(instance2.getTime())) 
+0

你確定它是本地時區而不是EPOCH秒(timezone-independant)? http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#getTime() – akaIDIOT

+0

@akaIDIOT內部表示形式自epoch以來,當打印日期時使用本地時區,一個'java.util.Date'的特性/錯誤。 – dan

+0

@ Bober02:你找到更好的東西了嗎?如果是,請分享。 –

2

您可以使用下面的代碼片段

String dateString = "14 Jul 2014 00:11:04 CEST"; 
date = formatter.parse(dateString); 
System.out.println(formatter.format(date)); 

// Set the formatter to use a different timezone - Indochina Time 
formatter.setTimeZone(TimeZone.getTimeZone("Asia/Bangkok")); 
System.out.println("ICT time : "+formatter.format(date)); 
8

接受的答案是正確的。 java.util.Date類沒有分配時區,但它的toString實現混淆地應用了JVM的當前默認時區。

避免java.util.Date & .Calendar

這是很多原因,以避免出了名的麻煩java.util.Date,.Calendar,和SimpleDateFormat類與Java捆綁之一。避免它們。相反,請使用:

約達時間

在約達時間2.3如下一些示例代碼。搜索StackOveflow瞭解更多示例和大量討論。

DateTimeZone timeZoneLondon = DateTimeZone.forID("Europe/London"); 
DateTimeZone timeZoneAthens = DateTimeZone.forID("Europe/Athens"); 

DateTime nowLondon = DateTime.now(timeZoneLondon); 
DateTime nowAthens = nowLondon.withZone(timeZoneAthens); 
DateTime nowUtc = nowLondon.withZone(DateTimeZone.UTC); 

java.time

的Java 8和更高版本有一個新的java.time package內置。這個軟件包受到了Joda-Time的啓發。雖然他們有一些相似之處和類名,但它們是不同的;每個都有其他缺點。一個顯着的區別是java.time避免了構造函數,而是使用靜態實例化方法。

在這個問題的情況下,他們的工作方式是一樣的。指定一個時區,然後調用now方法獲取當前時刻,然後基於舊的不可變實例創建一個新實例以調整時區。

請注意兩個不同的時區類。一個是命名時區,其中包括夏令時和其他此類異常的所有規則以及來自UTC的偏移量,而另一個僅爲偏移量。

ZoneId zoneMontréal = ZoneId.of("America/Montreal"); 
ZonedDateTime nowMontréal = ZonedDateTime.now (zoneMontréal); 

ZoneId zoneTokyo = ZoneId.of("Asia/Tokyo"); 
ZonedDateTime nowTokyo = nowMontréal.withZoneSameInstant(zoneTokyo); 

ZonedDateTime nowUtc = nowMontréal.withZoneSameInstant(ZoneOffset.UTC); 

其實java.util.Date確實有埋內its source code一個時區。但是班級爲了最實際的目的忽略了那個時區。所以,作爲簡寫,通常會說j.u.Date沒有分配時區。混亂?是。避免使用j.u.Date,並使用Joda-Time和/或java.time。