[英]Handling date/time in java/android and daylight savings
我正在為Android制作日記應用程序,我想讓用戶選擇他們所在的時區。時間一直是我編程的混亂區域。
我將為可用的時區創建一個枚舉。
我將以long
UTC格式將日期/時間條目保存到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個有用的時區。
首先,我建議您不要使用Calendar
類。 它已經過時,並且存在許多錯誤和設計問題 。 這個可怕的API被更好的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
這個瞬間轉換成時區,你可以使用ZoneId
用ZonedDateTime
:
// 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個“有用”時區的列表。 我不知道您用於定義該列表的標准,但如果用戶位於列表中不在的時區,會發生什么?
在這個鏈接和這里有一些時區選擇用戶界面的想法。 您可以選擇一個並適應您的應用程序。
我還建議不要使用(如果可能的話)3個字母的時區縮寫(如CST或PST ),因為它們含糊不清而且不標准 。 最好使用全名(如America / Sao_Paulo或Europe / London ),因為它們是Java的API使用的(您可以使用ZoneId.getAvailableZoneIds()
獲取完整列表)並且它們配置為每個都有所有DST更改區。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.