簡體   English   中英

Android上的SimpleDateFormat時區錯誤

[英]SimpleDateFormat timezone bug on Android

我一直試圖在我的應用程序中隔離一個錯誤。 我成功地制作了以下“謎語”:

SimpleDateFormat f1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
SimpleDateFormat f2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Date d = f1.parse("2012-01-01T00:00:00+0700");
String s1 = f1.format(d); // 2011-12-31T18:00:00+0700
String s2 = f2.format(d); // 2011-12-31T18:00:00+0100

當我在Android API 7上運行此代碼時,我在注釋中獲得了值(是的,真的)。 此行為取決於特定的Java實現。

我的問題是:

  • 為什么s1不等於s2?
  • 更重要的是, 為什么s1不正確? 雖然s2指向適當的時間點,但s1卻沒有。 Android的SimpleDateFormat實現似乎存在一個錯誤。

對問題1的回答請參閱BalusC的答案:

  • [使用SimpleDateFormat#parse #parse后]可能需要恢復先前由setTimeZone調用設置的任何TimeZone值以進行進一步操作。

對問題2的回答請參閱wrygiel的答案(我自己)。

  • 這是由於Android 2.1(API 7)中的錯誤造成的。

DateFormat#parse() javadoc中提到了這一點:

根據給定的解析位置解析日期/時間字符串。 例如,時間文本"07/10/96 4:5 PM, PDT"將被解析為等同於Date(837039900000L)

默認情況下,解析是寬松的:如果輸入不是此對象的格式方法使用的形式,但仍可以解析為日期,則解析成功。 客戶可以通過調用setLenient(false)堅持嚴格遵守格式。

此解析操作使用calendar生成Date 因此, calendar's日期時間字段和TimeZone值可能已被覆蓋,具體取決於子類實現。 先前通過調用setTimeZone設置的任何TimeZone值可能需要恢復以進行進一步操作。

注意最后一段。 遺憾的是,它沒有解釋何時會發生這種情況。 要解決您的特定問題,您需要在格式化操作之前顯式設置所需的時區。

至於SimpleDateFormat本身的可變性,這已為人所知多年。 您永遠不應該創建它並將其實例指定為靜態或類變量,而應始終作為方法(threadlocal)變量。

這是由於Android 2.1(API 7)中的錯誤造成的。 似乎Android程序員在他們的Android 2.1實現中錯過了一些未記錄的Java行為 (它被歸類為不可修復的bug本身!)。

你的問題引起了我的興趣,所以我繼續編寫你的代碼。 結果? 正如所料......

2011-12-31T18:00:00+0100
2011-12-31T18:00:00+0100

這兩個值是相同的,你使用一些並發? 也許變量在f2.format(d)之前的另一個線程上被更改。

我嘗試通過運行相同的程序來比較s1和s2。 他們和我一樣。 在此輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM