2016-10-10 72 views
1

我已經完成了從UTC字符串到本地時區日期的轉換方法,但它只是返回與字符串中相同的日期。這裏有什麼問題?日期時區變換

public static Date getUTCToDate(String utc){ 
    // String exampleOfUTCTime = "2016-09-27T19:35:32.717"; 

    try{ 
     Log.d("asd-timeBefore", "getUTCToDate: " + utc); 
     DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); 
     formatter.setTimeZone(TimeZone.getDefault()); 
     Date d = formatter.parse(utc); 
     Log.d("asd-timeAfter", "getUTCToDate: " + d); 
     return d; 
    } catch (ParseException e){ 
     e.printStackTrace(); 
    } 
    return null; 
} 
+1

您正在爲格式化程序設置不正確的時區 – xAqweRx

+0

您想要的時區的偏移量是多少? –

+0

我需要使用本地時區,因爲應用程序將用於各個國家 –

回答

1

試着改變你的代碼,就像這樣。這將UTC時間轉換爲本地時區:

public static Date getUTCToDate(String utc){ 
    // String exampleOfUTCTime = "2016-09-27T19:35:32.717"; 

    try{ 
     Log.d("asd-timeBefore", "getUTCToDate: " + utc); 
     DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"); 
     formatter.setTimeZone(TimeZone.getTimeZone("UTC")); 
     Date d = formatter.parse(utc); 
     Log.d("asd-timeAfter", "getUTCToDate: " + d); 
     return d; 
    } catch (ParseException e){ 
     e.printStackTrace(); 
    } 
    return null; 
} 
+0

它的工作原理!但是如何?我正在接收像'exampleOfUTCTime'這樣的字符串,所以我想我需要將它轉換爲本地時區,但似乎Android/Java本身關心本地時區。 –

+0

我不確定這是否正確。 –

+0

該轉換是由系統自動完成的。如果你正在設置UTC時區 - > SimpleDateFormat的想法像「好的,這是UTC」,但是當你給這個Date - >它會自動轉換爲本地時區。思想日期沒有時區 - >內部函數有'SimpleDateFormatter'它使用默認時區(當地時區) – xAqweRx

1

如果你想在UTC格式格式化的日期和時間,那麼你應該做這樣的

formatter.setTimeZone(TimeZone.getTimeZone("UTC")); 
1

答案與setTimeZone是正確的,但作爲替代方案,您可以嘗試在字符串中指定UTC本身並註明您正在使用時區SimpleDateFormat類,如:

public static Date getUTCToDate(String utc){ 
    // String exampleOfUTCTime = "2016-09-27T19:35:32.717 UTC"; 

    try{ 
     System.out.println("getUTCToDate: " + utc); 
     DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS z"); 
     Date d = formatter.parse(utc); 
     System.out.println("getUTCToDate: " + d); 
     return d; 
    } catch (ParseException e){ 
     e.printStackTrace(); 
    } 
    return null; 
} 
1

我需要使用本地時區,因爲應用程序將用於各個國家。

如果要格式化上使用客戶端的時區服務器端的日期,那麼你將不得不通過在從客戶端分鐘GMT時間偏移。使用此JavaScript代碼:

var offset = new Date().getTimezoneOffset(); 

然後通過這個偏移你的方法作爲參數:

public static Date getUTCToDate(String utc, int offsetInMinutes) { 
    // String exampleOfUTCTime = "2016-09-27T19:35:32.717"; 

    try { 
     Log.d("asd-timeBefore", "getUTCToDate: " + utc); 
     DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z"); 
     long offset = -1L*60*1000*offsetInMinutes; 
     String[] timezones = TimeZone.getAvailableIDs(offset); 
     formatter.setTimeZone(timezones[0]); 
     Date d = formatter.parse(utc); 
     Log.d("asd-timeAfter", "getUTCToDate: " + d); 
     return d; 
    } catch (ParseException e){ 
     e.printStackTrace(); 
    } 
    return null; 
} 

評論:

你會發現,我包括Z的日期格式參數在您的SimpleDateFormat。這將包括顯示爲距GMT時間的小時偏移的時區。

Java Date只是一個時間點,不考慮偏移量。如果你想要客戶端的時區信息,你必須自己帶上它。

1

TL;博士

LocalDateTime.parse("2016-09-27T19:35:32.717").atZone(ZoneOffset.UTC) 

詳細

你輸入的字符串一個UTC值:2016-09-27T19:35:32.717。該字符串缺少關於offset-from-UTCtime zone的任何信息。

您正在使用麻煩的舊日期時間類,現在是遺留的,由java.time類代替。

LocalDateTime

解析字符串作爲LocalDateTime對象缺乏任何偏移或時區。

該輸入字符串恰好符合日期 - 時間字符串的ISO 8601標準。解析/生成字符串時,java.time類默認使用ISO 8601格式。所以不需要指定格式化模式。

LocalDateTime ldt = LocalDateTime.parse("2016-09-27T19:35:32.717"); 

OffsetDateTime

如果上下文,你肯定知道字符串是爲了代表UTC了一會兒,然後應用偏移獲得OffsetDateTime。使用預定義常數ZoneOffset.UTC

OffsetDateTime odt = ldt.atZone(ZoneOffset.UTC); 

從那裏,你可以使用DateTimeFormatter生成字符串各種格式,如果需要的話。

ZonedDateTime

如果你想通過一些特定地區的時區的鏡頭,查看同一時刻,應用ZoneId獲得ZonedDateTime

時區與UTC的偏移量爲用於處理異常情況(如夏令時(DST))的一組規則。

continent/region的格式指定proper time zone name。切勿使用3-4字母縮寫,如ESTIST,因爲它們不是真正的時區,不是標準化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of("America/Montreal"); 
ZonedDateTime zdt = odt.atZoneSameInstant(z); 

如果需要,您可以獲取用戶當前的默認時區。但請注意,此默認設置可以隨時更改,即使在運行時期間也可以更改。因此,如果重要的話,您應該向用戶詢問預期的/所需的時區,而不是假設。

ZoneId z = ZoneId.systemDefault(); 

關於java.time

java.time框架是建立在Java 8和更高版本。這些類代替了日期 - 時間類legacy,如java.util.Date.Calendar,& java.text.SimpleDateFormat

Joda-Time項目現在位於maintenance mode,建議遷移到java.time。請參閱Oracle Tutorial。並搜索堆棧溢出了很多例子和解釋。規格是JSR 310

從何處獲取java.time類?

ThreeTen-Extra項目與其他類擴展java.time。這個項目是未來可能增加java.time的一個試驗場。您可以在這裏找到一些有用的類,如Interval,YearWeek,YearQuartermore

+0

這是綽綽有餘和預期。要檢查這些 - 看起來有趣! –