2017-06-03 137 views
1

我正在爲Android製作日記應用程序,我希望允許用戶選擇他們所在的時區。時間對我來說一直是一個編程領域。在java/android和夏令時中處理日期/時間

我將爲可用時區創建一個枚舉。

我打算將日期/時間條目保存爲UTC格式的long的sqlite,然後在Java中以編程方式處理偏移和DST以進行顯示。

我實際上知道Java在日期/時間處理方面的侷限性。

Calendar utc = Calendar.getInstance(TimeZone.getTimeZone("UTC")); //returns the current time in UTC format 
Long utcLong = utc.getTimeInMillis(); //returns current utc time in long for database insertion 

問題1:如何應用偏移量並考慮何時應用任何附加的DST偏移量?由於並非所有時區都遵守DST,因此DST在不同時區的不同日期生效。

問題2:Java的TimeZone類有類似〜800 ID的情況,如果用戶必須滾動瀏覽〜800個選項才能找到適用於它們的選項,這會很煩人。是否有可用的短名單?我想有大約50個有用的時區。

+0

備案,這裏的代碼示例不起作用。它返回本地時間,只是在不調整時間的情況下更改時區信息。 – psycotik

回答

2

首先,我建議你不要使用Calendar類。已過時,已有lots of bugs and design issues。這種可怕的API被替換了更好的:

下面的代碼適用於所有人,唯一不同的是程序包名稱(在Java 8中爲java.time,在ThreeTen Backport中爲org.threeten.bp),但類和方法名稱相同。

要獲得UTC當前日期/時間,最好的選擇是使用Instant類:

// current date/time in UTC - now() always returns the current instant in UTC 
Instant instant = Instant.now(); 
System.out.println(instant); // 2017-06-03T18:03:55.976Z 

// equivalent to calendar.getTimeInMillis(), it returns a long 
System.out.println(instant.toEpochMilli()); // 1496513035976 

爲了這個瞬間轉換成一個時區,您可以用ZonedDateTime使用ZoneId

// ZoneId accepts the same IDs used by TimeZone 
ZoneId zone = ZoneId.of("America/Sao_Paulo"); 
// convert instant to timezone 
ZonedDateTime z = instant.atZone(zone); 
System.out.println(z); // 2017-06-03T15:03:55.976-03:00[America/Sao_Paulo] 

// converts back to UTC (returns an Instant) 
System.out.println(z.toInstant()); // 2017-06-03T18:03:55.976Z 

上面的代碼已經處理了DST更改,因此從UTC到UTC的轉換非常簡單。

時區列表

你說你有50〜「有用」的時區的列表。我不知道你用什麼標準來定義這個列表,但是如果一個用戶在一個不在列表中的時區,會發生什麼?

this linkhere中有時區選取用戶界面的一些想法。你可以選擇一個並適應你的應用程序。

我也建議使用(如果可能的話)的3個字母的時區縮寫(如CSTPST),因爲它們ambiguous and not standard。最好使用全名(如America/Sao_PauloEurope/London),因爲它們是Java API所使用的名稱(可以通過ZoneId.getAvailableZoneIds()獲得完整列表),並且它們都配置了每個DST的每個更改區。

+0

我一直在尋找喬達時代,似乎是一個受歡迎的選擇。你用過那個嗎?你認爲threeten更好嗎? – psycotik

+2

Jodatime很好**,但**正在停止使用,並由新API取代。 Threeten更好,因爲它是新的Java 8 API的後端(所以未來的遷移比使用jodatime更容易)。即使在喬達的網站上,它說*注意,喬達時間被認爲是一個大部分「完成」的項目。計劃沒有重大改進。如果使用Java SE 8,請遷移到java.time(JSR-310)*。如果您使用java <= 7,請使用Threeten backport。所以我不建議用jodatime開始一個新項目。 – 2017-06-03 18:12:12

+1

我也添加了一些更多的答案的鏈接,希望它有幫助。 – 2017-06-03 18:25:03