2017-09-01 70 views
0

我想UTC轉換爲本地時間,的Java UTC到當地時間不靈

下面是我使用的代碼,

public static String utcToLocalDateFormat(String dateString) { 

     Log.i("DateFormat", "utcToLocal:Before===>" + dateString); 

     String formattedDate = null; 
     if (dateString != null) { 
      DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
      dateFormat.setTimeZone(TimeZone.getDefault()); 
      Date date = null; 
      try { 

       Log.i("DateFormat", "getTimeZone===>" +dateFormat.getTimeZone()); 
       date = dateFormat.parse(dateString); 
       System.out.println(date); 
      } catch (ParseException e) { 
       e.printStackTrace(); 
      } 
      formattedDate = dateFormat.format(date); 
      Log.i("DateFormat", "utcToLocal:After===>" + formattedDate); 

     } 
     return formattedDate; 
    } 

但問題是,之前和之後的時區轉換時間它不會轉換爲UTC到當地時間。 任何幫助表示讚賞。

以下是我的輸入: 1)2017年8月31日20時四十分59秒 2)2017年9月1日11:16:24.024

以下是輸出: 1)2017-08- 31 20時40分59秒 2)2017年9月1日11點16分24秒

+1

能否請您提供一些輸入和輸出(預期VS你在說什麼)? – 2017-09-01 12:25:50

+1

您的'dateFormat'解析輸入爲本地TZ可以嗎? – yegodm

+0

在你的日期格式模式中,你不知道什麼時區會傳遞給你的方法。所以字符串被解析,因爲它已經在默認的時區。 – Damian0o

回答

0

改變線

dateFormat.setTimeZone(TimeZone.getDefault()); 

dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 
2

當你這樣做:

dateFormat.setTimeZone(TimeZone.getDefault()); 

然後解析String,你說的格式:「我會給你在這個時區的日期和時間的字符串」。如您使用TimeZone.getDefault(),它將使用JVM的默認時區。所以,第一件事就是告訴格式化使用UTC在解析時:

DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
// use UTC to parse 
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 
.... 
date = dateFormat.parse(dateString); 

我與dateString測試等於2017-08-01 10:00:00。因此,date將等於2017-08-01 10:00:00 UTC。當您用System.out.println打印日期時,它會調用toString()並將其轉換爲JVM的默認時區。

在我使用的JVM,默認的時區爲America/Sao_Paulo,所以當我把這個:

System.out.println(date); 

它打印:

週二8月1日07:00:00 BRT 2017年

因爲在8月1日,上午10時在UTC相當於在聖保羅7 AM。 這將導致根據您的JVM默認時區更改。

如果你想打印日期,但日期和時間等同於另一個時區(UTC相比其他),你需要用不同的時區設定的另一格式:

DateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
// use my default timezone to format (America/Sao_Paulo) 
dateFormat2.setTimeZone(TimeZone.getDefault()); 
formattedDate = dateFormat2.format(date); 

這將打印:

2017年8月1日07:00:00

而不是默認的時區,你可以使用任何你想要的時區(我使用America/New_York爲例):

DateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
// use New York timezone 
dateFormat2.setTimeZone(TimeZone.getTimeZone("America/New_York")); 
formattedDate = dateFormat2.format(date); 

這將轉換的日期/時間到紐約的時區:

2017年8月1日06:00:00

如果您想要在UTC中打印日期/時間,則不需要創建另一個格式化程序,只需使用第一個格式程序(因爲它已設置爲UTC)。


JVM的默認時區can be changed without notice, even at runtime,所以最好使用特定的一個,而不是隻用getDefault()的。

傾向於使用IANA timezones names(總是格式爲Region/City,如America/Sao_PauloEurope/Berlin)。 避免使用3字母縮寫(如CST或),因爲它們是ambiguous and not standard

通過調用TimeZone.getAvailableIDs(),您可以獲得可用時區列表(並選擇最適合您系統的時區)。


新的日期/時間API

老班(DateCalendarSimpleDateFormat)有lots of problemsdesign issues,他們正在被新的API取代。

在Android中,您可以使用ThreeTen Backport,它是Java 8新日期/時間類的一個很好的後端。要使其工作,您還需要ThreeTenABP(更多關於如何使用它here)。

該API使用起來要容易得多。首先創建一個org.threeten.bp.format.DateTimeFormatter並將輸入String解析爲org.threeten.bp.LocalDateTime

然後將其轉換爲UTC(創建org.threeten.bp.ZonedDateTime),然後到你想要的時區,並使用其他格式以進行輸出:

// date/time with optional milliseconds 
DateTimeFormatter parser = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[.SSS]"); 
// parse to LocalDateTime 
LocalDateTime dt = LocalDateTime.parse(dateString, parser); 

// convert to UTC 
ZonedDateTime z = dt.atZone(ZoneOffset.UTC); 

// convert to another timezone 
z = z.withZoneSameInstant(ZoneId.of("America/New_York")); 
// format it 
// date/time without milliseconds 
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); 
System.out.println(fmt.format(z)); 

您還可以使用使用ZoneId.systemDefault()默認的時區,並使用ZoneId.getAvailableZoneIds()獲得所有可用時區。

如果你想要UTC的日期/時間,你可以跳過withZoneSameInstant()


要將其轉換爲java.util.Date,你可以使用org.threeten.bp.DateTimeUtils類:

// convert ZonedDateTime to java.util.Date 
Date d = DateTimeUtils.toDate(z.toInstant()); 
+0

謝謝,但我不想指定像時區(TimeZone.getTimeZone(「America/New_York」))你提到的,我的應用程序使用世界的任何部分,它應該根據該時區工作。 – Joe

+0

@Joe我已經更新了答案,使其更加清晰。 – 2017-09-01 13:11:30